Unified · Split
| @@ -695,7 +695,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { · 694 unmodified lines | ||
| 695 | 695 | // Start writing response to client |
| 696 | 696 | started = true |
| 697 | 697 | setCommonHeaders(w) |
| 698 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 698 | + setEventStreamHeaders(w) | |
| 699 | 699 | // Set 200 OK status |
| 700 | 700 | w.WriteHeader(200) |
| 701 | 701 | } |
| @@ -995,7 +995,7 @@ func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) { · 293 unmodified lines | ||
| 995 | 995 | return |
| 996 | 996 | } |
| 997 | 997 | |
| 998 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 998 | + setEventStreamHeaders(w) | |
| 999 | 999 | |
| 1000 | 1000 | // Trace Publisher and peer-trace-client uses nonblocking send and hence does not wait for slow receivers. |
| 1001 | 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 | 1064 | // This is needed to make r.Context().Done() work as |
| 1065 | 1065 | // expected in case of read timeout |
| 1066 | 1066 | w.Header().Add("Connection", "close") |
| 1067 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 1067 | + | |
| 1068 | + setEventStreamHeaders(w) | |
| 1068 | 1069 | |
| 1069 | 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 | 1226 | setCommonHeaders(w) |
| 1226 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 1227 | + | |
| 1228 | + setEventStreamHeaders(w) | |
| 1229 | + | |
| 1227 | 1230 | w.WriteHeader(http.StatusOK) |
| 1228 | 1231 | |
| 1229 | 1232 | errResp := func(err error) { |
| @@ -38,6 +38,13 @@ func mustGetRequestID(t time.Time) string { · 37 unmodified lines | ||
| 38 | 38 | return fmt.Sprintf("%X", t.UnixNano()) |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | +// setEventStreamHeaders to allow proxies to avoid buffering proxy responses | |
| 42 | +func 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 | 48 | // Write http common headers |
| 42 | 49 | func setCommonHeaders(w http.ResponseWriter) { |
| 43 | 50 | w.Header().Set(xhttp.ServerInfo, "MinIO/"+ReleaseTag) |
| @@ -22,7 +22,6 @@ import ( · 21 unmodified lines | ||
| 22 | 22 | "time" |
| 23 | 23 | |
| 24 | 24 | "github.com/gorilla/mux" |
| 25 | − xhttp "github.com/minio/minio/cmd/http" | |
| 26 | 25 | "github.com/minio/minio/cmd/logger" |
| 27 | 26 | policy "github.com/minio/minio/pkg/bucket/policy" |
| 28 | 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 | 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 | 123 | // Listen Publisher and peer-listen-client uses nonblocking send and hence does not wait for slow receivers. |
| 125 | 124 | // Use buffered channel to take care of burst sends or slow w.Write() |
| @@ -2615,7 +2615,9 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite · 2614 unmodified lines | ||
| 2615 | 2615 | w.Write(encodedErrorResponse) |
| 2616 | 2616 | w.(http.Flusher).Flush() |
| 2617 | 2617 | } |
| 2618 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 2618 | + | |
| 2619 | + setEventStreamHeaders(w) | |
| 2620 | + | |
| 2619 | 2621 | w = &whiteSpaceWriter{ResponseWriter: w, Flusher: w.(http.Flusher)} |
| 2620 | 2622 | completeDoneCh := sendWhiteSpace(w) |
| 2621 | 2623 | objInfo, err := completeMultiPartUpload(ctx, bucket, object, uploadID, completeParts, opts) |
| @@ -151,7 +151,8 @@ func (s *storageRESTServer) CrawlAndGetDataUsageHandler(w http.ResponseWriter, r · 150 unmodified lines | ||
| 151 | 151 | return |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 154 | + setEventStreamHeaders(w) | |
| 155 | + | |
| 155 | 156 | var cache dataUsageCache |
| 156 | 157 | err := cache.deserialize(r.Body) |
| 157 | 158 | if err != nil { |
| @@ -520,7 +521,7 @@ func (s *storageRESTServer) WalkSplunkHandler(w http.ResponseWriter, r *http.Req · 362 unmodified lines | ||
| 520 | 521 | dirPath := vars[storageRESTDirPath] |
| 521 | 522 | markerPath := vars[storageRESTMarkerPath] |
| 522 | 523 | |
| 523 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 524 | + setEventStreamHeaders(w) | |
| 524 | 525 | encoder := gob.NewEncoder(w) |
| 525 | 526 | |
| 526 | 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 | 549 | return |
| 549 | 550 | } |
| 550 | 551 | |
| 551 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 552 | + setEventStreamHeaders(w) | |
| 552 | 553 | encoder := gob.NewEncoder(w) |
| 553 | 554 | |
| 554 | 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 | 577 | return |
| 577 | 578 | } |
| 578 | 579 | |
| 579 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 580 | + setEventStreamHeaders(w) | |
| 580 | 581 | encoder := gob.NewEncoder(w) |
| 581 | 582 | |
| 582 | 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 | 661 | dErrsResp := &DeleteVersionsErrsResp{Errs: make([]error, totalVersions)} |
| 661 | 662 | |
| 662 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 663 | + setEventStreamHeaders(w) | |
| 663 | 664 | encoder := gob.NewEncoder(w) |
| 664 | 665 | done := keepHTTPResponseAlive(w) |
| 665 | 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 | 806 | return |
| 806 | 807 | } |
| 807 | 808 | |
| 808 | − w.Header().Set(xhttp.ContentType, "text/event-stream") | |
| 809 | + setEventStreamHeaders(w) | |
| 809 | 810 | encoder := gob.NewEncoder(w) |
| 810 | 811 | done := keepHTTPResponseAlive(w) |
| 811 | 812 | err = s.storage.VerifyFile(volume, filePath, fi) |