11package middleware
22
33import (
4- "bytes"
54 "compress/gzip"
65 "io"
7- "io/ioutil"
86 "net/http"
97 "sync"
108
@@ -43,26 +41,7 @@ type DefaultGzipDecompressPool struct {
4341}
4442
4543func (d * DefaultGzipDecompressPool ) gzipDecompressPool () sync.Pool {
46- return sync.Pool {
47- New : func () interface {} {
48- // create with an empty reader (but with GZIP header)
49- w , err := gzip .NewWriterLevel (ioutil .Discard , gzip .BestSpeed )
50- if err != nil {
51- return err
52- }
53-
54- b := new (bytes.Buffer )
55- w .Reset (b )
56- w .Flush ()
57- w .Close ()
58-
59- r , err := gzip .NewReader (bytes .NewReader (b .Bytes ()))
60- if err != nil {
61- return err
62- }
63- return r
64- },
65- }
44+ return sync.Pool {New : func () interface {} { return new (gzip.Reader ) }}
6645}
6746
6847//Decompress decompresses request body based if content encoding type is set to "gzip" with default config
@@ -82,38 +61,38 @@ func DecompressWithConfig(config DecompressConfig) echo.MiddlewareFunc {
8261
8362 return func (next echo.HandlerFunc ) echo.HandlerFunc {
8463 pool := config .GzipDecompressPool .gzipDecompressPool ()
64+
8565 return func (c echo.Context ) error {
8666 if config .Skipper (c ) {
8767 return next (c )
8868 }
89- switch c .Request ().Header .Get (echo .HeaderContentEncoding ) {
90- case GZIPEncoding :
91- b := c .Request ().Body
92-
93- i := pool .Get ()
94- gr , ok := i .(* gzip.Reader )
95- if ! ok {
96- return echo .NewHTTPError (http .StatusInternalServerError , i .(error ).Error ())
97- }
9869
99- if err := gr .Reset (b ); err != nil {
100- pool .Put (gr )
101- if err == io .EOF { //ignore if body is empty
102- return next (c )
103- }
104- return err
105- }
106- var buf bytes.Buffer
107- io .Copy (& buf , gr )
70+ if c .Request ().Header .Get (echo .HeaderContentEncoding ) != GZIPEncoding {
71+ return next (c )
72+ }
10873
109- gr .Close ()
110- pool .Put (gr )
74+ i := pool .Get ()
75+ gr , ok := i .(* gzip.Reader )
76+ if ! ok || gr == nil {
77+ return echo .NewHTTPError (http .StatusInternalServerError , i .(error ).Error ())
78+ }
79+ defer pool .Put (gr )
11180
112- b .Close () // http.Request.Body is closed by the Server, but because we are replacing it, it must be closed here
81+ b := c .Request ().Body
82+ defer b .Close ()
11383
114- r := ioutil .NopCloser (& buf )
115- c .Request ().Body = r
84+ if err := gr .Reset (b ); err != nil {
85+ if err == io .EOF { //ignore if body is empty
86+ return next (c )
87+ }
88+ return err
11689 }
90+
91+ // only Close gzip reader if it was set to a proper gzip source otherwise it will panic on close.
92+ defer gr .Close ()
93+
94+ c .Request ().Body = gr
95+
11796 return next (c )
11897 }
11998 }
0 commit comments