Select should return early errors as XML (#7230)

Currently, we were sending errors in Select binary format,
which is incompatible with AWS S3 behavior, errors in binary
are  sent after HTTP status code is already 200 OK - i.e it
happens during the evaluation of the record reader.
This commit is contained in:
Harshavardhana 2019-02-12 23:48:11 -08:00 committed by Nitish Tiwari
parent f9fecf0e76
commit 4ba77a916d
1 changed files with 20 additions and 4 deletions

View File

@ -161,8 +161,16 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r
s3Select, err := s3select.NewS3Select(r.Body) s3Select, err := s3select.NewS3Select(r.Body)
if err != nil { if err != nil {
if serr, ok := err.(s3select.SelectError); ok { if serr, ok := err.(s3select.SelectError); ok {
w.WriteHeader(serr.HTTPStatusCode()) encodedErrorResponse := encodeResponse(APIErrorResponse{
w.Write(s3select.NewErrorMessage(serr.ErrorCode(), serr.ErrorMessage())) Code: serr.ErrorCode(),
Message: serr.ErrorMessage(),
BucketName: bucket,
Key: object,
Resource: r.URL.Path,
RequestID: w.Header().Get(responseRequestIDKey),
HostID: w.Header().Get(responseDeploymentIDKey),
})
writeResponse(w, serr.HTTPStatusCode(), encodedErrorResponse, mimeXML)
} else { } else {
writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
} }
@ -195,8 +203,16 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r
if err = s3Select.Open(getObject); err != nil { if err = s3Select.Open(getObject); err != nil {
if serr, ok := err.(s3select.SelectError); ok { if serr, ok := err.(s3select.SelectError); ok {
w.WriteHeader(serr.HTTPStatusCode()) encodedErrorResponse := encodeResponse(APIErrorResponse{
w.Write(s3select.NewErrorMessage(serr.ErrorCode(), serr.ErrorMessage())) Code: serr.ErrorCode(),
Message: serr.ErrorMessage(),
BucketName: bucket,
Key: object,
Resource: r.URL.Path,
RequestID: w.Header().Get(responseRequestIDKey),
HostID: w.Header().Get(responseDeploymentIDKey),
})
writeResponse(w, serr.HTTPStatusCode(), encodedErrorResponse, mimeXML)
} else { } else {
writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
} }