/
server.go
88 lines (80 loc) · 2.06 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
// Package server is core logic shared by wspc wsps
package server
import (
"fmt"
"net"
"net/http"
"strings"
"github.com/gobwas/ws"
"github.com/gowsp/wsp/pkg/logger"
"github.com/gowsp/wsp/pkg/msg"
)
type Wsps struct {
config *Config
handler http.Handler
}
func New(config *Config) http.Handler {
return NewWithHandler(config, http.NotFoundHandler())
}
func NewWithHandler(config *Config, handler http.Handler) http.Handler {
config.clean()
wsps := &Wsps{config: config, handler: handler}
return wsps
}
func (s *Wsps) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
host, _, _ := net.SplitHostPort(r.Host)
channel := "http:domain:" + host
if val, ok := hub.Load(channel); ok {
val.(*conn).ServeHTTP(channel, rw, r)
return
}
path := strings.TrimPrefix(r.URL.Path, "/")
if path == s.config.Path {
s.ServeProxy(rw, r)
return
}
paths := strings.Split(path, "/")
if len(path) == 0 {
s.handler.ServeHTTP(rw, r)
return
}
channel = "http:path:" + paths[0]
if val, ok := hub.Load(channel); ok {
val.(*conn).ServeHTTP(channel, rw, r)
return
}
s.handler.ServeHTTP(rw, r)
}
func (s *Wsps) ServeProxy(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Auth") != s.config.Auth {
w.WriteHeader(401)
w.Write([]byte("token error, access denied!\n"))
logger.Error("illegal request %s", getRemoteIP(r))
return
}
proto := r.Header.Get("Proto")
logger.Info("accept %s, proto: %s", getRemoteIP(r), proto)
if proto, err := msg.ParseVersion(proto); err != nil || proto.Major() != msg.PROTOCOL_VERSION.Major() {
w.WriteHeader(400)
fmt.Fprintf(w, "client proto version %s not support, server proto is %s\n", proto, msg.PROTOCOL_VERSION)
return
}
ws, _, _, err := ws.UpgradeHTTP(r, w)
if err != nil {
logger.Error("websocket accept %v", err)
return
}
router := &conn{wsps: s}
router.ListenAndServe(ws)
router.close()
}
func getRemoteIP(r *http.Request) string {
IPAddress := r.Header.Get("X-Real-Ip")
if IPAddress == "" {
IPAddress = r.Header.Get("X-Forwarded-For")
}
if IPAddress == "" {
IPAddress = r.RemoteAddr
}
return IPAddress
}