Skip to content

Commit abbd502

Browse files
committed
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 <[email protected]>
1 parent 61f1a38 commit abbd502

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

src/net/http/serve_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,6 +2252,51 @@ func testHandlerPanic(t *testing.T, withHijack, h2 bool, panicValue interface{})
22522252
}
22532253
}
22542254

2255+
type terrorWriter struct{ t *testing.T }
2256+
2257+
func (w terrorWriter) Write(p []byte) (int, error) {
2258+
w.t.Errorf("%s", p)
2259+
return len(p), nil
2260+
}
2261+
2262+
// Issue 16456: allow writing 0 bytes on hijacked conn to test hijack
2263+
// without any log spam.
2264+
func TestServerWriteHijackZeroBytes(t *testing.T) {
2265+
defer afterTest(t)
2266+
done := make(chan struct{})
2267+
ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
2268+
defer close(done)
2269+
w.(Flusher).Flush()
2270+
conn, _, err := w.(Hijacker).Hijack()
2271+
if err != nil {
2272+
t.Errorf("Hijack: %v", err)
2273+
return
2274+
}
2275+
defer conn.Close()
2276+
_, err = w.Write(nil)
2277+
if err != ErrHijacked {
2278+
t.Errorf("Write error = %v; want ErrHijacked", err)
2279+
}
2280+
}))
2281+
ts.Config.ErrorLog = log.New(terrorWriter{t}, "Unexpected write: ", 0)
2282+
ts.Start()
2283+
defer ts.Close()
2284+
2285+
tr := &Transport{}
2286+
defer tr.CloseIdleConnections()
2287+
c := &Client{Transport: tr}
2288+
res, err := c.Get(ts.URL)
2289+
if err != nil {
2290+
t.Fatal(err)
2291+
}
2292+
res.Body.Close()
2293+
select {
2294+
case <-done:
2295+
case <-time.After(5 * time.Second):
2296+
t.Fatal("timeout")
2297+
}
2298+
}
2299+
22552300
func TestServerNoDate_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Date") }
22562301
func TestServerNoDate_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Date") }
22572302
func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") }

src/net/http/server.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,9 @@ func (w *response) WriteString(data string) (n int, err error) {
13181318
// either dataB or dataS is non-zero.
13191319
func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
13201320
if w.conn.hijacked() {
1321-
w.conn.server.logf("http: response.Write on hijacked connection")
1321+
if lenData > 0 {
1322+
w.conn.server.logf("http: response.Write on hijacked connection")
1323+
}
13221324
return 0, ErrHijacked
13231325
}
13241326
if !w.wroteHeader {

0 commit comments

Comments
 (0)