diff --git a/client.go b/client.go index b1eea7d9..cccf8e41 100644 --- a/client.go +++ b/client.go @@ -565,7 +565,7 @@ func (c *Client) SetTimeout(d time.Duration) *Client { func (c *Client) getDumpOptions() *DumpOptions { if c.dumpOptions == nil { - c.dumpOptions = newDefaultDumpOptions() + c.dumpOptions = NewDefaultDumpOptions() } return c.dumpOptions } diff --git a/client_test.go b/client_test.go index 7a6aeebe..6efbe4e8 100644 --- a/client_test.go +++ b/client_test.go @@ -17,6 +17,7 @@ import ( "testing" "time" + "github.com/imroc/req/v3/internal/dump" "github.com/imroc/req/v3/internal/header" "github.com/imroc/req/v3/internal/tests" "golang.org/x/net/publicsuffix" @@ -538,6 +539,26 @@ func testDisableAutoReadResponse(t *testing.T, c *Client) { tests.AssertNoError(t, err) } +func TestDumpBodyFormat(t *testing.T) { + var buff bytes.Buffer + opt := NewDefaultDumpOptions() + opt.Output = &buff + opt.RequestBodyFormat = dump.BodyFormatterFunc(func(p []byte, header http.Header) (formatted []byte, dumpImmediately bool) { + return append(p, []byte(" request formatted")...), true + }) + opt.ResponseBodyFormat = dump.BodyFormatterFunc(func(p []byte, header http.Header) (formatted []byte, dumpImmediately bool) { + return append(p, []byte(" response formatted")...), true + }) + + c := tc() + c.EnableDump(opt) + resp, err := c.R().SetBody("test body").Post("/") + assertSuccess(t, resp, err) + dump := buff.String() + tests.AssertContains(t, dump, " request formatted", true) + tests.AssertContains(t, dump, " response formatted", true) +} + func testEnableDumpAll(t *testing.T, fn func(c *Client) (de dumpExpected)) { testDump := func(c *Client) { buff := new(bytes.Buffer) diff --git a/dump.go b/dump.go index 77f96349..5c56ffd0 100644 --- a/dump.go +++ b/dump.go @@ -1,9 +1,10 @@ package req import ( - "github.com/imroc/req/v3/internal/dump" "io" "os" + + "github.com/imroc/req/v3/internal/dump" ) // DumpOptions controls the dump behavior. @@ -20,6 +21,9 @@ type DumpOptions struct { ResponseHeader bool ResponseBody bool Async bool + + RequestBodyFormat dump.BodyFormatter + ResponseBodyFormat dump.BodyFormatter } // Clone return a copy of DumpOptions @@ -35,6 +39,16 @@ type dumpOptions struct { *DumpOptions } +// RequestBodyFormatter implements dump.Options. +func (o dumpOptions) RequestBodyFormatter() dump.BodyFormatter { + return o.RequestBodyFormat +} + +// ResponseBodyFormatter implements dump.Options. +func (o dumpOptions) ResponseBodyFormatter() dump.BodyFormatter { + return o.ResponseBodyFormat +} + func (o dumpOptions) Output() io.Writer { if o.DumpOptions.Output == nil { return os.Stdout @@ -106,7 +120,8 @@ func (o dumpOptions) Clone() dump.Options { return dumpOptions{o.DumpOptions.Clone()} } -func newDefaultDumpOptions() *DumpOptions { +// NewDefaultDumpOptions returns a new default DumpOptions. +func NewDefaultDumpOptions() *DumpOptions { return &DumpOptions{ Output: os.Stdout, RequestBody: true, @@ -118,7 +133,7 @@ func newDefaultDumpOptions() *DumpOptions { func newDumper(opt *DumpOptions) *dump.Dumper { if opt == nil { - opt = newDefaultDumpOptions() + opt = NewDefaultDumpOptions() } if opt.Output == nil { opt.Output = os.Stderr diff --git a/dump_test.go b/dump_test.go new file mode 100644 index 00000000..72145538 --- /dev/null +++ b/dump_test.go @@ -0,0 +1,87 @@ +package req + +import ( + "bytes" + "fmt" + "github.com/imroc/req/v3/internal/tests" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/hjson/hjson-go/v4" +) + +type hjsonFormatter struct { + buf bytes.Buffer +} + +func (d *hjsonFormatter) BodyFormat(p []byte, header http.Header) (formatted []byte, dumpImmediately bool) { + if !strings.HasPrefix(header.Get("Content-Type"), "application/json") { + return p, true + } + + d.buf.Write(p) + + buf := d.buf.Bytes() + var data interface{} + if err := hjson.Unmarshal(buf, &data); err != nil { + return nil, false + } + + d.buf.Reset() + + hb, err := hjson.Marshal(data) + if err != nil { + return []byte(fmt.Sprintf("hjson error: %v", err)), true + } + + return hb, true +} + +func TestBodyFormatter(t *testing.T) { + server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Header().Set("Date", "Wed, 12 Mar 2025 05:39:45 GMT") + w.Write([]byte(`{"name": "bingoohuang", "age": 134}`)) + })) + server.Start() + defer server.Close() + + c := C() + opt := NewDefaultDumpOptions() + var buf bytes.Buffer + opt.Output = &buf + opt.RequestBodyFormat = &hjsonFormatter{} + opt.ResponseBodyFormat = &hjsonFormatter{} + c.EnableDump(opt) + + c.R(). + SetHeader("Host", "localhost"). + SetBody(map[string]any{"highhandedly": "gastroduodenoscopy", "epipodite": 13.4}). + Post(server.URL) + + expected := `POST / HTTP/1.1 +Host: localhost +User-Agent: req/v3 (https://github.com/imroc/req) +Content-Length: 54 +Content-Type: application/json; charset=utf-8 +Accept-Encoding: gzip + +{ + epipodite: 13.4 + highhandedly: gastroduodenoscopy +} +HTTP/1.1 200 OK +Content-Type: application/json +Date: Wed, 12 Mar 2025 05:39:45 GMT +Content-Length: 35 + +{ + age: 134 + name: bingoohuang +} +` + + tests.AssertEqual(t, expected, strings.ReplaceAll(buf.String(), "\r", "")) +} diff --git a/go.mod b/go.mod index c54597be..04196762 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.0 require ( github.com/andybalholm/brotli v1.1.1 github.com/hashicorp/go-multierror v1.1.1 + github.com/hjson/hjson-go/v4 v4.4.0 github.com/klauspost/compress v1.17.11 github.com/quic-go/qpack v0.5.1 github.com/quic-go/quic-go v0.48.2 diff --git a/go.sum b/go.sum index 98c5fd3b..e11b9c37 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,15 @@ -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= -github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY= -github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20241203143554-1e3fdc7de467 h1:keEZFtbLJugfE0qHn+Ge1JCE71spzkchQobDf3mzS/4= -github.com/google/pprof v0.0.0-20241203143554-1e3fdc7de467/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -24,8 +17,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/hjson/hjson-go/v4 v4.4.0 h1:D/NPvqOCH6/eisTb5/ztuIS8GUvmpHaLOcNk1Bjr298= +github.com/hjson/hjson-go/v4 v4.4.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= @@ -42,41 +35,26 @@ github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e h1:4qufH0hlUYs6AO6XmZC3GqfDPGSXHVXUFR6OND+iJX4= golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= diff --git a/internal/dump/dump.go b/internal/dump/dump.go index 0c52638a..0f3e9811 100644 --- a/internal/dump/dump.go +++ b/internal/dump/dump.go @@ -6,13 +6,39 @@ import ( "net/http" ) +// BodyFormatter is the interface for body formatter. +type BodyFormatter interface { + // BodyFormat formats the body and returns the formatted body and a boolean value indicating whether to dump immediately. + BodyFormat(p []byte, header http.Header) (formatted []byte, dumpImmediately bool) +} + +// BodyFormatterFunc is a function that implements the BodyFormatter interface. +type BodyFormatterFunc func(p []byte, header http.Header) (formatted []byte, dumpImmediately bool) + +// BodyFormat implements the BodyFormatter interface. +func (f BodyFormatterFunc) BodyFormat(p []byte, header http.Header) (formatted []byte, dumpImmediately bool) { + return f(p, header) +} + // Options controls the dump behavior. type Options interface { Output() io.Writer RequestHeaderOutput() io.Writer RequestBodyOutput() io.Writer + + // RequestBodyFormatter returns the request body formatter. + // If nil, the request body will not be formatted. + // Here you can use a customized formatter like for JSON pretty format, JSON to HTML format, etc. + RequestBodyFormatter() BodyFormatter + ResponseHeaderOutput() io.Writer ResponseBodyOutput() io.Writer + + // ResponseBodyFormatter, as like RequestBodyFormatter, returns the response body formatter. + // If nil, the response body will not be formatted. + // Here you can use a customized formatter like for JSON pretty format, JSON to HTML format, etc. + ResponseBodyFormatter() BodyFormatter + RequestHeader() bool RequestBody() bool ResponseHeader() bool @@ -21,36 +47,38 @@ type Options interface { Clone() Options } -func (d *Dumper) WrapResponseBodyReadCloser(rc io.ReadCloser) io.ReadCloser { - return &dumpResponseBodyReadCloser{rc, d} +func (d *Dumper) WrapResponseBodyReadCloser(rc io.ReadCloser, header http.Header) io.ReadCloser { + return &dumpResponseBodyReadCloser{rc, d, header} } type dumpResponseBodyReadCloser struct { io.ReadCloser - dump *Dumper + dump *Dumper + header http.Header } func (r *dumpResponseBodyReadCloser) Read(p []byte) (n int, err error) { n, err = r.ReadCloser.Read(p) - r.dump.DumpResponseBody(p[:n]) + r.dump.DumpResponseBody(p[:n], r.header) if err == io.EOF { r.dump.DumpDefault([]byte("\r\n")) } return } -func (d *Dumper) WrapRequestBodyWriteCloser(rc io.WriteCloser) io.WriteCloser { - return &dumpRequestBodyWriteCloser{rc, d} +func (d *Dumper) WrapRequestBodyWriteCloser(rc io.WriteCloser, header http.Header) io.WriteCloser { + return &dumpRequestBodyWriteCloser{rc, d, header} } type dumpRequestBodyWriteCloser struct { io.WriteCloser - dump *Dumper + dump *Dumper + header http.Header } func (w *dumpRequestBodyWriteCloser) Write(p []byte) (n int, err error) { n, err = w.WriteCloser.Write(p) - w.dump.DumpRequestBody(p[:n]) + w.dump.DumpRequestBody(p[:n], w.header) return } @@ -73,20 +101,22 @@ func (d *Dumper) WrapRequestHeaderWriter(w io.Writer) io.Writer { } type dumpRequestBodyWriter struct { - w io.Writer - dump *Dumper + w io.Writer + dump *Dumper + header http.Header } func (w *dumpRequestBodyWriter) Write(p []byte) (n int, err error) { n, err = w.w.Write(p) - w.dump.DumpRequestBody(p[:n]) + w.dump.DumpRequestBody(p[:n], w.header) return } -func (d *Dumper) WrapRequestBodyWriter(w io.Writer) io.Writer { +func (d *Dumper) WrapRequestBodyWriter(w io.Writer, header http.Header) io.Writer { return &dumpRequestBodyWriter{ - w: w, - dump: d, + w: w, + dump: d, + header: header, } } @@ -171,7 +201,15 @@ func (d *Dumper) DumpRequestHeader(p []byte) { d.DumpTo(p, d.RequestHeaderOutput()) } -func (d *Dumper) DumpRequestBody(p []byte) { +func (d *Dumper) DumpRequestBody(p []byte, header http.Header) { + if bd := d.RequestBodyFormatter(); bd != nil { + if pp, ok := bd.BodyFormat(p, header); ok { + p = pp + } else if !ok { + return + } + } + d.DumpTo(p, d.RequestBodyOutput()) } @@ -179,7 +217,15 @@ func (d *Dumper) DumpResponseHeader(p []byte) { d.DumpTo(p, d.ResponseHeaderOutput()) } -func (d *Dumper) DumpResponseBody(p []byte) { +func (d *Dumper) DumpResponseBody(p []byte, header http.Header) { + if bd := d.ResponseBodyFormatter(); bd != nil { + if pp, ok := bd.BodyFormat(p, header); ok { + p = pp + } else if !ok { + return + } + } + d.DumpTo(p, d.ResponseBodyOutput()) } @@ -218,7 +264,7 @@ func WrapResponseBodyIfNeeded(res *http.Response, req *http.Request, dump *Dumpe dumps := GetDumpers(req.Context(), dump) for _, d := range dumps { if d.ResponseBody() { - res.Body = d.WrapResponseBodyReadCloser(res.Body) + res.Body = d.WrapResponseBodyReadCloser(res.Body, res.Header) } } } diff --git a/internal/http2/transport.go b/internal/http2/transport.go index fea6685c..50f6a5a4 100644 --- a/internal/http2/transport.go +++ b/internal/http2/transport.go @@ -1716,7 +1716,7 @@ func (cs *clientStream) writeRequestBody(req *http.Request, dumps []*dump.Dumper if len(dumps) > 0 { writeData = func(streamID uint32, endStream bool, data []byte) error { for _, dump := range dumps { - dump.DumpRequestBody(data) + dump.DumpRequestBody(data, req.Header) } return cc.fr.WriteData(streamID, endStream, data) } diff --git a/transfer.go b/transfer.go index e9cd5a56..e1846728 100644 --- a/transfer.go +++ b/transfer.go @@ -310,7 +310,7 @@ func (t *transferWriter) writeBody(w io.Writer, dumps []*dump.Dumper) (err error rw := w // raw writer for _, dump := range dumps { if dump.RequestBody() { - w = dump.WrapRequestBodyWriter(w) + w = dump.WrapRequestBodyWriter(w, t.Header) } } @@ -327,7 +327,7 @@ func (t *transferWriter) writeBody(w io.Writer, dumps []*dump.Dumper) (err error cw := internal.NewChunkedWriter(rw) for _, dump := range dumps { if dump.RequestBody() { - cw = dump.WrapRequestBodyWriteCloser(cw) + cw = dump.WrapRequestBodyWriteCloser(cw, t.Header) } } _, err = t.doBodyCopy(cw, body)