Commit abbd502d authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

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/30812Reviewed-by: default avatarJoe Tsai <thebrokentoaster@gmail.com>
parent 61f1a38b
...@@ -2252,6 +2252,51 @@ func testHandlerPanic(t *testing.T, withHijack, h2 bool, panicValue interface{}) ...@@ -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_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Date") }
func TestServerNoDate_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Date") } func TestServerNoDate_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Date") }
func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") } func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") }
......
...@@ -1318,7 +1318,9 @@ func (w *response) WriteString(data string) (n int, err error) { ...@@ -1318,7 +1318,9 @@ func (w *response) WriteString(data string) (n int, err error) {
// either dataB or dataS is non-zero. // either dataB or dataS is non-zero.
func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) { func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
if w.conn.hijacked() { 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 return 0, ErrHijacked
} }
if !w.wroteHeader { if !w.wroteHeader {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment