diff --git a/entry.go b/entry.go index 8b2cd27..482323a 100644 --- a/entry.go +++ b/entry.go @@ -3,7 +3,9 @@ package main import ( "errors" "fmt" + "io/ioutil" "math/rand" + "net/http" "net/url" "strings" "time" @@ -24,21 +26,40 @@ type Entry struct { token string } -func CreateEntry(contentType ContentType, body string) (*Entry, error) { +func CreateEntry(contentType ContentType, r *http.Request) (*Entry, error) { if contentType == WwwForm { - bodyValues, err := url.ParseQuery(body) + bodyString, err := parseRequestBody(r) + if err != nil { + return nil, err + } + bodyValues, err := url.ParseQuery(bodyString) if err != nil { return nil, errors.New("failed to parse query") } return createEntryFromURLValues(bodyValues) - } else if contentType == Json || contentType == Multipart { - return nil, errors.New("multipart and json content-type are not implemented yet") + } else if contentType == Multipart { + err := r.ParseMultipartForm(1024 * 1024 * 16) + if err != nil { + return nil, errors.New("failed to parse Multipart") + } + return createEntryFromURLValues(r.MultipartForm.Value) + } else if contentType == Json { + return nil, errors.New("json content-type is not implemented yet") } else { return nil, errors.New("unsupported content-type") } } -func createEntryFromURLValues(bodyValues url.Values) (*Entry, error) { +func parseRequestBody(r *http.Request) (string, error) { + defer r.Body.Close() + bodyBytes, err := ioutil.ReadAll(r.Body) + if err != nil { + return "", errors.New("failed to read body") + } + return string(bodyBytes), nil +} + +func createEntryFromURLValues(bodyValues map[string][]string) (*Entry, error) { if h, ok := bodyValues["h"]; ok && len(h) == 1 && h[0] != "entry" { return nil, errors.New("only entry type is supported so far") } @@ -79,7 +100,7 @@ func createEntryFromURLValues(bodyValues url.Values) (*Entry, error) { } return entry, nil } - return nil, errors.New("error parsing the entry from URL Values") + return nil, errors.New("error parsing the entry") } func computeExtraSettings(entry *Entry) error { diff --git a/main.go b/main.go index b4b9ae1..a3cbed1 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "io/ioutil" "log" "net/http" "time" @@ -36,14 +35,7 @@ func handleMicroPub(w http.ResponseWriter, r *http.Request) { return } // Create entry - defer r.Body.Close() - bodyBytes, err := ioutil.ReadAll(r.Body) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - bodyString := string(bodyBytes) - entry, err := CreateEntry(contentType, bodyString) + entry, err := CreateEntry(contentType, r) if err != nil || entry == nil { w.WriteHeader(http.StatusBadRequest) if err != nil { diff --git a/validation.go b/validation.go index 5afe4d7..976143b 100644 --- a/validation.go +++ b/validation.go @@ -105,7 +105,7 @@ func GetContentType(contentType string) (ContentType, error) { if strings.Contains(contentType, "multipart/form-data") { return Multipart, nil } - return UnsupportedType, errors.New("content-type " + contentType + " is not supported, use application/x-www-form-urlencoded") + return UnsupportedType, errors.New("content-type " + contentType + " is not supported, use application/x-www-form-urlencoded or multipart/form-data") } return UnsupportedType, errors.New("content-type is not provided in the request") }