aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-10-11 09:23:39 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2016-10-13 21:55:38 +0000
commitabbd502d638262fa80e142ad18a89d6c75490672 (patch)
treee5f6fe64cd092ca65a58b44ed2653a59359a99a8 /src
parent61f1a38bcb52ad5e1753b43c405bb5b144b6966c (diff)
downloadgo-abbd502d638262fa80e142ad18a89d6c75490672.tar.xz
net/http: allow Handlers to test Hijacked conn without spamming error log
Make a zero-byte write to a hijacked connection not log anything, so handlers can test whether a connection is hacked by doing a Write(nil). Fixes #16456 Change-Id: Id56caf822c8592067bd8422672f0c1aec89e866c Reviewed-on: https://go-review.googlesource.com/30812 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/net/http/serve_test.go45
-rw-r--r--src/net/http/server.go4
2 files changed, 48 insertions, 1 deletions
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index 360d3a37b3..db72e70e35 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -2252,6 +2252,51 @@ func testHandlerPanic(t *testing.T, withHijack, h2 bool, panicValue interface{})
}
}
+type terrorWriter struct{ t *testing.T }
+
+func (w terrorWriter) Write(p []byte) (int, error) {
+ w.t.Errorf("%s", p)
+ return len(p), nil
+}
+
+// Issue 16456: allow writing 0 bytes on hijacked conn to test hijack
+// without any log spam.
+func TestServerWriteHijackZeroBytes(t *testing.T) {
+ defer afterTest(t)
+ done := make(chan struct{})
+ ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ defer close(done)
+ w.(Flusher).Flush()
+ conn, _, err := w.(Hijacker).Hijack()
+ if err != nil {
+ t.Errorf("Hijack: %v", err)
+ return
+ }
+ defer conn.Close()
+ _, err = w.Write(nil)
+ if err != ErrHijacked {
+ t.Errorf("Write error = %v; want ErrHijacked", err)
+ }
+ }))
+ ts.Config.ErrorLog = log.New(terrorWriter{t}, "Unexpected write: ", 0)
+ ts.Start()
+ defer ts.Close()
+
+ tr := &Transport{}
+ defer tr.CloseIdleConnections()
+ c := &Client{Transport: tr}
+ res, err := c.Get(ts.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ res.Body.Close()
+ select {
+ case <-done:
+ case <-time.After(5 * time.Second):
+ t.Fatal("timeout")
+ }
+}
+
func TestServerNoDate_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Date") }
func TestServerNoDate_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Date") }
func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") }
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 2677468aa3..d71006441e 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -1318,7 +1318,9 @@ func (w *response) WriteString(data string) (n int, err error) {
// either dataB or dataS is non-zero.
func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
if w.conn.hijacked() {
- w.conn.server.logf("http: response.Write on hijacked connection")
+ if lenData > 0 {
+ w.conn.server.logf("http: response.Write on hijacked connection")
+ }
return 0, ErrHijacked
}
if !w.wroteHeader {