api/server/httputils: matchesContentType(): return error instead of logging

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-04-05 11:31:27 +02:00
parent c6872980bb
commit ef490cae45
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
2 changed files with 25 additions and 18 deletions

View file

@ -9,7 +9,6 @@ import (
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// APIVersionKey is the client's requested API version.
@ -49,17 +48,12 @@ func CheckForJSON(r *http.Request) error {
ct := r.Header.Get("Content-Type")
// No Content-Type header is ok as long as there's no Body
if ct == "" {
if r.Body == nil || r.ContentLength == 0 {
return nil
}
if ct == "" && (r.Body == nil || r.ContentLength == 0) {
return nil
}
// Otherwise it better be json
if matchesContentType(ct, "application/json") {
return nil
}
return errdefs.InvalidParameter(errors.Errorf("Content-Type specified (%s) must be 'application/json'", ct))
return matchesContentType(ct, "application/json")
}
// ParseForm ensures the request form is parsed even with invalid content types.
@ -89,10 +83,13 @@ func VersionFromContext(ctx context.Context) string {
}
// matchesContentType validates the content type against the expected one
func matchesContentType(contentType, expectedType string) bool {
func matchesContentType(contentType, expectedType string) error {
mimetype, _, err := mime.ParseMediaType(contentType)
if err != nil {
logrus.Errorf("Error parsing media type: %s error: %v", contentType, err)
return errdefs.InvalidParameter(errors.Wrapf(err, "malformed Content-Type header (%s)", contentType))
}
return err == nil && mimetype == expectedType
if mimetype != expectedType {
return errdefs.InvalidParameter(errors.Errorf("unsupported Content-Type header (%s): must be '%s'", contentType, expectedType))
}
return nil
}

View file

@ -4,15 +4,25 @@ import "testing"
// matchesContentType
func TestJsonContentType(t *testing.T) {
if !matchesContentType("application/json", "application/json") {
t.Fail()
err := matchesContentType("application/json", "application/json")
if err != nil {
t.Error(err)
}
if !matchesContentType("application/json; charset=utf-8", "application/json") {
t.Fail()
err = matchesContentType("application/json; charset=utf-8", "application/json")
if err != nil {
t.Error(err)
}
if matchesContentType("dockerapplication/json", "application/json") {
t.Fail()
expected := "unsupported Content-Type header (dockerapplication/json): must be 'application/json'"
err = matchesContentType("dockerapplication/json", "application/json")
if err == nil || err.Error() != expected {
t.Errorf(`expected "%s", got "%v"`, expected, err)
}
expected = "malformed Content-Type header (foo;;;bar): mime: invalid media parameter"
err = matchesContentType("foo;;;bar", "application/json")
if err == nil || err.Error() != expected {
t.Errorf(`expected "%s", got "%v"`, expected, err)
}
}