From 98ddc3596cd1d3e6272eebc84ac2fbd616eefb71 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Fri, 17 Jun 2022 18:41:25 +0100 Subject: [PATCH] Avoid CompleteMultipart freeze with unexpected network issue (#15102) If sending a white space during a long S3 handler call fails, the whitespace goroutine forgets to return a result to the caller. Therefore, the complete multipart handler will be blocked. Remember to send the header written result to the caller or/and close the channel. --- cmd/object-handlers.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 04208ff91..0d6ddaca2 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -3101,10 +3101,12 @@ func (w *whiteSpaceWriter) WriteHeader(statusCode int) { // we do background append as and when the parts arrive and completeMultiPartUpload // is quick. Only in a rare case where parts would be out of order will // FS:completeMultiPartUpload() take a longer time. -func sendWhiteSpace(w http.ResponseWriter) <-chan bool { +func sendWhiteSpace(ctx context.Context, w http.ResponseWriter) <-chan bool { doneCh := make(chan bool) go func() { + defer close(doneCh) ticker := time.NewTicker(time.Second * 10) + defer ticker.Stop() headerWritten := false for { select { @@ -3124,7 +3126,8 @@ func sendWhiteSpace(w http.ResponseWriter) <-chan bool { } w.(http.Flusher).Flush() case doneCh <- headerWritten: - ticker.Stop() + return + case <-ctx.Done(): return } } @@ -3298,7 +3301,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite } w = &whiteSpaceWriter{ResponseWriter: w, Flusher: w.(http.Flusher)} - completeDoneCh := sendWhiteSpace(w) + completeDoneCh := sendWhiteSpace(ctx, w) objInfo, err := completeMultiPartUpload(ctx, bucket, object, uploadID, complMultipartUpload.Parts, opts) // Stop writing white spaces to the client. Note that close(doneCh) style is not used as it // can cause white space to be written after we send XML response in a race condition.