web / server limits
A default Go http.Server has no timeouts. A client can open a
connection, stream request header bytes slowly, and hold the connection
indefinitely.
I set limits on every server that parses HTTP requests:
var p http.Protocols
p.SetHTTP1(true)
srv := &http.Server{
Handler: h,
ReadHeaderTimeout: 10 * time.Second,
MaxHeaderBytes: 64 << 10,
Protocols: &p,
}
Read header timeout
ReadHeaderTimeout limits the time a client has to send the complete
request header. When the timeout expires, the server closes the
connection.
ReadTimeout covers the request body as well, which breaks slow file
uploads. Request headers are small, and 10 seconds is generous for
legitimate clients.
Max header bytes
MaxHeaderBytes limits the request header size. The default is 1 MiB.
Setting it to 64 KiB protects memory while allowing common cookies.
Headers above this limit receive 431 Request Header Fields Too Large.
Protocols
The server sits behind a gateway and speaks plain HTTP over a private
network without TLS. I disable HTTP/2 over plain text with Protocols
and allow HTTP/1.1 only.
What I leave out
I set no IdleTimeout. The gateway maintains persistent connections to
the server between requests, and an idle timeout would close them.
See also web / health checks and go / web framework.