From 538e5006823b3ffa85806cb33d7770f32bb76d77 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 24 May 2017 19:32:33 +0200 Subject: [PATCH] Issue #300: GzipHandler should implement http.Hijacker --- proxy/gzip/gzip_handler.go | 39 +++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/proxy/gzip/gzip_handler.go b/proxy/gzip/gzip_handler.go index 046eb5b14..42efd8884 100644 --- a/proxy/gzip/gzip_handler.go +++ b/proxy/gzip/gzip_handler.go @@ -8,8 +8,11 @@ package gzip import ( + "bufio" "compress/gzip" + "errors" "io" + "net" "net/http" "regexp" "strings" @@ -29,21 +32,35 @@ var gzipWriterPool = sync.Pool{ New: func() interface{} { return gzip.NewWriter(nil) }, } +type gzipHandler struct { + h http.Handler + contentTypes *regexp.Regexp +} + +func (h *gzipHandler) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if hj, ok := h.h.(http.Hijacker); ok { + return hj.Hijack() + } + return nil, nil, errors.New("not a Hijacker") +} + +func (h *gzipHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Add(headerVary, headerAcceptEncoding) + + if acceptsGzip(r) { + gzWriter := NewGzipResponseWriter(w, h.contentTypes) + defer gzWriter.Close() + h.h.ServeHTTP(gzWriter, r) + } else { + h.h.ServeHTTP(w, r) + } +} + // NewGzipHandler wraps an existing handler to transparently gzip the response // body if the client supports it (via the Accept-Encoding header) and the // response Content-Type matches the contentTypes expression. func NewGzipHandler(h http.Handler, contentTypes *regexp.Regexp) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Add(headerVary, headerAcceptEncoding) - - if acceptsGzip(r) { - gzWriter := NewGzipResponseWriter(w, contentTypes) - defer gzWriter.Close() - h.ServeHTTP(gzWriter, r) - } else { - h.ServeHTTP(w, r) - } - }) + return &gzipHandler{h, contentTypes} } type GzipResponseWriter struct {