]> Cypherpunks repositories - gostls13.git/commitdiff
http: add DumpRequest, DumpResponse, for debugging
authorPetar Maymounkov <petarm@gmail.com>
Fri, 19 Feb 2010 15:51:51 +0000 (07:51 -0800)
committerRuss Cox <rsc@golang.org>
Fri, 19 Feb 2010 15:51:51 +0000 (07:51 -0800)
R=rsc
CC=golang-dev
https://golang.org/cl/206050

src/pkg/http/Makefile
src/pkg/http/dump.go [new file with mode: 0644]

index 3966372a7fe95f4577a15bb9971c782e6e246721..d7149d70b11d2f76124848ee9c3bdd36a808cefd 100644 (file)
@@ -8,6 +8,7 @@ TARG=http
 GOFILES=\
        chunked.go\
        client.go\
+       dump.go\
        fs.go\
        lex.go\
        persist.go\
diff --git a/src/pkg/http/dump.go b/src/pkg/http/dump.go
new file mode 100644 (file)
index 0000000..73ac979
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+       "bytes"
+       "io"
+       "os"
+)
+
+
+// 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.
+func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err os.Error) {
+       var buf bytes.Buffer
+       if _, err = buf.ReadFrom(b); err != nil {
+               return nil, nil, err
+       }
+       if err = b.Close(); err != nil {
+               return nil, nil, err
+       }
+       return nopCloser{&buf}, nopCloser{bytes.NewBuffer(buf.Bytes())}, nil
+}
+
+// DumpRequest returns the wire representation of req,
+// optionally including the request body, for debugging.
+// DumpRequest is semantically a no-op, but in order to
+// dump the body, it reads the body data into memory and
+// changes req.Body to refer to the in-memory copy.
+func DumpRequest(req *Request, body bool) (dump []byte, err os.Error) {
+       var b bytes.Buffer
+       save := req.Body
+       if !body || req.Body == nil {
+               req.Body = nil
+       } else {
+               save, req.Body, err = drainBody(req.Body)
+               if err != nil {
+                       return
+               }
+       }
+       err = req.Write(&b)
+       req.Body = save
+       if err != nil {
+               return
+       }
+       dump = b.Bytes()
+       return
+}
+
+// DumpResponse is like DumpRequest but dumps a response.
+func DumpResponse(resp *Response, body bool) (dump []byte, err os.Error) {
+       var b bytes.Buffer
+       save := resp.Body
+       savecl := resp.ContentLength
+       if !body || resp.Body == nil {
+               resp.Body = nil
+               resp.ContentLength = 0
+       } else {
+               save, resp.Body, err = drainBody(resp.Body)
+               if err != nil {
+                       return
+               }
+       }
+       err = resp.Write(&b)
+       resp.Body = save
+       resp.ContentLength = savecl
+       if err != nil {
+               return
+       }
+       dump = b.Bytes()
+       return
+}