From 5c0acbc6fcebf585d523fb1f89a40aae6aaf441c Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 11 Jul 2019 13:19:25 -0700 Subject: [PATCH] Add text/event-stream for long running http connections (#7909) When MinIO is behind a proxy, proxies end up killing clients when no data is seen on the connection, adding the right content-type ensures that proxies do not come in the way. --- cmd/admin-handlers.go | 7 ++++--- cmd/bucket-notification-handlers.go | 3 +++ cmd/object-handlers.go | 1 + cmd/storage-rest-server.go | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 6b975f1e7..ee902175a 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -681,12 +681,12 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { // Start writing response to client started = true setCommonHeaders(w) - w.Header().Set(xhttp.ContentType, string(mimeJSON)) + w.Header().Set(xhttp.ContentType, "text/event-stream") // Set 200 OK status w.WriteHeader(200) } // Send whitespace and keep connection open - w.Write([]byte("\n\r")) + w.Write([]byte(" ")) w.(http.Flusher).Flush() case hr := <-respCh: switch hr.apiErr { @@ -1486,7 +1486,8 @@ func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) { // Avoid reusing tcp connection if read timeout is hit // This is needed to make r.Context().Done() work as // expected in case of read timeout - w.Header().Add(xhttp.Connection, "close") + w.Header().Set(xhttp.Connection, "close") + w.Header().Set(xhttp.ContentType, "text/event-stream") doneCh := make(chan struct{}) defer close(doneCh) diff --git a/cmd/bucket-notification-handlers.go b/cmd/bucket-notification-handlers.go index 93fdacb1f..d339b2184 100644 --- a/cmd/bucket-notification-handlers.go +++ b/cmd/bucket-notification-handlers.go @@ -23,6 +23,7 @@ import ( "net/http" "github.com/gorilla/mux" + xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/event" "github.com/minio/minio/pkg/event/target" @@ -246,6 +247,8 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit return } + w.Header().Set(xhttp.ContentType, "text/event-stream") + target, err := target.NewHTTPClientTarget(*host, w) if err != nil { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 4a6c57b87..c63661cf5 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -2280,6 +2280,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite w.Write(encodedErrorResponse) w.(http.Flusher).Flush() } + w.Header().Set(xhttp.ContentType, "text/event-stream") w = &whiteSpaceWriter{ResponseWriter: w, Flusher: w.(http.Flusher)} completeDoneCh := sendWhiteSpace(ctx, w) objInfo, err := completeMultiPartUpload(ctx, bucket, object, uploadID, completeParts, opts) diff --git a/cmd/storage-rest-server.go b/cmd/storage-rest-server.go index fd29e0a02..d31bb132a 100644 --- a/cmd/storage-rest-server.go +++ b/cmd/storage-rest-server.go @@ -540,6 +540,7 @@ func (s *storageRESTServer) VerifyFile(w http.ResponseWriter, r *http.Request) { return } algo := BitrotAlgorithmFromString(algoStr) + w.Header().Set(xhttp.ContentType, "text/event-stream") doneCh := sendWhiteSpaceVerifyFile(w) err = s.storage.VerifyFile(volume, filePath, algo, hash, int64(shardSize)) <-doneCh