Commit 4a532c66 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http/httputil: ensure DumpRequestOut dumps all of Body

Bodies larger than 8KB (the default bufio reader size) weren't
being dumped.  Force a read of the body so they're teed into
the response buffer.

Thanks to Steven Hartland for identifying the problem.

Fixes #8089

LGTM=r
R=golang-codereviews, r
CC=adg, golang-codereviews
https://golang.org/cl/144650044
parent 1b89cd16
......@@ -95,19 +95,27 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
// with a dummy response.
var buf bytes.Buffer // records the output
pr, pw := io.Pipe()
defer pr.Close()
defer pw.Close()
dr := &delegateReader{c: make(chan io.Reader)}
// Wait for the request before replying with a dummy response:
go func() {
http.ReadRequest(bufio.NewReader(pr))
req, err := http.ReadRequest(bufio.NewReader(pr))
if err == nil {
// Ensure all the body is read; otherwise
// we'll get a partial dump.
io.Copy(ioutil.Discard, req.Body)
req.Body.Close()
}
dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\n\r\n")
}()
t := &http.Transport{
DisableKeepAlives: true,
Dial: func(net, addr string) (net.Conn, error) {
return &dumpConn{io.MultiWriter(&buf, pw), dr}, nil
},
}
defer t.CloseIdleConnections()
_, err := t.RoundTrip(reqSend)
......
......@@ -111,6 +111,30 @@ var dumpTests = []dumpTest{
NoBody: true,
},
// Request with Body > 8196 (default buffer size)
{
Req: http.Request{
Method: "POST",
URL: &url.URL{
Scheme: "http",
Host: "post.tld",
Path: "/",
},
ContentLength: 8193,
ProtoMajor: 1,
ProtoMinor: 1,
},
Body: bytes.Repeat([]byte("a"), 8193),
WantDumpOut: "POST / HTTP/1.1\r\n" +
"Host: post.tld\r\n" +
"User-Agent: Go 1.1 package http\r\n" +
"Content-Length: 8193\r\n" +
"Accept-Encoding: gzip\r\n\r\n" +
strings.Repeat("a", 8193),
},
}
func TestDumpRequest(t *testing.T) {
......@@ -125,6 +149,8 @@ func TestDumpRequest(t *testing.T) {
tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b))
case func() io.ReadCloser:
tt.Req.Body = b()
default:
t.Fatalf("Test %d: unsupported Body of %T", i, tt.Body)
}
}
setBody()
......@@ -159,7 +185,9 @@ func TestDumpRequest(t *testing.T) {
}
}
if dg := runtime.NumGoroutine() - numg0; dg > 4 {
t.Errorf("Unexpectedly large number of new goroutines: %d new", dg)
buf := make([]byte, 4096)
buf = buf[:runtime.Stack(buf, true)]
t.Errorf("Unexpectedly large number of new goroutines: %d new: %s", dg, buf)
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment