1
0
mirror of https://github.com/labstack/echo.git synced 2025-04-21 12:17:04 +02:00

Add sync.Pool to gzip middleware

This commit is contained in:
Tyler Bunnell 2015-09-11 16:23:57 -06:00
parent 33eb3fb67b
commit 4f3335aac7
2 changed files with 36 additions and 2 deletions

@ -4,9 +4,11 @@ import (
"bufio" "bufio"
"compress/gzip" "compress/gzip"
"io" "io"
"io/ioutil"
"net" "net"
"net/http" "net/http"
"strings" "strings"
"sync"
"github.com/labstack/echo" "github.com/labstack/echo"
) )
@ -37,6 +39,12 @@ func (w *gzipWriter) CloseNotify() <-chan bool {
return w.ResponseWriter.(http.CloseNotifier).CloseNotify() return w.ResponseWriter.(http.CloseNotifier).CloseNotify()
} }
var writerPool = sync.Pool{
New: func() interface{} {
return gzip.NewWriter(ioutil.Discard)
},
}
// Gzip returns a middleware which compresses HTTP response using gzip compression // Gzip returns a middleware which compresses HTTP response using gzip compression
// scheme. // scheme.
func Gzip() echo.MiddlewareFunc { func Gzip() echo.MiddlewareFunc {
@ -46,8 +54,12 @@ func Gzip() echo.MiddlewareFunc {
return func(c *echo.Context) error { return func(c *echo.Context) error {
c.Response().Header().Add(echo.Vary, echo.AcceptEncoding) c.Response().Header().Add(echo.Vary, echo.AcceptEncoding)
if strings.Contains(c.Request().Header.Get(echo.AcceptEncoding), scheme) { if strings.Contains(c.Request().Header.Get(echo.AcceptEncoding), scheme) {
w := gzip.NewWriter(c.Response().Writer()) w := writerPool.Get().(*gzip.Writer)
defer w.Close() w.Reset(c.Response().Writer())
defer func() {
w.Close()
writerPool.Put(w)
}()
gw := gzipWriter{Writer: w, ResponseWriter: c.Response().Writer()} gw := gzipWriter{Writer: w, ResponseWriter: c.Response().Writer()}
c.Response().Header().Set(echo.ContentEncoding, scheme) c.Response().Header().Set(echo.ContentEncoding, scheme)
c.Response().SetWriter(gw) c.Response().SetWriter(gw)

@ -119,3 +119,25 @@ func TestGzipCloseNotify(t *testing.T) {
assert.Equal(t, closed, true) assert.Equal(t, closed, true)
} }
func BenchmarkGzip(b *testing.B) {
b.StopTimer()
b.ReportAllocs()
h := func(c *echo.Context) error {
c.Response().Write([]byte("test")) // For Content-Type sniffing
return nil
}
req, _ := http.NewRequest(echo.GET, "/", nil)
req.Header.Set(echo.AcceptEncoding, "gzip")
b.StartTimer()
for i := 0; i < b.N; i++ {
rec := httptest.NewRecorder()
c := echo.NewContext(req, echo.NewResponse(rec), echo.New())
Gzip()(h)(c)
}
}