Skip to content

Commit 92f4ff6

Browse files
Merge pull request #87 from basecamp/prevent-response-buffering
Ensure all response writers are flushable
2 parents d79c073 + 3707aac commit 92f4ff6

File tree

4 files changed

+42
-0
lines changed

4 files changed

+42
-0
lines changed

internal/cacheable_response.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ func (c *CacheableResponse) WriteHeader(statusCode int) {
7575
c.headersWritten = true
7676
}
7777

78+
func (c *CacheableResponse) Flush() {
79+
flusher, ok := c.responseWriter.(http.Flusher)
80+
if ok {
81+
flusher.Flush()
82+
}
83+
}
84+
7885
func (c *CacheableResponse) CacheStatus() (bool, time.Time) {
7986
if c.stasher.Overflowed() {
8087
return false, time.Time{}

internal/handler_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package internal
22

33
import (
44
"bytes"
5+
"fmt"
56
"net/http"
67
"net/http/httptest"
78
"net/url"
@@ -280,6 +281,26 @@ func TestHandlerAddsXRequestStartHeader(t *testing.T) {
280281
assert.Equal(t, http.StatusOK, w.Code)
281282
}
282283

284+
func TestHandlerAllowsFlushingTheResponseBody(t *testing.T) {
285+
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
286+
w.Header().Set("Content-Type", "text/event-stream")
287+
fmt.Fprintf(w, "data: event\n\n")
288+
w.(http.Flusher).Flush()
289+
290+
}))
291+
defer upstream.Close()
292+
293+
h := NewHandler(handlerOptions(upstream.URL))
294+
295+
w := httptest.NewRecorder()
296+
r := httptest.NewRequest("GET", "/", nil)
297+
h.ServeHTTP(w, r)
298+
299+
assert.Equal(t, http.StatusOK, w.Code)
300+
assert.Equal(t, "text/event-stream", w.Header().Get("Content-Type"))
301+
assert.True(t, w.Flushed)
302+
}
303+
283304
// Helpers
284305

285306
func handlerOptions(targetUrl string) HandlerOptions {

internal/logging_middleware.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,10 @@ func (r *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
8787
}
8888
return con, rw, err
8989
}
90+
91+
func (r *responseWriter) Flush() {
92+
flusher, ok := r.ResponseWriter.(http.Flusher)
93+
if ok {
94+
flusher.Flush()
95+
}
96+
}

internal/sendfile_handler.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ func (w *sendfileWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
7979
return hijacker.Hijack()
8080
}
8181

82+
func (w *sendfileWriter) Flush() {
83+
flusher, ok := w.w.(http.Flusher)
84+
if ok {
85+
flusher.Flush()
86+
}
87+
}
88+
8289
func (w *sendfileWriter) sendingFilename() string {
8390
return w.w.Header().Get("X-Sendfile")
8491
}

0 commit comments

Comments
 (0)