github.com/nsqio/nsq@v1.3.0/internal/http_api/compress.go (about) 1 // Copyright 2013 The Gorilla Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // copied from https://github.com/gorilla/handlers/blob/master/compress.go 6 7 package http_api 8 9 import ( 10 "compress/flate" 11 "compress/gzip" 12 "io" 13 "net/http" 14 "strings" 15 ) 16 17 type compressResponseWriter struct { 18 io.Writer 19 http.ResponseWriter 20 http.Hijacker 21 } 22 23 func (w *compressResponseWriter) Header() http.Header { 24 return w.ResponseWriter.Header() 25 } 26 27 func (w *compressResponseWriter) WriteHeader(c int) { 28 w.ResponseWriter.Header().Del("Content-Length") 29 w.ResponseWriter.WriteHeader(c) 30 } 31 32 func (w *compressResponseWriter) Write(b []byte) (int, error) { 33 h := w.ResponseWriter.Header() 34 if h.Get("Content-Type") == "" { 35 h.Set("Content-Type", http.DetectContentType(b)) 36 } 37 h.Del("Content-Length") 38 return w.Writer.Write(b) 39 } 40 41 // CompressHandler gzip compresses HTTP responses for clients that support it 42 // via the 'Accept-Encoding' header. 43 func CompressHandler(h http.Handler) http.Handler { 44 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 45 L: 46 for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") { 47 switch strings.TrimSpace(enc) { 48 case "gzip": 49 w.Header().Set("Content-Encoding", "gzip") 50 w.Header().Add("Vary", "Accept-Encoding") 51 52 gw := gzip.NewWriter(w) 53 defer gw.Close() 54 55 h, hok := w.(http.Hijacker) 56 if !hok { /* w is not Hijacker... oh well... */ 57 h = nil 58 } 59 60 w = &compressResponseWriter{ 61 Writer: gw, 62 ResponseWriter: w, 63 Hijacker: h, 64 } 65 66 break L 67 case "deflate": 68 w.Header().Set("Content-Encoding", "deflate") 69 w.Header().Add("Vary", "Accept-Encoding") 70 71 fw, _ := flate.NewWriter(w, flate.DefaultCompression) 72 defer fw.Close() 73 74 h, hok := w.(http.Hijacker) 75 if !hok { /* w is not Hijacker... oh well... */ 76 h = nil 77 } 78 79 w = &compressResponseWriter{ 80 Writer: fw, 81 ResponseWriter: w, 82 Hijacker: h, 83 } 84 85 break L 86 } 87 } 88 89 h.ServeHTTP(w, r) 90 }) 91 }