From 5fbdd70de9ec878246536dc7fd052a364db65393 Mon Sep 17 00:00:00 2001 From: Praveen raj Mani Date: Tue, 26 Jun 2018 01:05:43 +0530 Subject: [PATCH] Minio handle for list_objects_v2 with a blank ContinuationToken (#5940) minio will now return an error for a blank continuation token in list_objects_v2,so as in s3. Fixes #5931 --- cmd/api-errors.go | 7 ++++++- cmd/api-resources.go | 12 +++++++++++- cmd/api-resources_test.go | 27 ++++++++++++++++++++++++++- cmd/bucket-handlers-listobjects.go | 9 ++++++++- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 8e9f520d7..6c4f1c988 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -193,6 +193,7 @@ const ( ErrHealMissingBucket ErrHealAlreadyRunning ErrHealOverlappingPaths + ErrIncorrectContinuationToken ) // error code to APIError structure, these fields carry respective @@ -842,7 +843,11 @@ var errorCodeResponse = map[APIErrorCode]APIError{ Description: "Object storage backend is unreachable", HTTPStatusCode: http.StatusServiceUnavailable, }, - + ErrIncorrectContinuationToken: { + Code: "InvalidArgument", + Description: "The continuation token provided is incorrect", + HTTPStatusCode: http.StatusBadRequest, + }, // Add your error structure here. } diff --git a/cmd/api-resources.go b/cmd/api-resources.go index 55ee0dcd3..b5f2757c1 100644 --- a/cmd/api-resources.go +++ b/cmd/api-resources.go @@ -36,7 +36,17 @@ func getListObjectsV1Args(values url.Values) (prefix, marker, delimiter string, } // Parse bucket url queries for ListObjects V2. -func getListObjectsV2Args(values url.Values) (prefix, token, startAfter, delimiter string, fetchOwner bool, maxkeys int, encodingType string) { +func getListObjectsV2Args(values url.Values) (prefix, token, startAfter, delimiter string, fetchOwner bool, maxkeys int, encodingType string, errCode APIErrorCode) { + errCode = ErrNone + + // The continuation-token cannot be empty. + if val, ok := values["continuation-token"]; ok { + if len(val[0]) == 0 { + errCode = ErrIncorrectContinuationToken + return + } + } + prefix = values.Get("prefix") token = values.Get("continuation-token") startAfter = values.Get("start-after") diff --git a/cmd/api-resources_test.go b/cmd/api-resources_test.go index b76fb18ca..7dc91bcd5 100644 --- a/cmd/api-resources_test.go +++ b/cmd/api-resources_test.go @@ -29,6 +29,7 @@ func TestListObjectsV2Resources(t *testing.T) { fetchOwner bool maxKeys int encodingType string + errCode APIErrorCode }{ { values: url.Values{ @@ -47,6 +48,7 @@ func TestListObjectsV2Resources(t *testing.T) { fetchOwner: true, maxKeys: 100, encodingType: "gzip", + errCode: ErrNone, }, { values: url.Values{ @@ -64,11 +66,34 @@ func TestListObjectsV2Resources(t *testing.T) { fetchOwner: true, maxKeys: 1000, encodingType: "gzip", + errCode: ErrNone, + }, + { + values: url.Values{ + "prefix": []string{"photos/"}, + "continuation-token": []string{""}, + "start-after": []string{"start-after"}, + "delimiter": []string{"/"}, + "fetch-owner": []string{"true"}, + "encoding-type": []string{"gzip"}, + }, + prefix: "", + token: "", + startAfter: "", + delimiter: "", + fetchOwner: false, + maxKeys: 0, + encodingType: "", + errCode: ErrIncorrectContinuationToken, }, } for i, testCase := range testCases { - prefix, token, startAfter, delimiter, fetchOwner, maxKeys, encodingType := getListObjectsV2Args(testCase.values) + prefix, token, startAfter, delimiter, fetchOwner, maxKeys, encodingType, errCode := getListObjectsV2Args(testCase.values) + + if errCode != testCase.errCode { + t.Errorf("Test %d: Expected error code:%d, got %d", i+1, testCase.errCode, errCode) + } if prefix != testCase.prefix { t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.prefix, prefix) } diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index f320eed11..da91fd238 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -70,8 +70,15 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http return } + urlValues := r.URL.Query() + // Extract all the listObjectsV2 query params to their native values. - prefix, token, startAfter, delimiter, fetchOwner, maxKeys, _ := getListObjectsV2Args(r.URL.Query()) + prefix, token, startAfter, delimiter, fetchOwner, maxKeys, _, errCode := getListObjectsV2Args(urlValues) + + if errCode != ErrNone { + writeErrorResponse(w, errCode, r.URL) + return + } // In ListObjectsV2 'continuation-token' is the marker. marker := token