/
server.go
83 lines (73 loc) · 1.7 KB
/
server.go
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
package http
import (
"context"
"net/http"
"time"
"github.com/caddyserver/certmagic"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"github.com/zitryss/aye-and-nay/domain/domain"
"github.com/zitryss/aye-and-nay/pkg/errors"
)
var (
ErrServerClosed = http.ErrServerClosed
)
func NewServer(
conf ServerConfig,
middle func(http.Handler) http.Handler,
serv domain.Servicer,
serverWait chan<- error,
) (*Server, error) {
contr := newController(conf.Controller, serv)
router := newRouter(contr)
handler := middle(router)
srv, err := newServer(conf, handler)
if err != nil {
return nil, errors.Wrap(err)
}
return &Server{conf, srv, serverWait}, nil
}
func newServer(conf ServerConfig, handler http.Handler) (*http.Server, error) {
srv := &http.Server{
Addr: conf.Host + ":" + conf.Port,
Handler: handler,
ReadTimeout: conf.ReadTimeout,
WriteTimeout: conf.WriteTimeout + 1*time.Second,
IdleTimeout: conf.IdleTimeout,
}
if conf.Domain != "" {
tlsConfig, err := certmagic.TLS([]string{conf.Domain})
if err != nil {
return nil, errors.Wrap(err)
}
srv.TLSConfig = tlsConfig
}
if conf.H2C {
srv.Handler = h2c.NewHandler(srv.Handler, &http2.Server{})
}
return srv, nil
}
type Server struct {
conf ServerConfig
srv *http.Server
serverWait chan<- error
}
func (s *Server) Monitor(ctx context.Context) {
go func() {
<-ctx.Done()
s.shutdown()
}()
}
func (s *Server) Start() error {
err := s.srv.ListenAndServe()
if err != nil {
return errors.Wrap(err)
}
return nil
}
func (s *Server) shutdown() {
ctx, cancel := context.WithTimeout(context.Background(), s.conf.ShutdownTimeout)
defer cancel()
err := s.srv.Shutdown(ctx)
s.serverWait <- err
}