Avoid sending an error after 206 HTTP code (#6264)

When a S3 client sends a GET Object with a range header, 206 http
code is returned indicating success, however the call of the object
layer's GetObject() inside the handler can return an error and will lead
to writing an XML error message, which is obviously wrong since
we already sent 206 http code. So in the case, we just stop sending
data to the S3 client, this latter can still detect if there is no
error when comparing received data with Content-Length header
in the Get Object response.
This commit is contained in:
Anis Elleuch 2018-08-08 23:39:47 +01:00 committed by Harshavardhana
parent 6df20734f9
commit 5a1ae862a7
2 changed files with 10 additions and 4 deletions

View file

@ -100,6 +100,5 @@ func setObjectHeaders(w http.ResponseWriter, objInfo ObjectInfo, contentRange *h
// Override content-length
w.Header().Set("Content-Length", strconv.FormatInt(contentRange.getLength(), 10))
w.Header().Set("Content-Range", contentRange.String())
w.WriteHeader(http.StatusPartialContent)
}
}

View file

@ -173,16 +173,23 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
setObjectHeaders(w, objInfo, hrange)
setHeadGetRespHeaders(w, r.URL.Query())
httpWriter := ioutil.WriteOnClose(writer)
getObject := objectAPI.GetObject
if api.CacheAPI() != nil && !hasSSECustomerHeader(r.Header) {
getObject = api.CacheAPI().GetObject
}
statusCodeWritten := false
httpWriter := ioutil.WriteOnClose(writer)
if hrange != nil && hrange.offsetBegin > -1 {
statusCodeWritten = true
w.WriteHeader(http.StatusPartialContent)
}
// Reads the object at startOffset and writes to mw.
if err = getObject(ctx, bucket, object, startOffset, length, httpWriter, objInfo.ETag); err != nil {
if !httpWriter.HasWritten() { // write error response only if no data has been written to client yet
if !httpWriter.HasWritten() && !statusCodeWritten { // write error response only if no data or headers has been written to client yet
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
}
httpWriter.Close()
@ -190,7 +197,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
}
if err = httpWriter.Close(); err != nil {
if !httpWriter.HasWritten() { // write error response only if no data has been written to client yet
if !httpWriter.HasWritten() && !statusCodeWritten { // write error response only if no data or headers has been written to client yet
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
return
}