diff --git a/context.go b/context.go index 870590de..97bf620a 100644 --- a/context.go +++ b/context.go @@ -462,12 +462,10 @@ func (ctx *Context) Write(format string, a ...interface{}) { // Gzip accepts bytes, which are compressed to gzip format and sent to the client func (ctx *Context) Gzip(b []byte, status int) { - ctx.RequestCtx.Response.Header.Add("Content-Encoding", "gzip") - gzipWriter := ctx.framework.gzipWriterPool.Get().(*gzip.Writer) - gzipWriter.Reset(ctx.RequestCtx.Response.BodyWriter()) - gzipWriter.Write(b) - gzipWriter.Close() - ctx.framework.gzipWriterPool.Put(gzipWriter) + _, err := fasthttp.WriteGzip(ctx.RequestCtx.Response.BodyWriter(), b) + if err == nil { + ctx.RequestCtx.Response.Header.Add("Content-Encoding", "gzip") + } } // RenderWithStatus builds up the response from the specified template or a response engine. diff --git a/iris.go b/iris.go index 742f27ea..e6f3c686 100644 --- a/iris.go +++ b/iris.go @@ -199,10 +199,7 @@ func New(cfg ...config.Iris) *Framework { // we always use 's' no 'f' because 's' is easier for me to remember because of 'station' // some things never change :) s := &Framework{ - Config: &c, - gzipWriterPool: sync.Pool{New: func() interface{} { - return &gzip.Writer{} - }}, + Config: &c, responses: &responseEngines{}, Available: make(chan bool), } @@ -852,7 +849,15 @@ func (s *Framework) URL(routeName string, args ...interface{}) (url string) { // Note that: each iris station has its own pool // see ReleaseGzip func (s *Framework) AcquireGzip(w io.Writer) *gzip.Writer { - gzipWriter := s.gzipWriterPool.Get().(*gzip.Writer) + v := s.gzipWriterPool.Get() + if v == nil { + gzipWriter, err := gzip.NewWriterLevel(w, gzip.DefaultCompression) + if err != nil { + return nil + } + return gzipWriter + } + gzipWriter := v.(*gzip.Writer) gzipWriter.Reset(w) return gzipWriter } diff --git a/response.go b/response.go index 439af5cf..ee36ebe3 100644 --- a/response.go +++ b/response.go @@ -4,6 +4,7 @@ import ( "strings" "github.com/iris-contrib/errors" + "github.com/valyala/fasthttp" ) type ( @@ -151,9 +152,7 @@ func (r *responseEngineMap) render(ctx *Context, obj interface{}, options ...map ctx.SetContentType(ctype) if gzipEnabled { - gzipWriter := ctx.framework.AcquireGzip(ctx.Response.BodyWriter()) - defer ctx.framework.ReleaseGzip(gzipWriter) - _, err := gzipWriter.Write(finalResult) + _, err := fasthttp.WriteGzip(ctx.RequestCtx.Response.BodyWriter(), finalResult) if err != nil { return err } diff --git a/template.go b/template.go index 4d974adf..a6b9922b 100644 --- a/template.go +++ b/template.go @@ -190,6 +190,7 @@ func (t *templateEngineWrapper) execute(ctx *Context, filename string, binding i var out io.Writer if gzipEnabled { ctx.Response.Header.Add("Content-Encoding", "gzip") + gzipWriter := ctx.framework.AcquireGzip(ctx.Response.BodyWriter()) defer ctx.framework.ReleaseGzip(gzipWriter) out = gzipWriter @@ -197,7 +198,8 @@ func (t *templateEngineWrapper) execute(ctx *Context, filename string, binding i out = ctx.Response.BodyWriter() } - return t.ExecuteWriter(out, filename, binding, options...) + err = t.ExecuteWriter(out, filename, binding, options...) + return err } // executeToString executes a template from a specific template engine and returns its contents result as string, it doesn't renders