diff options
author | nirav <nirav@teisuu.com> | 2021-10-24 04:31:35 +0000 |
---|---|---|
committer | nirav <nirav@teisuu.com> | 2021-10-24 04:31:35 +0000 |
commit | c331f26cc305c33701725f3c2ddfd10123df618c (patch) | |
tree | fcca532f1a4ed9b41e527376f8f8d4ffab8dd041 | |
parent | ea6350e4ea7d1978dee0bbeba5fcaaace539aa4c (diff) | |
download | gziphandler-c331f26cc305c33701725f3c2ddfd10123df618c.tar.gz gziphandler-c331f26cc305c33701725f3c2ddfd10123df618c.zip |
-rw-r--r-- | handler.go | 51 |
1 files changed, 35 insertions, 16 deletions
@@ -2,23 +2,30 @@ package gziphandler import ( "compress/gzip" + "io/ioutil" "net/http" "strings" + "sync" ) -type gw struct { +type respWriter struct { http.ResponseWriter w *gzip.Writer } -func (w *gw) Write(d []byte) (int, error) { +func (w *respWriter) Write(d []byte) (int, error) { return w.w.Write(d) } -func (w *gw) Close() error { +func (w *respWriter) Close() error { return w.w.Close() } +type handler struct { + next http.Handler + pool sync.Pool +} + func acceptsGzip(r *http.Request) bool { ae := r.Header.Get("Accept-Encoding") for _, e := range strings.Split(ae, ",") { @@ -33,21 +40,33 @@ func acceptsGzip(r *http.Request) bool { return false } +func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if !acceptsGzip(r) { + h.next.ServeHTTP(w, r) + return + } + w.Header().Set("Content-Encoding", "gzip") + gw := h.pool.Get().(*gzip.Writer) + gw.Reset(w) + rw := &respWriter{ + ResponseWriter: w, + w: gw, + } + h.next.ServeHTTP(rw, r) + gw.Close() + h.pool.Put(gw) +} + // Handler returns an http.Handler that compresses the response data written // by an existing handler h, using the compress/gzip.Writer with default // compression level. func Handler(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !acceptsGzip(r) { - h.ServeHTTP(w, r) - return - } - w.Header().Set("Content-Encoding", "gzip") - gw := &gw{ - ResponseWriter: w, - w: gzip.NewWriter(w), - } - h.ServeHTTP(gw, r) - gw.Close() - }) + return &handler{ + next: h, + pool: sync.Pool{ + New: func() interface{} { + return gzip.NewWriter(ioutil.Discard) + }, + }, + } } |