From 8436c57bb579660429888d10efd43317bc0514a5 Mon Sep 17 00:00:00 2001 From: Andreea-Lupu Date: Thu, 16 Nov 2023 16:42:48 +0200 Subject: [PATCH] fix: handle parameters in Content-Type header Signed-off-by: Andreea-Lupu --- pkg/api/routes.go | 2 +- pkg/api/routes_test.go | 30 +++++++++++++++++++++++++++--- pkg/common/http_server.go | 7 +++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/pkg/api/routes.go b/pkg/api/routes.go index 82160ef3f..cf8f81bdf 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 d9b7bc4e3..fbd068792 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 254aa1709..373b43392 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] +}