The template's files at a77fd30, without its history or LICENSE, after script/rename simplexcalc. Model: opus-5-5
56 lines
1.9 KiB
Go
56 lines
1.9 KiB
Go
package server
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// HTTP server hardening limits. These are the connection-level bounds;
|
|
// the per-request deadline is middleware.Timeout, driven by
|
|
// REQUEST_TIMEOUT.
|
|
const (
|
|
// readHeaderTimeout is the slowloris bound: request headers must
|
|
// arrive within it, and it starts on connection accept.
|
|
readHeaderTimeout = 5 * time.Second
|
|
|
|
// readTimeout covers headers plus body. Bodies are capped by
|
|
// MAX_REQUEST_BODY, which transfers well inside this even on a
|
|
// slow mobile link.
|
|
readTimeout = 30 * time.Second
|
|
|
|
// writeTimeout must exceed the per-request timeout: it starts when
|
|
// the headers are read, so it spans handler execution, and a
|
|
// smaller value would cut the connection instead of letting the
|
|
// request context deadline end the request with a status. The
|
|
// margin is added to whatever REQUEST_TIMEOUT is configured to.
|
|
writeTimeoutMargin = 15 * time.Second
|
|
|
|
// idleTimeout bounds how long an idle keep-alive connection is
|
|
// held; browsers reconnect transparently.
|
|
idleTimeout = 120 * time.Second
|
|
|
|
maxHeaderBytes = 1 << 20
|
|
)
|
|
|
|
// newHTTPServer builds the http.Server.
|
|
//
|
|
// ErrorLog is set on purpose: net/http internals (TLS handshake
|
|
// errors, request parse errors, panics net/http itself recovers) write
|
|
// through it, and unset they would emit plain text on stderr via the
|
|
// default log package — a few lines of unstructured output in the
|
|
// middle of a JSON log stream, which is exactly the kind of thing a log
|
|
// pipeline drops on the floor.
|
|
func (s *Server) newHTTPServer(listenAddr string) *http.Server {
|
|
return &http.Server{
|
|
Addr: listenAddr,
|
|
ReadHeaderTimeout: readHeaderTimeout,
|
|
ReadTimeout: readTimeout,
|
|
WriteTimeout: s.params.Config.RequestTimeout + writeTimeoutMargin,
|
|
IdleTimeout: idleTimeout,
|
|
MaxHeaderBytes: maxHeaderBytes,
|
|
Handler: s,
|
|
ErrorLog: slog.NewLogLogger(s.log.Handler(), slog.LevelError),
|
|
}
|
|
}
|