github.com/icyphox/x@v0.0.355-0.20220311094250-029bd783e8b8/httpx/gzip_server.go (about) 1 package httpx 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "net/http" 10 "strings" 11 ) 12 13 type CompressionRequestReader struct { 14 ErrHandler func(w http.ResponseWriter, r *http.Request, err error) 15 } 16 17 func defaultCompressionErrorHandler(w http.ResponseWriter, r *http.Request, err error) { 18 http.Error(w, err.Error(), http.StatusBadRequest) 19 } 20 21 func NewCompressionRequestReader(eh func(w http.ResponseWriter, r *http.Request, err error)) *CompressionRequestReader { 22 if eh == nil { 23 eh = defaultCompressionErrorHandler 24 } 25 26 return &CompressionRequestReader{ 27 ErrHandler: eh, 28 } 29 } 30 31 func (c *CompressionRequestReader) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 32 for _, enc := range strings.Split(r.Header.Get("Content-Encoding"), ",") { 33 switch enc = strings.TrimSpace(enc); enc { 34 case "gzip": 35 var b bytes.Buffer 36 reader, err := gzip.NewReader(r.Body) 37 if err != nil { 38 c.ErrHandler(w, r, err) 39 return 40 } 41 42 /* #nosec G110 - FIXME */ 43 if _, err := io.Copy(&b, reader); err != nil { 44 c.ErrHandler(w, r, err) 45 return 46 } 47 48 r.Body = ioutil.NopCloser(&b) 49 case "identity": 50 fallthrough 51 case "": 52 // nothing to do 53 default: 54 c.ErrHandler(w, r, fmt.Errorf("%s content encoding not supported", enc)) 55 } 56 } 57 58 next(w, r) 59 }