-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebserver.go
132 lines (110 loc) · 3.84 KB
/
webserver.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
package main
/*
SEE ALSO:
Not used here but seems to be an AMAZING go framework:
https://github.com/gofiber/fiber
Primarily from:
https://gowebexamples.com/websockets/
And:
https://github.com/denji/golang-tls (Excellent resource!)
Generate certs in ~/.ssh with the command:
openssl req -x509 -newkey rsa:4096 -keyout ~/.ssh/key.pem -out ~/.ssh/cert.pem -days 365 -nodes
Uses two env vars:
UseInsecureCerts: If set to "true", will set tlsConfig.InsecureSkipVerify to true.
CertsPath: Path to certs, including trailing slash.
If you have to run as sudo, use the command "sudo -E ./webserver" to ensure sudo has access to your env vars.
*/
import (
"log"
"net/http"
"os"
"crypto/tls"
"github.com/gorilla/websocket"
)
var send = make(chan string)
var upgrader = websocket.Upgrader{
ReadBufferSize: 4096,
WriteBufferSize: 4096,
}
func wsStart() {
if addr, err := getIPbyName("eth0"); err == nil {
log.Println("wsStart(): eth0 IP: " + addr)
} else {
log.Println("wsStart(): " + err.Error())
}
go func() {
// this is a standalone http server that only handles redirect to https
go http.ListenAndServe(":80", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusMovedPermanently)
}))
// beginning of https server
// for better efficiency and clarity, handle routes through a mux
mux := http.NewServeMux()
// Standard HTML page
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
// this page has a websocket client that connects via /ws.
mux.HandleFunc("/websockets", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "websockets.html")
})
// upgrade to websocket connection
mux.HandleFunc("/ws", wsComms)
tlsConfig := &tls.Config{ // See: https://github.com/denji/golang-tls
MinVersion: tls.VersionTLS12,
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
PreferServerCipherSuites: true,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
},
}
// set an env var to use self-signed certs
//if strings.ToLower(os.Getenv("UseInsecureCerts")) == "true" {
tlsConfig.InsecureSkipVerify = true
//}
srv := &http.Server{
Addr: ":443",
Handler: mux,
TLSConfig: tlsConfig,
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0), // enable HTTP/2
}
log.Println(os.Getenv("CertsPath"))
log.Println(os.Getenv("CertsPath"))
log.Fatal(srv.ListenAndServeTLS(os.Getenv("CertsPath")+"cert.pem", os.Getenv("CertsPath")+"key.pem"))
}()
}
// wsComms - Handles communications to/from websocket
func wsComms(w http.ResponseWriter, r *http.Request) {
if ws, err := upgrader.Upgrade(w, r, nil); err == nil { // error ignored for sake of simplicity
defer ws.Close()
log.Printf("wsComms(): Connection from %s upgraded...\n", ws.RemoteAddr())
// handle comms TO the websocket
go func(s *websocket.Conn) {
for {
select {
case m := <-send:
// In actual practice, we'd probably use ws.WriteJSON instead.
if err := s.WriteMessage(websocket.TextMessage, []byte(m)); err != nil {
log.Println("wsComms(): Error sending message:", err.Error())
}
}
}
}(ws)
send <- "Welcome..."
// handle comms FROM the websocket
for {
_, bMsg, err := ws.ReadMessage() // In actual practice, we'd probably use ws.ReadJSON instead.
if err != nil {
log.Println("wsComms(): Error receiving message:", err.Error())
break
}
send <- string(bMsg)
log.Println("wsComms(): Received from client : " + string(bMsg))
}
} else {
log.Println("wsComms(): Error upgrading connection:", err)
}
}