diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index 6abb272b0..7abff1dbb 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -696,7 +696,7 @@ func TestValidateHealQueryParams(t *testing.T) { marker: "notmatchingmarker", delimiter: "/", maxKeys: "10", - apiErr: ErrNotImplemented, + apiErr: ErrInvalidPrefixMarker, }, // 8. Invalid params with unsupported delimiter. { @@ -812,7 +812,7 @@ func TestListObjectsHealHandler(t *testing.T) { marker: "notmatchingmarker", delimiter: "/", maxKeys: "10", - statusCode: getAPIError(ErrNotImplemented).HTTPStatusCode, + statusCode: getAPIError(ErrInvalidPrefixMarker).HTTPStatusCode, }, // 8. Invalid params with unsupported delimiter. { diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 5bf45e4cd..3c205c6cd 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -124,6 +124,7 @@ const ( ErrUnsupportedMetadata ErrMaximumExpires ErrSlowDown + ErrInvalidPrefixMarker // Add new error codes here. // Server-Side-Encryption (with Customer provided key) related API errors. @@ -524,6 +525,12 @@ var errorCodeResponse = map[APIErrorCode]APIError{ Description: "Please reduce your request", HTTPStatusCode: http.StatusServiceUnavailable, }, + ErrInvalidPrefixMarker: { + Code: "InvalidPrefixMarker", + Description: "Invalid marker prefix combination", + HTTPStatusCode: http.StatusBadRequest, + }, + // FIXME: Actual XML error response also contains the header which missed in list of signed header parameters. ErrUnsignedHeaders: { Code: "AccessDenied", diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index f204773c1..47c153165 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -44,7 +44,7 @@ func validateListObjectsArgs(prefix, marker, delimiter string, maxKeys int) APIE if marker != "" { // Marker not common with prefix is not implemented. if !hasPrefix(marker, prefix) { - return ErrNotImplemented + return ErrInvalidPrefixMarker } } // Success. @@ -107,9 +107,18 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http // Validate the query params before beginning to serve the request. // fetch-owner is not validated since it is a boolean if s3Error := validateListObjectsArgs(prefix, marker, delimiter, maxKeys); s3Error != ErrNone { + // return empty response if invalid marker + //TODO: avoid this pattern when moving to errors package + if s3Error == ErrInvalidPrefixMarker { + listObjectsInfo := ListObjectsInfo{} + response := generateListObjectsV2Response(bucket, prefix, token, marker, startAfter, delimiter, fetchOwner, listObjectsInfo.IsTruncated, maxKeys, listObjectsInfo.Objects, listObjectsInfo.Prefixes) + writeSuccessResponseXML(w, encodeResponse(response)) + return + } writeErrorResponse(w, s3Error, r.URL) return } + // Inititate a list objects operation based on the input params. // On success would return back ListObjectsInfo object to be // marshalled into S3 compatible XML header. @@ -151,6 +160,13 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http // Validate all the query params before beginning to serve the request. if s3Error := validateListObjectsArgs(prefix, marker, delimiter, maxKeys); s3Error != ErrNone { + // return empty response if invalid marker + //TODO: avoid this pattern when moving to errors package + if s3Error == ErrInvalidPrefixMarker { + response := generateListObjectsV1Response(bucket, prefix, marker, delimiter, maxKeys, ListObjectsInfo{}) + writeSuccessResponseXML(w, encodeResponse(response)) + return + } writeErrorResponse(w, s3Error, r.URL) return }