...
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
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
53 default:
54 c.ErrHandler(w, r, fmt.Errorf("%s content encoding not supported", enc))
55 }
56 }
57
58 next(w, r)
59 }
60
View as plain text