diff --git a/pkg/api/routes.go b/pkg/api/routes.go index 82160ef3..cf8f81bd 100644 --- a/pkg/api/routes.go +++ b/pkg/api/routes.go @@ -663,7 +663,7 @@ func (rh *RouteHandler) UpdateManifest(response http.ResponseWriter, request *ht return } - mediaType := request.Header.Get("Content-Type") + mediaType := zcommon.GetContentType(request) if !storageCommon.IsSupportedMediaType(mediaType) { err := apiErr.NewError(apiErr.MANIFEST_INVALID).AddDetail(map[string]string{"mediaType": mediaType}) zcommon.WriteJSON(response, http.StatusUnsupportedMediaType, apiErr.NewErrorList(err)) diff --git a/pkg/api/routes_test.go b/pkg/api/routes_test.go index d9b7bc4e..fbd06879 100644 --- a/pkg/api/routes_test.go +++ b/pkg/api/routes_test.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" @@ -211,12 +212,12 @@ func TestRoutes(t *testing.T) { }) Convey("UpdateManifest ", func() { - testUpdateManifest := func(urlVars map[string]string, ism *mocks.MockedImageStore) int { + testUpdateManifest := func(urlVars map[string]string, contentType string, ism *mocks.MockedImageStore) int { ctlr.StoreController.DefaultStore = ism str := []byte("test") request, _ := http.NewRequestWithContext(context.TODO(), http.MethodPut, baseURL, bytes.NewBuffer(str)) request = mux.SetURLVars(request, urlVars) - request.Header.Add("Content-Type", ispec.MediaTypeImageManifest) + request.Header.Add("Content-Type", contentType) response := httptest.NewRecorder() rthdlr.UpdateManifest(response, request) @@ -226,12 +227,14 @@ func TestRoutes(t *testing.T) { return resp.StatusCode } + contentType := ispec.MediaTypeImageManifest // repo not found statusCode := testUpdateManifest( map[string]string{ "name": "test", "reference": "reference", }, + contentType, &mocks.MockedImageStore{ PutImageManifestFn: func(repo, reference, mediaType string, body []byte) (godigest.Digest, godigest.Digest, error, @@ -246,7 +249,7 @@ func TestRoutes(t *testing.T) { "name": "test", "reference": "reference", }, - + contentType, &mocks.MockedImageStore{ PutImageManifestFn: func(repo, reference, mediaType string, body []byte) (godigest.Digest, godigest.Digest, error, @@ -261,6 +264,7 @@ func TestRoutes(t *testing.T) { "name": "test", "reference": "reference", }, + contentType, &mocks.MockedImageStore{ PutImageManifestFn: func(repo, reference, mediaType string, body []byte) (godigest.Digest, godigest.Digest, error, @@ -275,6 +279,7 @@ func TestRoutes(t *testing.T) { "name": "test", "reference": "reference", }, + contentType, &mocks.MockedImageStore{ PutImageManifestFn: func(repo, reference, mediaType string, body []byte) (godigest.Digest, godigest.Digest, error, @@ -290,6 +295,7 @@ func TestRoutes(t *testing.T) { "name": "test", "reference": "reference", }, + contentType, &mocks.MockedImageStore{ PutImageManifestFn: func(repo, reference, mediaType string, body []byte) (godigest.Digest, godigest.Digest, error, @@ -298,6 +304,24 @@ func TestRoutes(t *testing.T) { }, }) So(statusCode, ShouldEqual, http.StatusInternalServerError) + + // multiple parameters in "Content-Type" header + contentType = fmt.Sprintf("%s; %s", ispec.MediaTypeImageManifest, "chartset=utf-8") + statusCode = testUpdateManifest( + map[string]string{ + "name": "test", + "reference": "reference", + }, + contentType, + &mocks.MockedImageStore{ + PutImageManifestFn: func(repo, reference, mediaType string, body []byte) (godigest.Digest, + godigest.Digest, error, + ) { + return "", "", nil + }, + }) + So(statusCode, ShouldNotEqual, http.StatusUnsupportedMediaType) + So(statusCode, ShouldEqual, http.StatusInternalServerError) }) Convey("DeleteManifest", func() { diff --git a/pkg/common/http_server.go b/pkg/common/http_server.go index 254aa170..373b4339 100644 --- a/pkg/common/http_server.go +++ b/pkg/common/http_server.go @@ -148,3 +148,10 @@ func QueryHasParams(values url.Values, params []string) bool { return true } + +func GetContentType(r *http.Request) string { + contentType := r.Header.Get("Content-Type") + contentTypeParams := strings.Split(contentType, ";") + + return contentTypeParams[0] +}