summaryrefslogtreecommitdiff
path: root/src/pkg/http
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/http')
-rw-r--r--src/pkg/http/pprof/pprof.go14
-rw-r--r--src/pkg/http/transfer.go20
2 files changed, 32 insertions, 2 deletions
diff --git a/src/pkg/http/pprof/pprof.go b/src/pkg/http/pprof/pprof.go
index bc79e2183..917c7f877 100644
--- a/src/pkg/http/pprof/pprof.go
+++ b/src/pkg/http/pprof/pprof.go
@@ -26,6 +26,7 @@ package pprof
import (
"bufio"
+ "bytes"
"fmt"
"http"
"os"
@@ -88,10 +89,14 @@ func Profile(w http.ResponseWriter, r *http.Request) {
func Symbol(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ // We have to read the whole POST body before
+ // writing any output. Buffer the output here.
+ var buf bytes.Buffer
+
// We don't know how many symbols we have, but we
// do have symbol information. Pprof only cares whether
// this number is 0 (no symbols available) or > 0.
- fmt.Fprintf(w, "num_symbols: 1\n")
+ fmt.Fprintf(&buf, "num_symbols: 1\n")
var b *bufio.Reader
if r.Method == "POST" {
@@ -109,14 +114,19 @@ func Symbol(w http.ResponseWriter, r *http.Request) {
if pc != 0 {
f := runtime.FuncForPC(uintptr(pc))
if f != nil {
- fmt.Fprintf(w, "%#x %s\n", pc, f.Name())
+ fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name())
}
}
// Wait until here to check for err; the last
// symbol will have an err because it doesn't end in +.
if err != nil {
+ if err != os.EOF {
+ fmt.Fprintf(&buf, "reading request: %v\n", err)
+ }
break
}
}
+
+ w.Write(buf.Bytes())
}
diff --git a/src/pkg/http/transfer.go b/src/pkg/http/transfer.go
index 98c32bab6..0fa8bed43 100644
--- a/src/pkg/http/transfer.go
+++ b/src/pkg/http/transfer.go
@@ -439,9 +439,29 @@ type body struct {
hdr interface{} // non-nil (Response or Request) value means read trailer
r *bufio.Reader // underlying wire-format reader for the trailer
closing bool // is the connection to be closed after reading body?
+ closed bool
+}
+
+// ErrBodyReadAfterClose is returned when reading a Request Body after
+// the body has been closed. This typically happens when the body is
+// read after an HTTP Handler calls WriteHeader or Write on its
+// ResponseWriter.
+var ErrBodyReadAfterClose = os.NewError("http: invalid Read on closed request Body")
+
+func (b *body) Read(p []byte) (n int, err os.Error) {
+ if b.closed {
+ return 0, ErrBodyReadAfterClose
+ }
+ return b.Reader.Read(p)
}
func (b *body) Close() os.Error {
+ if b.closed {
+ return nil
+ }
+ defer func() {
+ b.closed = true
+ }()
if b.hdr == nil && b.closing {
// no trailer and closing the connection next.
// no point in reading to EOF.