package server import ( "errors" "fmt" "net/http" "time" "go.uber.org/fx" ) const ( readTimeout = 10 * time.Second maxHeaderBytes = 1 << 20 // 1 MiB // requestTimeout (routes.go) is the single per-request // processing budget, enforced by chi's middleware.Timeout. // writeTimeout must exceed that budget so a handler can write // its 503 when the chi timeout fires; if it were shorter the // server would abort the write first and the chi budget would // be unreachable dead configuration. writeTimeout = requestTimeout + 5*time.Second ) // newHTTPServer constructs the http.Server. It performs no I/O // and does not start listening. func (s *Server) newHTTPServer() *http.Server { listenAddr := fmt.Sprintf(":%d", s.params.Config.Port) return &http.Server{ Addr: listenAddr, Handler: s, MaxHeaderBytes: maxHeaderBytes, ReadTimeout: readTimeout, WriteTimeout: writeTimeout, } } // listenAndServe runs the listener until the server is shut // down. A genuine listen failure (not the expected // ErrServerClosed from a clean shutdown) requests process // shutdown through fx with a non-zero exit code, so the failure // is visible to any supervisor. func (s *Server) listenAndServe() { s.log.Info("http begin listen", "listenaddr", s.httpServer.Addr, "version", s.params.Globals.Version, "buildarch", s.params.Globals.Buildarch, ) err := s.httpServer.ListenAndServe() if err == nil || errors.Is(err, http.ErrServerClosed) { return } s.log.Error("listen error", "error", err) shutdownErr := s.shutdowner.Shutdown(fx.ExitCode(1)) if shutdownErr != nil { s.log.Error("request shutdown failed", "error", shutdownErr) } }