Skip to content

Commit a6a1d18

Browse files
committed
Make the gzip middleware work with streamed responses
I realized that the gzip middleware was not working with the streamed responses. Step to reproduce: * take the streaming example from here: https://github.com/ant0ine/go-json-rest-examples/tree/master/streaming * enable gzip compression with: "EnableGzip: true," in the resource handler. * go run streaming/main.go * curl --compressed -i http://127.0.0.1:8080/stream This change instantiates only one gzip writer per response writer, and flushes it after each write.
1 parent 39ea2b5 commit a6a1d18

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

rest/gzip.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func (mw *gzipMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
1717
// gzip support enabled
1818
canGzip := strings.Contains(r.Header.Get("Accept-Encoding"), "gzip")
1919
// client accepts gzip ?
20-
writer := &gzipResponseWriter{w, false, canGzip}
20+
writer := &gzipResponseWriter{w, false, canGzip, nil}
2121
// call the handler with the wrapped writer
2222
h(writer, r)
2323
}
@@ -35,6 +35,7 @@ type gzipResponseWriter struct {
3535
ResponseWriter
3636
wroteHeader bool
3737
canGzip bool
38+
gzipWriter *gzip.Writer
3839
}
3940

4041
// Set the right headers for gzip encoded responses.
@@ -96,9 +97,23 @@ func (w *gzipResponseWriter) Write(b []byte) (int, error) {
9697
writer := w.ResponseWriter.(http.ResponseWriter)
9798

9899
if w.canGzip {
99-
gzipWriter := gzip.NewWriter(writer)
100-
defer gzipWriter.Close()
101-
return gzipWriter.Write(b)
100+
// Write can be called multiple times for a given response.
101+
// (see the streaming example:
102+
// https://github.com/ant0ine/go-json-rest-examples/tree/master/streaming)
103+
// The gzipWriter is instantiated only once, and flushed after
104+
// each write.
105+
if w.gzipWriter == nil {
106+
w.gzipWriter = gzip.NewWriter(writer)
107+
}
108+
count, errW := w.gzipWriter.Write(b)
109+
errF := w.gzipWriter.Flush()
110+
if errW != nil {
111+
return count, errW
112+
}
113+
if errF != nil {
114+
return count, errF
115+
}
116+
return count, nil
102117
}
103118

104119
return writer.Write(b)

0 commit comments

Comments
 (0)