diff --git a/bind.go b/bind.go index 6f41ce587..8e932afda 100644 --- a/bind.go +++ b/bind.go @@ -5,6 +5,7 @@ import ( "encoding/xml" "errors" "fmt" + "mime" "net/http" "reflect" "strconv" @@ -51,6 +52,14 @@ func (b *DefaultBinder) BindQueryParams(c Context, i interface{}) error { return nil } +func contentTypeIsJSON(mediaType string) bool { + parsed, _, err := mime.ParseMediaType(mediaType) + if err != nil { + return false + } + return parsed == "application/json" || strings.HasSuffix(parsed, "+json") +} + // BindBody binds request body contents to bindable object // NB: then binding forms take note that this implementation uses standard library form parsing // which parses form data from BOTH URL and BODY if content type is not MIMEMultipartForm @@ -64,7 +73,7 @@ func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) { ctype := req.Header.Get(HeaderContentType) switch { - case strings.HasPrefix(ctype, MIMEApplicationJSON): + case contentTypeIsJSON(ctype): if err = c.Echo().JSONSerializer.Deserialize(c, i); err != nil { switch err.(type) { case *HTTPError: diff --git a/bind_test.go b/bind_test.go index c11723303..53449d574 100644 --- a/bind_test.go +++ b/bind_test.go @@ -192,8 +192,10 @@ func TestToMultipleFields(t *testing.T) { func TestBindJSON(t *testing.T) { testBindOkay(t, strings.NewReader(userJSON), nil, MIMEApplicationJSON) testBindOkay(t, strings.NewReader(userJSON), dummyQuery, MIMEApplicationJSON) + testBindOkay(t, strings.NewReader(userJSON), dummyQuery, contentTypeJSONVariant) testBindArrayOkay(t, strings.NewReader(usersJSON), nil, MIMEApplicationJSON) testBindArrayOkay(t, strings.NewReader(usersJSON), dummyQuery, MIMEApplicationJSON) + testBindArrayOkay(t, strings.NewReader(usersJSON), dummyQuery, contentTypeJSONVariant) testBindError(t, strings.NewReader(invalidContent), MIMEApplicationJSON, &json.SyntaxError{}) testBindError(t, strings.NewReader(userJSONInvalidType), MIMEApplicationJSON, &json.UnmarshalTypeError{}) } diff --git a/echo_test.go b/echo_test.go index a352e4026..4d088a028 100644 --- a/echo_test.go +++ b/echo_test.go @@ -38,6 +38,7 @@ const ( userJSONInvalidType = `{"id":"1","name":"Jon Snow"}` userXMLConvertNumberError = `Number oneJon Snow` userXMLUnsupportedTypeError = `<>Number oneJon Snow` + contentTypeJSONVariant = `application/external.dns.webhook+json;version=1` ) const userJSONPretty = `{