History

fix: avoid buffering of server sent events by proxies (#10164)

Harshavardhana committed 6 years ago

Commit 25a55ba1 parent fe157165 files · +25 −13Browse files

Unified · Split

5 files
  1. cmd/admin-handlers.go +7 −4
  2. cmd/api-headers.go +7 −0
  3. cmd/listen-notification-handlers.go +1 −2
  4. cmd/object-handlers.go +3 −1
  5. cmd/storage-rest-server.go +7 −6
cmd/admin-handlers.go+7−4
@@ -695,7 +695,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { · 694 unmodified lines
695 // Start writing response to client695 // Start writing response to client
696 started = true696 started = true
697 setCommonHeaders(w)697 setCommonHeaders(w)
698 w.Header().Set(xhttp.ContentType, "text/event-stream")698 setEventStreamHeaders(w)
699 // Set 200 OK status699 // Set 200 OK status
700 w.WriteHeader(200)700 w.WriteHeader(200)
701 }701 }
@@ -995,7 +995,7 @@ func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) { · 293 unmodified lines
995 return995 return
996 }996 }
997 997
998 w.Header().Set(xhttp.ContentType, "text/event-stream")998 setEventStreamHeaders(w)
999 999
1000 // Trace Publisher and peer-trace-client uses nonblocking send and hence does not wait for slow receivers.1000 // Trace Publisher and peer-trace-client uses nonblocking send and hence does not wait for slow receivers.
1001 // Use buffered channel to take care of burst sends or slow w.Write()1001 // Use buffered channel to take care of burst sends or slow w.Write()
@@ -1064,7 +1064,8 @@ func (a adminAPIHandlers) ConsoleLogHandler(w http.ResponseWriter, r *http.Reque · 62 unmodified lines
1064 // This is needed to make r.Context().Done() work as1064 // This is needed to make r.Context().Done() work as
1065 // expected in case of read timeout1065 // expected in case of read timeout
1066 w.Header().Add("Connection", "close")1066 w.Header().Add("Connection", "close")
1067 w.Header().Set(xhttp.ContentType, "text/event-stream")1067
1068 setEventStreamHeaders(w)
1068 1069
1069 logCh := make(chan interface{}, 4000)1070 logCh := make(chan interface{}, 4000)
1070 1071
@@ -1223,7 +1224,9 @@ func (a adminAPIHandlers) OBDInfoHandler(w http.ResponseWriter, r *http.Request) · 152 unmodified lines
1223 }1224 }
1224 1225
1225 setCommonHeaders(w)1226 setCommonHeaders(w)
1226 w.Header().Set(xhttp.ContentType, "text/event-stream")1227
1228 setEventStreamHeaders(w)
1229
1227 w.WriteHeader(http.StatusOK)1230 w.WriteHeader(http.StatusOK)
1228 1231
1229 errResp := func(err error) {1232 errResp := func(err error) {
cmd/api-headers.go+7−0
@@ -38,6 +38,13 @@ func mustGetRequestID(t time.Time) string { · 37 unmodified lines
38 return fmt.Sprintf("%X", t.UnixNano())38 return fmt.Sprintf("%X", t.UnixNano())
39}39}
40 40
41// setEventStreamHeaders to allow proxies to avoid buffering proxy responses
42func setEventStreamHeaders(w http.ResponseWriter) {
43 w.Header().Set(xhttp.ContentType, "text/event-stream")
44 w.Header().Set(xhttp.CacheControl, "no-cache") // nginx to turn off buffering
45 w.Header().Set("X-Accel-Buffering", "no") // nginx to turn off buffering
46}
47
41// Write http common headers48// Write http common headers
42func setCommonHeaders(w http.ResponseWriter) {49func setCommonHeaders(w http.ResponseWriter) {
43 w.Header().Set(xhttp.ServerInfo, "MinIO/"+ReleaseTag)50 w.Header().Set(xhttp.ServerInfo, "MinIO/"+ReleaseTag)
cmd/listen-notification-handlers.go+1−2
@@ -22,7 +22,6 @@ import ( · 21 unmodified lines
22 "time"22 "time"
23 23
24 "github.com/gorilla/mux"24 "github.com/gorilla/mux"
25 xhttp "github.com/minio/minio/cmd/http"
26 "github.com/minio/minio/cmd/logger"25 "github.com/minio/minio/cmd/logger"
27 policy "github.com/minio/minio/pkg/bucket/policy"26 policy "github.com/minio/minio/pkg/bucket/policy"
28 "github.com/minio/minio/pkg/event"27 "github.com/minio/minio/pkg/event"
@@ -119,7 +118,7 @@ func (api objectAPIHandlers) ListenNotificationHandler(w http.ResponseWriter, r · 90 unmodified lines
119 118
120 rulesMap := event.NewRulesMap(eventNames, pattern, event.TargetID{ID: mustGetUUID()})119 rulesMap := event.NewRulesMap(eventNames, pattern, event.TargetID{ID: mustGetUUID()})
121 120
122 w.Header().Set(xhttp.ContentType, "text/event-stream")121 setEventStreamHeaders(w)
123 122
124 // Listen Publisher and peer-listen-client uses nonblocking send and hence does not wait for slow receivers.123 // Listen Publisher and peer-listen-client uses nonblocking send and hence does not wait for slow receivers.
125 // Use buffered channel to take care of burst sends or slow w.Write()124 // Use buffered channel to take care of burst sends or slow w.Write()
cmd/object-handlers.go+3−1
@@ -2615,7 +2615,9 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite · 2614 unmodified lines
2615 w.Write(encodedErrorResponse)2615 w.Write(encodedErrorResponse)
2616 w.(http.Flusher).Flush()2616 w.(http.Flusher).Flush()
2617 }2617 }
2618 w.Header().Set(xhttp.ContentType, "text/event-stream")2618
2619 setEventStreamHeaders(w)
2620
2619 w = &whiteSpaceWriter{ResponseWriter: w, Flusher: w.(http.Flusher)}2621 w = &whiteSpaceWriter{ResponseWriter: w, Flusher: w.(http.Flusher)}
2620 completeDoneCh := sendWhiteSpace(w)2622 completeDoneCh := sendWhiteSpace(w)
2621 objInfo, err := completeMultiPartUpload(ctx, bucket, object, uploadID, completeParts, opts)2623 objInfo, err := completeMultiPartUpload(ctx, bucket, object, uploadID, completeParts, opts)
cmd/storage-rest-server.go+7−6
@@ -151,7 +151,8 @@ func (s *storageRESTServer) CrawlAndGetDataUsageHandler(w http.ResponseWriter, r · 150 unmodified lines
151 return151 return
152 }152 }
153 153
154 w.Header().Set(xhttp.ContentType, "text/event-stream")154 setEventStreamHeaders(w)
155
155 var cache dataUsageCache156 var cache dataUsageCache
156 err := cache.deserialize(r.Body)157 err := cache.deserialize(r.Body)
157 if err != nil {158 if err != nil {
@@ -520,7 +521,7 @@ func (s *storageRESTServer) WalkSplunkHandler(w http.ResponseWriter, r *http.Req · 362 unmodified lines
520 dirPath := vars[storageRESTDirPath]521 dirPath := vars[storageRESTDirPath]
521 markerPath := vars[storageRESTMarkerPath]522 markerPath := vars[storageRESTMarkerPath]
522 523
523 w.Header().Set(xhttp.ContentType, "text/event-stream")524 setEventStreamHeaders(w)
524 encoder := gob.NewEncoder(w)525 encoder := gob.NewEncoder(w)
525 526
526 fch, err := s.storage.WalkSplunk(volume, dirPath, markerPath, r.Context().Done())527 fch, err := s.storage.WalkSplunk(volume, dirPath, markerPath, r.Context().Done())
@@ -548,7 +549,7 @@ func (s *storageRESTServer) WalkVersionsHandler(w http.ResponseWriter, r *http.R · 21 unmodified lines
548 return549 return
549 }550 }
550 551
551 w.Header().Set(xhttp.ContentType, "text/event-stream")552 setEventStreamHeaders(w)
552 encoder := gob.NewEncoder(w)553 encoder := gob.NewEncoder(w)
553 554
554 fch, err := s.storage.WalkVersions(volume, dirPath, markerPath, recursive, r.Context().Done())555 fch, err := s.storage.WalkVersions(volume, dirPath, markerPath, recursive, r.Context().Done())
@@ -576,7 +577,7 @@ func (s *storageRESTServer) WalkHandler(w http.ResponseWriter, r *http.Request) · 21 unmodified lines
576 return577 return
577 }578 }
578 579
579 w.Header().Set(xhttp.ContentType, "text/event-stream")580 setEventStreamHeaders(w)
580 encoder := gob.NewEncoder(w)581 encoder := gob.NewEncoder(w)
581 582
582 fch, err := s.storage.Walk(volume, dirPath, markerPath, recursive, r.Context().Done())583 fch, err := s.storage.Walk(volume, dirPath, markerPath, recursive, r.Context().Done())
@@ -659,7 +660,7 @@ func (s *storageRESTServer) DeleteVersionsHandler(w http.ResponseWriter, r *http · 76 unmodified lines
659 660
660 dErrsResp := &DeleteVersionsErrsResp{Errs: make([]error, totalVersions)}661 dErrsResp := &DeleteVersionsErrsResp{Errs: make([]error, totalVersions)}
661 662
662 w.Header().Set(xhttp.ContentType, "text/event-stream")663 setEventStreamHeaders(w)
663 encoder := gob.NewEncoder(w)664 encoder := gob.NewEncoder(w)
664 done := keepHTTPResponseAlive(w)665 done := keepHTTPResponseAlive(w)
665 errs := s.storage.DeleteVersions(volume, versions)666 errs := s.storage.DeleteVersions(volume, versions)
@@ -805,7 +806,7 @@ func (s *storageRESTServer) VerifyFileHandler(w http.ResponseWriter, r *http.Req · 139 unmodified lines
805 return806 return
806 }807 }
807 808
808 w.Header().Set(xhttp.ContentType, "text/event-stream")809 setEventStreamHeaders(w)
809 encoder := gob.NewEncoder(w)810 encoder := gob.NewEncoder(w)
810 done := keepHTTPResponseAlive(w)811 done := keepHTTPResponseAlive(w)
811 err = s.storage.VerifyFile(volume, filePath, fi)812 err = s.storage.VerifyFile(volume, filePath, fi)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t