diff --git a/h2_bundle.go b/h2_bundle.go index dd968f67..cd9fdd48 100644 --- a/h2_bundle.go +++ b/h2_bundle.go @@ -49,7 +49,7 @@ import ( "sync" "sync/atomic" "time" - + "compress/gzip" "github.com/useflyent/fhttp/http2/hpack" "github.com/useflyent/fhttp/httptrace" "golang.org/x/net/http/httpguts" @@ -8976,10 +8976,41 @@ func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http cs.bytesRemain = res.ContentLength res.Body = http2transportResponseBody{cs} go cs.awaitRequestCancel(cs.req) - - res.Body = DecompressBody(res) + if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" { + res.Header.Del("Content-Encoding") + res.Header.Del("Content-Length") + res.ContentLength = -1 + res.Body = &http2gzipReader{body: res.Body} + res.Uncompressed = true + } return res, nil } +// gzipReader wraps a response body so it can lazily +// call gzip.NewReader on the first call to Read +type http2gzipReader struct { + _ http2incomparable + body io.ReadCloser // underlying Response.Body + zr *gzip.Reader // lazily-initialized gzip reader + zerr error // sticky error +} +func (gz *http2gzipReader) Read(p []byte) (n int, err error) { + if gz.zerr != nil { + return 0, gz.zerr + } + if gz.zr == nil { + gz.zr, err = gzip.NewReader(gz.body) + if err != nil { + gz.zerr = err + return 0, err + } + } + return gz.zr.Read(p) +} + +func (gz *http2gzipReader) Close() error { + return gz.body.Close() +} + func (rl *http2clientConnReadLoop) processTrailers(cs *http2clientStream, f *http2MetaHeadersFrame) error { if cs.pastTrailers {