diff options
Diffstat (limited to 'libgo/go/net/http/httputil/dump.go')
-rw-r--r-- | libgo/go/net/http/httputil/dump.go | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/libgo/go/net/http/httputil/dump.go b/libgo/go/net/http/httputil/dump.go index e22cc66dbf..7104c37454 100644 --- a/libgo/go/net/http/httputil/dump.go +++ b/libgo/go/net/http/httputil/dump.go @@ -18,11 +18,16 @@ import ( "time" ) -// One of the copies, say from b to r2, could be avoided by using a more -// elaborate trick where the other copy is made during Request/Response.Write. -// This would complicate things too much, given that these functions are for -// debugging only. +// drainBody reads all of b to memory and then returns two equivalent +// ReadClosers yielding the same bytes. +// +// It returns an error if the initial slurp of all bytes fails. It does not attempt +// to make the returned ReadClosers have identical error-matching behavior. func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) { + if b == http.NoBody { + // No copying needed. Preserve the magic sentinel meaning of NoBody. + return http.NoBody, http.NoBody, nil + } var buf bytes.Buffer if _, err = buf.ReadFrom(b); err != nil { return nil, b, err @@ -128,7 +133,7 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { // If we used a dummy body above, remove it now. // TODO: if the req.ContentLength is large, we allocate memory - // unnecessarily just to slice it off here. But this is just + // unnecessarily just to slice it off here. But this is just // a debug function, so this is acceptable for now. We could // discard the body earlier if this matters. if dummyBody { @@ -163,18 +168,10 @@ func valueOrDefault(value, def string) string { var reqWriteExcludeHeaderDump = map[string]bool{ "Host": true, // not in Header map anyway - "Content-Length": true, "Transfer-Encoding": true, "Trailer": true, } -// dumpAsReceived writes req to w in the form as it was received, or -// at least as accurately as possible from the information retained in -// the request. -func dumpAsReceived(req *http.Request, w io.Writer) error { - return nil -} - // DumpRequest returns the given request in its HTTP/1.x wire // representation. It should only be used by servers to debug client // requests. The returned representation is an approximation only; @@ -191,7 +188,8 @@ func dumpAsReceived(req *http.Request, w io.Writer) error { // // The documentation for http.Request.Write details which fields // of req are included in the dump. -func DumpRequest(req *http.Request, body bool) (dump []byte, err error) { +func DumpRequest(req *http.Request, body bool) ([]byte, error) { + var err error save := req.Body if !body || req.Body == nil { req.Body = nil @@ -239,7 +237,7 @@ func DumpRequest(req *http.Request, body bool) (dump []byte, err error) { err = req.Header.WriteSubset(&b, reqWriteExcludeHeaderDump) if err != nil { - return + return nil, err } io.WriteString(&b, "\r\n") @@ -258,35 +256,42 @@ func DumpRequest(req *http.Request, body bool) (dump []byte, err error) { req.Body = save if err != nil { - return + return nil, err } - dump = b.Bytes() - return + return b.Bytes(), nil } -// errNoBody is a sentinel error value used by failureToReadBody so we can detect -// that the lack of body was intentional. +// errNoBody is a sentinel error value used by failureToReadBody so we +// can detect that the lack of body was intentional. var errNoBody = errors.New("sentinel error value") // failureToReadBody is a io.ReadCloser that just returns errNoBody on -// Read. It's swapped in when we don't actually want to consume the -// body, but need a non-nil one, and want to distinguish the error -// from reading the dummy body. +// Read. It's swapped in when we don't actually want to consume +// the body, but need a non-nil one, and want to distinguish the +// error from reading the dummy body. type failureToReadBody struct{} func (failureToReadBody) Read([]byte) (int, error) { return 0, errNoBody } func (failureToReadBody) Close() error { return nil } +// emptyBody is an instance of empty reader. var emptyBody = ioutil.NopCloser(strings.NewReader("")) // DumpResponse is like DumpRequest but dumps a response. -func DumpResponse(resp *http.Response, body bool) (dump []byte, err error) { +func DumpResponse(resp *http.Response, body bool) ([]byte, error) { var b bytes.Buffer + var err error save := resp.Body savecl := resp.ContentLength if !body { - resp.Body = failureToReadBody{} + // For content length of zero. Make sure the body is an empty + // reader, instead of returning error through failureToReadBody{}. + if resp.ContentLength == 0 { + resp.Body = emptyBody + } else { + resp.Body = failureToReadBody{} + } } else if resp.Body == nil { resp.Body = emptyBody } else { |