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
This commit is contained in:
Praveen raj Mani 2018-06-26 01:05:43 +05:30 committed by kannappanr
parent 0bbdd02a57
commit 5fbdd70de9
4 changed files with 51 additions and 4 deletions

View File

@ -193,6 +193,7 @@ const (
ErrHealMissingBucket ErrHealMissingBucket
ErrHealAlreadyRunning ErrHealAlreadyRunning
ErrHealOverlappingPaths ErrHealOverlappingPaths
ErrIncorrectContinuationToken
) )
// error code to APIError structure, these fields carry respective // error code to APIError structure, these fields carry respective
@ -842,7 +843,11 @@ var errorCodeResponse = map[APIErrorCode]APIError{
Description: "Object storage backend is unreachable", Description: "Object storage backend is unreachable",
HTTPStatusCode: http.StatusServiceUnavailable, HTTPStatusCode: http.StatusServiceUnavailable,
}, },
ErrIncorrectContinuationToken: {
Code: "InvalidArgument",
Description: "The continuation token provided is incorrect",
HTTPStatusCode: http.StatusBadRequest,
},
// Add your error structure here. // Add your error structure here.
} }

View File

@ -36,7 +36,17 @@ func getListObjectsV1Args(values url.Values) (prefix, marker, delimiter string,
} }
// Parse bucket url queries for ListObjects V2. // 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") prefix = values.Get("prefix")
token = values.Get("continuation-token") token = values.Get("continuation-token")
startAfter = values.Get("start-after") startAfter = values.Get("start-after")

View File

@ -29,6 +29,7 @@ func TestListObjectsV2Resources(t *testing.T) {
fetchOwner bool fetchOwner bool
maxKeys int maxKeys int
encodingType string encodingType string
errCode APIErrorCode
}{ }{
{ {
values: url.Values{ values: url.Values{
@ -47,6 +48,7 @@ func TestListObjectsV2Resources(t *testing.T) {
fetchOwner: true, fetchOwner: true,
maxKeys: 100, maxKeys: 100,
encodingType: "gzip", encodingType: "gzip",
errCode: ErrNone,
}, },
{ {
values: url.Values{ values: url.Values{
@ -64,11 +66,34 @@ func TestListObjectsV2Resources(t *testing.T) {
fetchOwner: true, fetchOwner: true,
maxKeys: 1000, maxKeys: 1000,
encodingType: "gzip", 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 { 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 { if prefix != testCase.prefix {
t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.prefix, prefix) t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.prefix, prefix)
} }

View File

@ -70,8 +70,15 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
return return
} }
urlValues := r.URL.Query()
// Extract all the listObjectsV2 query params to their native values. // 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. // In ListObjectsV2 'continuation-token' is the marker.
marker := token marker := token