diff --git a/src/agreements_api.go b/src/agreements_api.go index 2ecdf51..7e3053d 100644 --- a/src/agreements_api.go +++ b/src/agreements_api.go @@ -65,7 +65,7 @@ func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps http } } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return @@ -178,7 +178,7 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht // else user not found - we allow to save consent for unlinked users! } } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return diff --git a/src/expiration_api.go b/src/expiration_api.go index 749b410..8e3f41a 100644 --- a/src/expiration_api.go +++ b/src/expiration_api.go @@ -189,7 +189,7 @@ func (e mainEnv) expStart(w http.ResponseWriter, r *http.Request, ps httprouter. returnError(w, r, "internal error", 405, nil, event) return } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return diff --git a/src/lbasis_api.go b/src/lbasis_api.go index 8ce1318..63b0520 100644 --- a/src/lbasis_api.go +++ b/src/lbasis_api.go @@ -20,7 +20,7 @@ func (e mainEnv) createLegalBasis(w http.ResponseWriter, r *http.Request, ps htt returnError(w, r, "bad brief format", 405, nil, nil) return } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, nil) return diff --git a/src/pactivities_api.go b/src/pactivities_api.go index 7d40401..81bd5c8 100644 --- a/src/pactivities_api.go +++ b/src/pactivities_api.go @@ -20,7 +20,7 @@ func (e mainEnv) pactivityCreate(w http.ResponseWriter, r *http.Request, ps http returnError(w, r, "bad activity format", 405, nil, nil) return } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, nil) return diff --git a/src/requests_api.go b/src/requests_api.go index 4d289e9..4558c97 100644 --- a/src/requests_api.go +++ b/src/requests_api.go @@ -171,7 +171,7 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h if authResult == "" { return } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return @@ -265,7 +265,7 @@ func (e mainEnv) cancelUserRequest(w http.ResponseWriter, r *http.Request, ps ht if enforceUUID(w, request, event) == false { return } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return diff --git a/src/sessions_api.go b/src/sessions_api.go index c2e6c2e..4b920a6 100644 --- a/src/sessions_api.go +++ b/src/sessions_api.go @@ -118,7 +118,7 @@ func (e mainEnv) newUserSession(w http.ResponseWriter, r *http.Request, ps httpr if e.enforceAuth(w, r, event) == "" { return } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return diff --git a/src/sharedrecords_api.go b/src/sharedrecords_api.go index c799f5b..121e3e2 100644 --- a/src/sharedrecords_api.go +++ b/src/sharedrecords_api.go @@ -23,7 +23,7 @@ func (e mainEnv) newSharedRecord(w http.ResponseWriter, r *http.Request, ps http if e.enforceAuth(w, r, event) == "" { return } - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return diff --git a/src/userapps_api.go b/src/userapps_api.go index 1bd1c8a..a115403 100644 --- a/src/userapps_api.go +++ b/src/userapps_api.go @@ -30,7 +30,7 @@ func (e mainEnv) userappNew(w http.ResponseWriter, r *http.Request, ps httproute return } - data, err := getJSONPostData(r) + data, err := getJSONPostMap(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return @@ -70,21 +70,15 @@ func (e mainEnv) userappChange(w http.ResponseWriter, r *http.Request, ps httpro returnError(w, r, "bad appname", 405, nil, event) return } - - data, err := getJSONPostData(r) + jsonData, err := getJSONPostData(r) if err != nil { returnError(w, r, "failed to decode request body", 405, err, event) return } - if len(data) == 0 { + if jsonData == nil { returnError(w, r, "empty body", 405, nil, event) return } - jsonData, err := json.Marshal(data) - if err != nil { - returnError(w, r, "internal error", 405, err, event) - return - } // make sure userapp exists resultJSON, err := e.db.getUserApp(userTOKEN, appName, e.conf) if err != nil { diff --git a/src/utils.go b/src/utils.go index 1f73cbd..43efaf8 100644 --- a/src/utils.go +++ b/src/utils.go @@ -66,7 +66,7 @@ func getStringValue(r interface{}) string { case []uint8: return strings.TrimSpace(string(r.([]uint8))) case float64: - return strconv.Itoa(int(r.(float64))) + return strconv.Itoa(int(r.(float64))) } return "" } @@ -425,7 +425,7 @@ func enforceUUID(w http.ResponseWriter, uuidCode string, event *auditEvent) bool return true } -func getJSONPostData(r *http.Request) (map[string]interface{}, error) { +func getJSONPostMap(r *http.Request) (map[string]interface{}, error) { cType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) if err != nil { fmt.Printf("ignoring empty content-type: %s\n", err) @@ -433,16 +433,15 @@ func getJSONPostData(r *http.Request) (map[string]interface{}, error) { } cType = strings.ToLower(cType) records := make(map[string]interface{}) - //body, _ := ioutil.ReadAll(r.Body) - //fmt.Printf("Body: %s\n", body) if r.Method == "DELETE" { // otherwise data is not parsed! r.Method = "PATCH" } - body, err := ioutil.ReadAll(r.Body) + body0, err := ioutil.ReadAll(r.Body) if err != nil { return nil, err } + body := strings.TrimSpace(string(body0)) if len(body) < 3 { return nil, nil } @@ -450,7 +449,7 @@ func getJSONPostData(r *http.Request) (map[string]interface{}, error) { if body[0] == '{' { return nil, errors.New("wrong content-type, json instead of url encoded data") } - form, err := url.ParseQuery(string(body)) + form, err := url.ParseQuery(body) if err != nil { fmt.Printf("error in http data parsing: %s\n", err) return nil, err @@ -463,13 +462,13 @@ func getJSONPostData(r *http.Request) (map[string]interface{}, error) { records[key] = value[0] } } else if strings.HasPrefix(cType, "application/json") { - err = json.Unmarshal(body, &records) + err = json.Unmarshal([]byte(body), &records) if err != nil { log.Printf("Error in json decode %s", err) return nil, err } } else if strings.HasPrefix(cType, "application/xml") { - err = json.Unmarshal(body, &records) + err = json.Unmarshal([]byte(body), &records) if err != nil { log.Printf("Error in xml/json decode %s", err) return nil, err @@ -486,6 +485,69 @@ func getJSONPostData(r *http.Request) (map[string]interface{}, error) { return records, nil } +func getJSONPostData(r *http.Request) ([]byte, error){ + cType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + fmt.Printf("ignoring empty content-type: %s\n", err) + return nil, nil + } + cType = strings.ToLower(cType) + records := make(map[string]interface{}) + var records2 []map[string]interface{} + if r.Method == "DELETE" { + // otherwise data is not parsed! + r.Method = "PATCH" + } + body0, err := ioutil.ReadAll(r.Body) + if err != nil { + return nil, err + } + body := strings.TrimSpace(string(body0)) + if len(body) < 3 { + return nil, nil + } + if strings.HasPrefix(cType, "application/x-www-form-urlencoded") { + if body[0] == '{' || body[0] == '[' { + return nil, errors.New("wrong content-type, json instead of url encoded data") + } + form, err := url.ParseQuery(body) + if err != nil { + fmt.Printf("error in http data parsing: %s\n", err) + return nil, err + } + if len(form) == 0 { + return nil, nil + } + for key, value := range form { + records[key] = value[0] + } + return json.Marshal(records) + } else if strings.HasPrefix(cType, "application/json") || strings.HasPrefix(cType, "application/xml") { + if body[0] == '{' { + err = json.Unmarshal([]byte(body), &records) + } else if body[0] == '[' { + err = json.Unmarshal([]byte(body), &records2) + } else { + return nil, errors.New("wrong content-type, not a json string") + } + if err != nil { + return nil, err + } + if body[0] == '{' { + return json.Marshal(records) + } else if body[0] == '[' { + return json.Marshal(records2) + } + } + log.Printf("Ignore wrong content type: %s", cType) + maxStrLen := 200 + if len(body) < maxStrLen { + maxStrLen = len(body) + } + log.Printf("Body[max 200 chars]: %s", body[0:maxStrLen]) + return nil, errors.New("wrong content-type, not a json string") +} + func getIndexString(val interface{}) string { switch val.(type) { case nil: @@ -506,7 +568,7 @@ func getIndexString(val interface{}) string { func getJSONPost(r *http.Request, defaultCountry string) (userJSON, error) { var result userJSON - records, err := getJSONPostData(r) + records, err := getJSONPostMap(r) if err != nil { return result, err }