X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=blobdiff_plain;f=net%2Fhttp%2Fgzip%2Fgzip.go;fp=net%2Fhttp%2Fgzip%2Fgzip.go;h=7d84116beb9316f7a1bb6be7aa4bee3eced02c92;hp=0000000000000000000000000000000000000000;hb=db158dcf09436b003defd333f1a665e7e051d820;hpb=d09b7a78d44dc259725902b8141cdba0d716b121 diff --git a/net/http/gzip/gzip.go b/net/http/gzip/gzip.go new file mode 100644 index 00000000..7d84116b --- /dev/null +++ b/net/http/gzip/gzip.go @@ -0,0 +1,61 @@ +package gzip + +import ( + "bufio" + "compress/gzip" + "errors" + "io" + "net" + "net/http" + "strings" + "sync" +) + +var pool = sync.Pool{ + New: func() interface{} { + w, _ := gzip.NewWriterLevel(nil, gzip.BestSpeed) // #nosec + return w + }, +} + +func getWriter(w io.Writer) *gzip.Writer { + gz := pool.Get().(*gzip.Writer) + gz.Reset(w) + return gz +} + +type Handler struct { + Handler http.Handler +} + +func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Vary", "Accept-Encoding") + if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { + h.Handler.ServeHTTP(w, r) + return + } + w.Header().Set("Content-Encoding", "gzip") + gz := getWriter(w) + w = &responseWriter{gz, w} + h.Handler.ServeHTTP(w, r) + gz.Close() + pool.Put(gz) +} + +type responseWriter struct { + w io.Writer // w wraps only method Write + http.ResponseWriter // embedded for the other methods +} + +var _ http.ResponseWriter = (*responseWriter)(nil) +var _ http.Hijacker = (*responseWriter)(nil) + +func (w *responseWriter) Write(p []byte) (int, error) { return w.w.Write(p) } + +func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + h, ok := w.ResponseWriter.(http.Hijacker) + if !ok { + return nil, nil, errors.New("not a hijacker") + } + return h.Hijack() +}