-
Notifications
You must be signed in to change notification settings - Fork 5
/
server.go
103 lines (79 loc) · 1.89 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package rpcserver
import (
"context"
"crypto/rand"
"crypto/tls"
"net"
"net/http"
"runtime"
"golang.org/x/net/http2"
"golang.org/x/sync/errgroup"
"github.com/0xef53/kvmrun/pkg/rpc/common"
)
func serve(ctx context.Context, h http.Handler, addr string, tlsConfig *tls.Config) error {
srv := http.Server{Handler: h}
var listener net.Listener
if tlsConfig == nil {
l, err := net.Listen("tcp", addr)
if err != nil {
return err
}
listener = l
} else {
http2.ConfigureServer(&srv, &http2.Server{})
l, err := tls.Listen("tcp", addr, tlsConfig)
if err != nil {
return err
}
listener = l
}
defer listener.Close()
idleConnsClosed := make(chan struct{})
go func() {
<-ctx.Done()
srv.Shutdown(context.Background())
close(idleConnsClosed)
}()
if err := srv.Serve(listener); err != http.ErrServerClosed {
// Error starting or closing listener
return err
}
<-idleConnsClosed
return nil
}
func ServeTls(ctx context.Context, h http.Handler, addrs []string, crt, key string) error {
tlsConfig, err := rpccommon.TlsConfig(crt, key)
if err != nil {
return err
}
tlsConfig.Rand = rand.Reader
group1, ctx1 := errgroup.WithContext(ctx)
for _, addr := range addrs {
_addr := addr
group1.Go(func() error { return serve(ctx1, h, _addr, tlsConfig) })
}
return group1.Wait()
}
func ServeUnixSocket(ctx context.Context, h http.Handler, sockpath string) error {
if sockpath[0] == '@' && runtime.GOOS == "linux" {
sockpath = sockpath + string(0)
}
srv := http.Server{Handler: h}
listener, err := net.Listen("unix", sockpath)
if err != nil {
return err
}
defer listener.Close()
idleConnsClosed := make(chan struct{})
go func() {
<-ctx.Done()
srv.Shutdown(context.Background())
close(idleConnsClosed)
}()
if err := srv.Serve(listener); err != http.ErrServerClosed {
// Error starting or closing listener
return err
}
<-idleConnsClosed
return nil
}