-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
137 lines (118 loc) · 3.01 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package main
import (
"crypto/tls"
"fmt"
"github.com/gorilla/mux"
"github.com/justinas/alice"
"github.com/rs/cors"
"log"
"net"
"net/http"
"rsc.io/letsencrypt"
"strconv"
"time"
)
func Serve(url string, port int) error {
r := NewRouter()
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Authorization", "Content-Type", "Accept"},
})
chain := alice.New(c.Handler, AuthHandler).Then(r)
if port != 443 {
fmt.Println("Starting HTTP Server on port " + strconv.Itoa(port) + ".")
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(port), chain))
} else {
fmt.Println("Starting HTTPS Server on port 443 with a Let's Encrypt TLS certificate.")
var m letsencrypt.Manager
//if err := m.CacheFile("letsencrypt.cache"); err != nil {
if err := CacheFile(&m); err != nil {
fmt.Println(err)
log.Fatal(err)
}
l, err := net.Listen("tcp", ":http")
if err != nil {
fmt.Println(err)
return err
}
defer l.Close()
go http.Serve(l, http.HandlerFunc(redirectHTTP))
//return serveHTTPS(&m, &r)
log.Fatal(serveHTTPS(&m, chain))
}
return nil
}
//func serveHTTPS(m *letsencrypt.Manager, r *mux.Router) error {
func serveHTTPS(m *letsencrypt.Manager, chain http.Handler) error {
srv := &http.Server{
Addr: ":https",
//Handler: r,
Handler: chain,
TLSConfig: &tls.Config{
GetCertificate: m.GetCertificate,
},
}
return srv.ListenAndServeTLS("", "")
}
// RedirectHTTP is an HTTP handler (suitable for use with http.HandleFunc)
// that responds to all requests by redirecting to the same URL served over HTTPS.
// It should only be invoked for requests received over HTTP.
func redirectHTTP(w http.ResponseWriter, r *http.Request) {
if r.TLS != nil || r.Host == "" {
http.Error(w, "not found", 404)
}
u := r.URL
u.Host = r.Host
u.Scheme = "https"
http.Redirect(w, r, u.String(), 302)
}
func CacheFile(m *letsencrypt.Manager) error {
data, err := getLetsEncryptCache("schutt")
if err != nil {
return err
}
if len(data) > 0 {
if err := m.Unmarshal(data); err != nil {
return err
}
}
go func() {
for range m.Watch() {
//err := ioutil.WriteFile(name, []byte(m.Marshal()), 0600)
err := updateLetsEncryptCache(m.Marshal(), "schutt")
if err != nil {
log.Printf("writing letsencrypt cache: %v", err)
fmt.Println("data marshal error: " + err.Error())
}
}
}()
return nil
}
func NewRouter() *mux.Router {
router := mux.NewRouter().StrictSlash(true)
for _, route := range routes {
var handler http.Handler
handler = route.HandlerFunc
handler = Logger(handler, route.Name)
router.
Methods(route.Method).
Path(route.Pattern).
Name(route.Name).
Handler(handler)
}
return router
}
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s\t%s\t%s\t%s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}