aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/http
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2011-09-28 09:27:11 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-09-28 09:27:11 -0700
commit58a5f1e84f4e6679ffb70a0cc81d786e078b4ef7 (patch)
tree890c940ab7da95de9f72f86478eb3e7754dee9ac /src/pkg/http
parent32d1e46058ce94d1959812ede5a51142bb36263f (diff)
downloadgo-58a5f1e84f4e6679ffb70a0cc81d786e078b4ef7.tar.xz
http: don't send a 400 Bad Request after a client shutdown
Fixes #2312 R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/5143049
Diffstat (limited to 'src/pkg/http')
-rw-r--r--src/pkg/http/serve_test.go32
-rw-r--r--src/pkg/http/server.go2
2 files changed, 34 insertions, 0 deletions
diff --git a/src/pkg/http/serve_test.go b/src/pkg/http/serve_test.go
index 1bb748c3c9..dfe4278ca3 100644
--- a/src/pkg/http/serve_test.go
+++ b/src/pkg/http/serve_test.go
@@ -987,6 +987,38 @@ func TestRequestBodyLimit(t *testing.T) {
}
}
+// TestClientWriteShutdown tests that if the client shuts down the write
+// side of their TCP connection, the server doesn't send a 400 Bad Request.
+func TestClientWriteShutdown(t *testing.T) {
+ ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+ defer ts.Close()
+ conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+ if err != nil {
+ t.Fatalf("Dial: %v", err)
+ }
+ err = conn.(*net.TCPConn).CloseWrite()
+ if err != nil {
+ t.Fatalf("Dial: %v", err)
+ }
+ donec := make(chan bool)
+ go func() {
+ defer close(donec)
+ bs, err := ioutil.ReadAll(conn)
+ if err != nil {
+ t.Fatalf("ReadAll: %v", err)
+ }
+ got := string(bs)
+ if got != "" {
+ t.Errorf("read %q from server; want nothing", got)
+ }
+ }()
+ select {
+ case <-donec:
+ case <-time.After(10e9):
+ t.Fatalf("timeout")
+ }
+}
+
type errorListener struct {
errs []os.Error
}
diff --git a/src/pkg/http/server.go b/src/pkg/http/server.go
index 6be3611f0f..8326ff8be1 100644
--- a/src/pkg/http/server.go
+++ b/src/pkg/http/server.go
@@ -572,6 +572,8 @@ func (c *conn) serve() {
// while they're still writing their
// request. Undefined behavior.
msg = "413 Request Entity Too Large"
+ } else if err == io.ErrUnexpectedEOF {
+ break // Don't reply
} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
break // Don't reply
}