|
|
|
@ -1168,29 +1168,7 @@ func (a *Agent) listenHTTP() ([]*HTTPServer, error) {
|
|
|
|
|
connLimitFn := a.httpConnLimiter.HTTPConnStateFunc()
|
|
|
|
|
|
|
|
|
|
if proto == "https" {
|
|
|
|
|
// Enforce TLS handshake timeout
|
|
|
|
|
httpServer.ConnState = func(conn net.Conn, state http.ConnState) {
|
|
|
|
|
switch state {
|
|
|
|
|
case http.StateNew:
|
|
|
|
|
// Set deadline to prevent slow send before TLS handshake or first
|
|
|
|
|
// byte of request.
|
|
|
|
|
conn.SetReadDeadline(time.Now().Add(a.config.HTTPSHandshakeTimeout))
|
|
|
|
|
case http.StateActive:
|
|
|
|
|
// Clear read deadline. We should maybe set read timeouts more
|
|
|
|
|
// generally but that's a bigger task as some HTTP endpoints may
|
|
|
|
|
// stream large requests and responses (e.g. snapshot) so we can't
|
|
|
|
|
// set sensible blanket timeouts here.
|
|
|
|
|
conn.SetReadDeadline(time.Time{})
|
|
|
|
|
}
|
|
|
|
|
// Pass through to conn limit. This is OK because we didn't change
|
|
|
|
|
// state (i.e. Close conn).
|
|
|
|
|
connLimitFn(conn, state)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This will enable upgrading connections to HTTP/2 as
|
|
|
|
|
// part of TLS negotiation.
|
|
|
|
|
err = http2.ConfigureServer(httpServer, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if err := setupHTTPS(httpServer, connLimitFn, a.config.HTTPSHandshakeTimeout); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -1218,6 +1196,33 @@ func (a *Agent) listenHTTP() ([]*HTTPServer, error) {
|
|
|
|
|
return servers, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// setupHTTPS adds HTTP/2 support, ConnState, and a connection handshake timeout
|
|
|
|
|
// to the http.Server.
|
|
|
|
|
func setupHTTPS(server *http.Server, connState func(net.Conn, http.ConnState), timeout time.Duration) error {
|
|
|
|
|
// Enforce TLS handshake timeout
|
|
|
|
|
server.ConnState = func(conn net.Conn, state http.ConnState) {
|
|
|
|
|
switch state {
|
|
|
|
|
case http.StateNew:
|
|
|
|
|
// Set deadline to prevent slow send before TLS handshake or first
|
|
|
|
|
// byte of request.
|
|
|
|
|
conn.SetReadDeadline(time.Now().Add(timeout))
|
|
|
|
|
case http.StateActive:
|
|
|
|
|
// Clear read deadline. We should maybe set read timeouts more
|
|
|
|
|
// generally but that's a bigger task as some HTTP endpoints may
|
|
|
|
|
// stream large requests and responses (e.g. snapshot) so we can't
|
|
|
|
|
// set sensible blanket timeouts here.
|
|
|
|
|
conn.SetReadDeadline(time.Time{})
|
|
|
|
|
}
|
|
|
|
|
// Pass through to conn limit. This is OK because we didn't change
|
|
|
|
|
// state (i.e. Close conn).
|
|
|
|
|
connState(conn, state)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This will enable upgrading connections to HTTP/2 as
|
|
|
|
|
// part of TLS negotiation.
|
|
|
|
|
return http2.ConfigureServer(server, nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
|
|
|
|
|
// connections. It's used so dead TCP connections eventually go away.
|
|
|
|
|
type tcpKeepAliveListener struct {
|
|
|
|
|