aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/http/server.go')
-rw-r--r--src/net/http/server.go24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 9124903b89..25fab288f2 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -324,7 +324,7 @@ func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
}
}
- c.setState(rwc, StateHijacked)
+ c.setState(rwc, StateHijacked, runHooks)
return
}
@@ -1739,7 +1739,12 @@ func validNextProto(proto string) bool {
return true
}
-func (c *conn) setState(nc net.Conn, state ConnState) {
+const (
+ runHooks = true
+ skipHooks = false
+)
+
+func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) {
srv := c.server
switch state {
case StateNew:
@@ -1752,6 +1757,9 @@ func (c *conn) setState(nc net.Conn, state ConnState) {
}
packedState := uint64(time.Now().Unix()<<8) | uint64(state)
atomic.StoreUint64(&c.curState.atomic, packedState)
+ if !runHook {
+ return
+ }
if hook := srv.ConnState; hook != nil {
hook(nc, state)
}
@@ -1805,7 +1813,7 @@ func (c *conn) serve(ctx context.Context) {
}
if !c.hijacked() {
c.close()
- c.setState(c.rwc, StateClosed)
+ c.setState(c.rwc, StateClosed, runHooks)
}
}()
@@ -1833,6 +1841,10 @@ func (c *conn) serve(ctx context.Context) {
if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) {
if fn := c.server.TLSNextProto[proto]; fn != nil {
h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}}
+ // Mark freshly created HTTP/2 as active and prevent any server state hooks
+ // from being run on these connections. This prevents closeIdleConns from
+ // closing such connections. See issue https://golang.org/issue/39776.
+ c.setState(c.rwc, StateActive, skipHooks)
fn(c.server, tlsConn, h)
}
return
@@ -1853,7 +1865,7 @@ func (c *conn) serve(ctx context.Context) {
w, err := c.readRequest(ctx)
if c.r.remain != c.server.initialReadLimitSize() {
// If we read any bytes off the wire, we're active.
- c.setState(c.rwc, StateActive)
+ c.setState(c.rwc, StateActive, runHooks)
}
if err != nil {
const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
@@ -1936,7 +1948,7 @@ func (c *conn) serve(ctx context.Context) {
}
return
}
- c.setState(c.rwc, StateIdle)
+ c.setState(c.rwc, StateIdle, runHooks)
c.curReq.Store((*response)(nil))
if !w.conn.server.doKeepAlives() {
@@ -2971,7 +2983,7 @@ func (srv *Server) Serve(l net.Listener) error {
}
tempDelay = 0
c := srv.newConn(rw)
- c.setState(c.rwc, StateNew) // before Serve can return
+ c.setState(c.rwc, StateNew, runHooks) // before Serve can return
go c.serve(connCtx)
}
}