From bcb822c3906a0ffad5d2bcd56f1aa262bd08cd70 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Thu, 30 Jun 2016 18:48:50 -0700 Subject: [PATCH] Send XML header before the first of whitespace chars (#2046) * Sent XML header before the first of whitespace chars XML parsing fails in aws cli due to unexpected whitespace character. To fix this, we send the xml header before we send the first whitespace character, if any. * Fix race between sendWhiteSpaceChars and completeMultiUploadpart --- api-response.go | 5 +++-- object-handlers.go | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/api-response.go b/api-response.go index 9b982510b..da29f25ff 100644 --- a/api-response.go +++ b/api-response.go @@ -502,10 +502,11 @@ func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorCode APIE setCommonHeaders(w) // write Header w.WriteHeader(error.HTTPStatusCode) - writeErrorResponseNoHeader(w, req, error, resource) + writeErrorResponseNoHeader(w, req, errorCode, resource) } -func writeErrorResponseNoHeader(w http.ResponseWriter, req *http.Request, error APIError, resource string) { +func writeErrorResponseNoHeader(w http.ResponseWriter, req *http.Request, errorCode APIErrorCode, resource string) { + error := getAPIError(errorCode) // Generate error response. errorResponse := getAPIErrorResponse(error, resource) encodedErrorResponse := encodeResponse(errorResponse) diff --git a/object-handlers.go b/object-handlers.go index 5a42e0a2a..7da414277 100644 --- a/object-handlers.go +++ b/object-handlers.go @@ -974,6 +974,14 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite // Send 200 OK setCommonHeaders(w) w.WriteHeader(http.StatusOK) + // Xml headers need to be sent before we possibly send whitespace characters + // to the client. + _, err = w.Write([]byte(xml.Header)) + if err != nil { + errorIf(err, "Unable to write XML header for complete multipart upload") + writeErrorResponseNoHeader(w, r, ErrInternalError, r.URL.Path) + return + } doneCh := make(chan struct{}) // Signal that completeMultipartUpload is over via doneCh @@ -992,7 +1000,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite writePartSmallErrorResponse(w, r, oErr) default: // Handle all other generic issues. - writeErrorResponseNoHeader(w, r, getAPIError(toAPIErrorCode(err)), r.URL.Path) + writeErrorResponseNoHeader(w, r, toAPIErrorCode(err), r.URL.Path) } return } @@ -1001,7 +1009,12 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite location := getLocation(r) // Generate complete multipart response. response := generateCompleteMultpartUploadResponse(bucket, object, location, md5Sum) - encodedSuccessResponse := encodeResponse(response) + encodedSuccessResponse, err := xml.Marshal(response) + if err != nil { + errorIf(err, "Unable to parse CompleteMultipartUpload response") + writeErrorResponseNoHeader(w, r, ErrInternalError, r.URL.Path) + return + } // write success response. w.Write(encodedSuccessResponse) w.(http.Flusher).Flush()