mirror of https://github.com/minio/minio.git
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:
parent
0bbdd02a57
commit
5fbdd70de9
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue