Skip to content

Commit

Permalink
Optimize server connection close logic (#1310)
Browse files Browse the repository at this point in the history
* server.go Make code more clear

Inline isHTTP11 var.
Use direct Header.SetConnectionClose() and Header.ConnectionClose()

* server.go Use direct SetConnectionClose()

The SetCanonical(strConnection, strClose) call internally will anyway call SetConnectionClose().
The "Connection: close" will be printed in the ResponseHeader.AppendBytes()

* server.go Simplify connectionClose evaluation

The conn limit check merged into connectionClose evaluation.
This improves performance for most cases:
1. If the connectionClose already true then the conn limit check won't be performed.
2. The SetConnectionClose() was duplicated
3. First check conn limit and only then check for resp.connClose because most users don't close conns manually.
4. We may optimize more: If the resp.connClose = true then SetConnectionClose() not needed but as mentioned above this is a rare case.
  • Loading branch information
stokito committed Jun 5, 2022
1 parent 66bc61e commit de18824
Showing 1 changed file with 8 additions and 10 deletions.
18 changes: 8 additions & 10 deletions server.go
Expand Up @@ -2127,7 +2127,6 @@ func (s *Server) serveConn(c net.Conn) (err error) {
hijackNoResponse bool

connectionClose bool
isHTTP11 bool

continueReadingRequest bool = true
)
Expand Down Expand Up @@ -2323,8 +2322,8 @@ func (s *Server) serveConn(c net.Conn) (err error) {
}
}

// store req.ConnectionClose so even if it was changed inside of handler
connectionClose = s.DisableKeepalive || ctx.Request.Header.ConnectionClose()
isHTTP11 = ctx.Request.Header.IsHTTP11()

if serverName != nil {
ctx.Response.Header.SetServerBytes(serverName)
Expand Down Expand Up @@ -2354,10 +2353,6 @@ func (s *Server) serveConn(c net.Conn) (err error) {
hijackNoResponse = ctx.hijackNoResponse && hijackHandler != nil
ctx.hijackNoResponse = false

if s.MaxRequestsPerConn > 0 && connRequestNum >= uint64(s.MaxRequestsPerConn) {
ctx.SetConnectionClose()
}

if writeTimeout > 0 {
if err := c.SetWriteDeadline(time.Now().Add(writeTimeout)); err != nil {
panic(fmt.Sprintf("BUG: error in SetWriteDeadline(%v): %v", writeTimeout, err))
Expand All @@ -2371,11 +2366,14 @@ func (s *Server) serveConn(c net.Conn) (err error) {
previousWriteTimeout = 0
}

connectionClose = connectionClose || ctx.Response.ConnectionClose() || (s.CloseOnShutdown && atomic.LoadInt32(&s.stop) == 1)
connectionClose = connectionClose ||
(s.MaxRequestsPerConn > 0 && connRequestNum >= uint64(s.MaxRequestsPerConn)) ||
ctx.Response.Header.ConnectionClose() ||
(s.CloseOnShutdown && atomic.LoadInt32(&s.stop) == 1)
if connectionClose {
ctx.Response.Header.SetCanonical(strConnection, strClose)
} else if !isHTTP11 {
// Set 'Connection: keep-alive' response header for non-HTTP/1.1 request.
ctx.Response.Header.SetConnectionClose()
} else if !ctx.Request.Header.IsHTTP11() {
// Set 'Connection: keep-alive' response header for HTTP/1.0 request.
// There is no need in setting this header for http/1.1, since in http/1.1
// connections are keep-alive by default.
ctx.Response.Header.SetCanonical(strConnection, strKeepAlive)
Expand Down

0 comments on commit de18824

Please sign in to comment.