You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-mitmproxy/proxy/flowencoding.go

120 lines
2.3 KiB
Go

package proxy
import (
"bytes"
"compress/flate"
"compress/gzip"
"errors"
"io"
"strconv"
"strings"
"github.com/andybalholm/brotli"
)
var errEncodingNotSupport = errors.New("content-encoding not support")
var textContentTypes = []string{
"text",
"javascript",
"json",
}
func (r *Response) IsTextContentType() bool {
contentType := r.Header.Get("Content-Type")
if contentType == "" {
return false
}
for _, substr := range textContentTypes {
if strings.Contains(contentType, substr) {
return true
}
}
return false
}
func (r *Response) DecodedBody() ([]byte, error) {
if r.decodedBody != nil {
return r.decodedBody, nil
}
if r.decodedErr != nil {
return nil, r.decodedErr
}
if r.Body == nil {
return nil, nil
}
if len(r.Body) == 0 {
r.decodedBody = r.Body
return r.decodedBody, nil
}
enc := r.Header.Get("Content-Encoding")
if enc == "" || enc == "identity" {
r.decodedBody = r.Body
return r.decodedBody, nil
}
decodedBody, decodedErr := decode(enc, r.Body)
if decodedErr != nil {
r.decodedErr = decodedErr
log.Error(r.decodedErr)
return nil, decodedErr
}
r.decodedBody = decodedBody
r.decoded = true
return r.decodedBody, nil
}
func (r *Response) ReplaceToDecodedBody() {
body, err := r.DecodedBody()
if err != nil || body == nil {
return
}
r.Body = body
r.Header.Del("Content-Encoding")
r.Header.Set("Content-Length", strconv.Itoa(len(body)))
r.Header.Del("Transfer-Encoding")
}
func decode(enc string, body []byte) ([]byte, error) {
if enc == "gzip" {
dreader, err := gzip.NewReader(bytes.NewReader(body))
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(make([]byte, 0))
_, err = io.Copy(buf, dreader)
if err != nil {
return nil, err
}
err = dreader.Close()
if err != nil {
return nil, err
}
return buf.Bytes(), nil
} else if enc == "br" {
dreader := brotli.NewReader(bytes.NewReader(body))
buf := bytes.NewBuffer(make([]byte, 0))
_, err := io.Copy(buf, dreader)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
} else if enc == "deflate" {
dreader := flate.NewReader(bytes.NewReader(body))
buf := bytes.NewBuffer(make([]byte, 0))
_, err := io.Copy(buf, dreader)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
return nil, errEncodingNotSupport
}