Skip to content

net/http: document that conn.Hijack might have left-over read/write timeouts on net.Conn #8296

@encryptio

Description

@encryptio
What does 'go version' print?

Found with go-1.2rc3, present in go-1.3, and still present in the default branch as of
20272:90616fa61ef4.

What steps reproduce the problem?

Setting a ReadTimeout or WriteTimeout on an http.Server and then hijacking a http.conn
(passed as the ResponseWriter) from a request handler leaves the deadlines set on the
connection.

This causes unexpected read and write behavior, requiring an unnatural removal of the
deadlines after hijacking. I found this while implementing the server half of the HTML5
EventSource API, and it also affects any other hijack users (e.g. go.net's websocket
package does not have code to clear deadlines when it takes over a connection; I have
not tested it though.)

A simplified example of the issue is here (probably useful to derive a regression test
from): http://play.golang.org/p/bRyjSayMJN

Adding these two lines fixes the issue:

diff -r 90616fa61ef4 src/pkg/net/http/server.go
--- a/src/pkg/net/http/server.go    Fri Jun 27 18:30:09 2014 -0700
+++ b/src/pkg/net/http/server.go    Fri Jun 27 22:43:18 2014 -0700
@@ -128,18 +128,20 @@
 func (c *conn) hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
    c.mu.Lock()
    defer c.mu.Unlock()
    if c.hijackedv {
        return nil, nil, ErrHijacked
    }
    if c.closeNotifyc != nil {
        return nil, nil, errors.New("http: Hijack is incompatible with use of CloseNotifier")
    }
+   c.rwc.SetReadDeadline(time.Time{})
+   c.rwc.SetWriteDeadline(time.Time{})
    c.hijackedv = true
    rwc = c.rwc
    buf = c.buf
    c.rwc = nil
    c.buf = nil
    c.setState(rwc, StateHijacked)
    return
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions