github.com/rpdict/ponzu@v0.10.1-0.20190226054626-477f29d6bf5e/system/api/gzip.go (about)

     1  package api
     2  
     3  import (
     4  	"compress/gzip"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/rpdict/ponzu/system/db"
     9  )
    10  
    11  // Gzip wraps a HandlerFunc to compress responses when possible
    12  func Gzip(next http.HandlerFunc) http.HandlerFunc {
    13  	return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    14  		if db.ConfigCache("gzip_disabled").(bool) == true {
    15  			next.ServeHTTP(res, req)
    16  			return
    17  		}
    18  
    19  		// check if req header content-encoding supports gzip
    20  		if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
    21  			// gzip response data
    22  			res.Header().Set("Content-Encoding", "gzip")
    23  			gzWriter := gzip.NewWriter(res)
    24  			defer gzWriter.Close()
    25  			var gzres gzipResponseWriter
    26  			if pusher, ok := res.(http.Pusher); ok {
    27  				gzres = gzipResponseWriter{res, pusher, gzWriter}
    28  			} else {
    29  				gzres = gzipResponseWriter{res, nil, gzWriter}
    30  			}
    31  
    32  			next.ServeHTTP(gzres, req)
    33  			return
    34  		}
    35  
    36  		next.ServeHTTP(res, req)
    37  	})
    38  }
    39  
    40  type gzipResponseWriter struct {
    41  	http.ResponseWriter
    42  	pusher http.Pusher
    43  
    44  	gw *gzip.Writer
    45  }
    46  
    47  func (gzw gzipResponseWriter) Write(p []byte) (int, error) {
    48  	return gzw.gw.Write(p)
    49  }
    50  
    51  func (gzw gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
    52  	if gzw.pusher == nil {
    53  		return nil
    54  	}
    55  
    56  	if opts == nil {
    57  		opts = &http.PushOptions{
    58  			Header: make(http.Header),
    59  		}
    60  	}
    61  
    62  	opts.Header.Set("Accept-Encoding", "gzip")
    63  
    64  	return gzw.pusher.Push(target, opts)
    65  }