mirror of
https://github.com/dstotijn/hetty.git
synced 2025-07-01 18:47:29 -04:00
Transparently decompress gzip
formatted response bodies
This commit is contained in:
35
pkg/proxy/gzip.go
Normal file
35
pkg/proxy/gzip.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func gunzipResponseBody(res *http.Response) error {
|
||||||
|
if res.Header.Get("Content-Encoding") != "gzip" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
gzipReader, err := gzip.NewReader(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("proxy: could not create gzip reader: %w", err)
|
||||||
|
}
|
||||||
|
defer gzipReader.Close()
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
|
||||||
|
//nolint:gosec
|
||||||
|
if _, err := io.Copy(buf, gzipReader); err != nil {
|
||||||
|
return fmt.Errorf("proxy: could not read gzipped response body: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res.Body = io.NopCloser(buf)
|
||||||
|
res.Header.Del("Content-Encoding")
|
||||||
|
res.Header.Set("Content-Length", fmt.Sprint(buf.Len()))
|
||||||
|
res.ContentLength = int64(buf.Len())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -114,6 +114,11 @@ func (p *Proxy) modifyRequest(r *http.Request) {
|
|||||||
func (p *Proxy) modifyResponse(res *http.Response) error {
|
func (p *Proxy) modifyResponse(res *http.Response) error {
|
||||||
fn := nopResModifier
|
fn := nopResModifier
|
||||||
|
|
||||||
|
// TODO: Make decompressing gzip formatted response bodies a configurable project setting.
|
||||||
|
if err := gunzipResponseBody(res); err != nil {
|
||||||
|
return fmt.Errorf("proxy: failed to gunzip response body: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
for i := len(p.resModifiers) - 1; i >= 0; i-- {
|
for i := len(p.resModifiers) - 1; i >= 0; i-- {
|
||||||
fn = p.resModifiers[i](fn)
|
fn = p.resModifiers[i](fn)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package reqlog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -267,23 +266,6 @@ func (svc *service) BypassOutOfScopeRequests() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseHTTPResponse(res *http.Response) (ResponseLog, error) {
|
func ParseHTTPResponse(res *http.Response) (ResponseLog, error) {
|
||||||
if res.Header.Get("Content-Encoding") == "gzip" {
|
|
||||||
gzipReader, err := gzip.NewReader(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
return ResponseLog{}, fmt.Errorf("reqlog: could not create gzip reader: %w", err)
|
|
||||||
}
|
|
||||||
defer gzipReader.Close()
|
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
|
|
||||||
//nolint:gosec
|
|
||||||
if _, err := io.Copy(buf, gzipReader); err != nil {
|
|
||||||
return ResponseLog{}, fmt.Errorf("reqlog: could not read gzipped response body: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Body = io.NopCloser(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ResponseLog{}, fmt.Errorf("reqlog: could not read body: %w", err)
|
return ResponseLog{}, fmt.Errorf("reqlog: could not read body: %w", err)
|
||||||
|
Reference in New Issue
Block a user