-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.go
More file actions
90 lines (81 loc) · 3.24 KB
/
server.go
File metadata and controls
90 lines (81 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package rmhttp
import (
"context"
"fmt"
"net/http"
"time"
)
// ------------------------------------------------------------------------------------------------
// SERVER
// ------------------------------------------------------------------------------------------------
// A Server wraps the standard library net/http.Server. It provide default lifecycle management
// and debugger logging on top of the expected http.Server behaviour.
type Server struct {
Server http.Server
Router http.Handler
Port int
Host string
writeTimeoutPadding time.Duration
}
// NewServer creates, initialises and returns a pointer to a Server.
func NewServer(
config ServerConfig,
router http.Handler,
) *Server {
srv := Server{
Server: http.Server{
Handler: router,
ReadTimeout: time.Duration(config.TCPReadTimeout) * time.Second,
ReadHeaderTimeout: time.Duration(config.TCPReadHeaderTimeout) * time.Second,
WriteTimeout: time.Duration(config.TCPWriteTimeout) * time.Second,
IdleTimeout: time.Duration(config.TCPIdleTimeout) * time.Second,
DisableGeneralOptionsHandler: config.DisableGeneralOptionsHandler,
},
Router: router,
Host: config.Host,
Port: config.Port,
writeTimeoutPadding: time.Duration(config.TCPWriteTimeoutPadding) * time.Second,
}
srv.Server.Addr = fmt.Sprintf("%s:%d", config.Host, config.Port)
return &srv
}
// maybeUpdateTimeout updates the http.Server read and write timeouts, if the passed duration
// is longer than the current values. We do this to ensure that the TCP connection does not
// timeout before the longest request timeout.
//
// See https://adam-p.ca/blog/2022/01/golang-http-server-timeouts/
func (srv *Server) maybeUpdateTimeout(timeout time.Duration) {
readTimeout := timeout + srv.Server.ReadHeaderTimeout + srv.writeTimeoutPadding
writeTimeout := timeout + srv.writeTimeoutPadding
if readTimeout > srv.Server.ReadTimeout && writeTimeout > srv.Server.WriteTimeout {
srv.Server.ReadTimeout = readTimeout
srv.Server.WriteTimeout = writeTimeout
}
}
// bestRouter returns the faster router for the Server, given the current configuration. If the
// router has custom error handlers, it returns the Router itself; otherwise, it returns the
// Router's underlying Mux.
func (srv *Server) setBestRouter() {
if r, ok := srv.Router.(*Router); ok {
if !r.HasErrorHandlers() {
srv.Router = r.Mux
}
}
}
// ListenAndServe directly proxies the http.Server.ListenAndServe method. It starts the server
// without TLS support on the configured address and port.
func (srv *Server) ListenAndServe() error {
srv.setBestRouter()
return srv.Server.ListenAndServe()
}
// ListenAndServeTLS directly proxies the http.Server.ListenAndServeTLS method. It starts the
// server with TLS support on the configured address and port.
func (srv *Server) ListenAndServeTLS(cert string, key string) error {
srv.setBestRouter()
return srv.Server.ListenAndServeTLS(cert, key)
}
// Shutdown directly proxies the net/http.Server.Shutdown method. It will stop the Server, if
// running.
func (srv *Server) Shutdown(ctx context.Context) error {
return srv.Server.Shutdown(ctx)
}