-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.go
More file actions
108 lines (95 loc) · 2.62 KB
/
server.go
File metadata and controls
108 lines (95 loc) · 2.62 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package easyhttps
import (
"context"
"crypto/tls"
"fmt"
"log"
"net/http"
"os"
"golang.org/x/crypto/acme/autocert"
)
// Server represents the things a server can do
type Server interface {
ListenAndServe() error
}
// WrapHTTPS wraps an http server in HTTPS TLS
func WrapHTTPS(s *http.Server, tlsAddr, cacheDir, host string) Server {
httpsSrv := &HTTPSServer{
TLSDataDir: cacheDir,
AllowedHost: host,
srv: &http.Server{
Handler: s.Handler,
Addr: tlsAddr,
WriteTimeout: s.WriteTimeout,
ReadTimeout: s.ReadTimeout,
IdleTimeout: s.IdleTimeout,
},
}
m := httpsSrv.InitAutocert()
httpSrv := &HTTPServer{
srv: &http.Server{
Handler: httpsSrv.makeHTTPToHTTPSRedirectMux(m),
Addr: s.Addr,
WriteTimeout: s.WriteTimeout,
ReadTimeout: s.ReadTimeout,
IdleTimeout: s.IdleTimeout,
},
}
return &RedirectHTTPSServer{
HTTPServer: httpSrv,
HTTPSServer: httpsSrv,
}
}
// RedirectHTTPSServer redirects traffic going to the httpServer to the https server
type RedirectHTTPSServer struct {
*HTTPSServer
*HTTPServer
}
// ListenAndServe listen and serves on the calling server
func (s *RedirectHTTPSServer) ListenAndServe() error {
errChan := make(chan error)
go func() { errChan <- s.HTTPSServer.ListenAndServe() }()
go func() { errChan <- s.HTTPServer.ListenAndServe() }()
return <-errChan
}
// HTTPSServer represents everything needed to run an https server
type HTTPSServer struct {
TLSDataDir string
AllowedHost string
srv *http.Server
}
// InitAutocert configures the http server and returns the autocert manager
func (s *HTTPSServer) InitAutocert() *autocert.Manager {
hostPolicy := func(ctx context.Context, host string) error {
if host == s.AllowedHost {
return nil
}
return fmt.Errorf("acme/autocert: only %s host is allowed", s.AllowedHost)
}
if err := os.MkdirAll(s.TLSDataDir, 0700); err != nil {
log.Printf("warning: autocert.NewListener not using a cache: %v", err)
return nil
}
m := &autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: hostPolicy,
Cache: autocert.DirCache(s.TLSDataDir),
}
m.GetCertificate(&tls.ClientHelloInfo{})
s.srv.TLSConfig = &tls.Config{
GetCertificate: m.GetCertificate,
}
return m
}
// ListenAndServe listens and serves on the port of the calling server
func (s *HTTPSServer) ListenAndServe() error {
return s.srv.ListenAndServeTLS("", "")
}
// HTTPServer represents everything needed to run an http server
type HTTPServer struct {
srv *http.Server
}
// ListenAndServe listens and serves on the calling server's port
func (s *HTTPServer) ListenAndServe() error {
return s.srv.ListenAndServe()
}