mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
// Package ws implements a simple websocket client.
|
|
package ws
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha1"
|
|
"encoding/base64"
|
|
"net"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/nadoo/glider/log"
|
|
"github.com/nadoo/glider/pool"
|
|
"github.com/nadoo/glider/proxy"
|
|
)
|
|
|
|
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
|
|
|
// WS is the base ws proxy struct.
|
|
type WS struct {
|
|
dialer proxy.Dialer
|
|
proxy proxy.Proxy
|
|
addr string
|
|
host string
|
|
path string
|
|
|
|
server proxy.Server
|
|
}
|
|
|
|
// NewWS returns a websocket proxy.
|
|
func NewWS(s string, d proxy.Dialer, p proxy.Proxy) (*WS, error) {
|
|
u, err := url.Parse(s)
|
|
if err != nil {
|
|
log.F("[ws] parse url err: %s", err)
|
|
return nil, err
|
|
}
|
|
|
|
addr := u.Host
|
|
|
|
// TODO:
|
|
if addr == "" {
|
|
addr = d.Addr()
|
|
}
|
|
|
|
w := &WS{
|
|
dialer: d,
|
|
proxy: p,
|
|
addr: addr,
|
|
host: u.Query().Get("host"),
|
|
path: u.Path,
|
|
}
|
|
|
|
if w.host == "" {
|
|
w.host, _, _ = net.SplitHostPort(addr)
|
|
}
|
|
|
|
if w.path == "" {
|
|
w.path = "/"
|
|
}
|
|
|
|
return w, nil
|
|
}
|
|
|
|
// parseFirstLine parses "GET /foo HTTP/1.1" OR "HTTP/1.1 200 OK" into its three parts.
|
|
// TODO: move to separate http lib package for reuse(also for http proxy module)
|
|
func parseFirstLine(line string) (r1, r2, r3 string, ok bool) {
|
|
s1 := strings.Index(line, " ")
|
|
s2 := strings.Index(line[s1+1:], " ")
|
|
if s1 < 0 || s2 < 0 {
|
|
return
|
|
}
|
|
s2 += s1 + 1
|
|
return line[:s1], line[s1+1 : s2], line[s2+1:], true
|
|
}
|
|
|
|
func generateClientKey() string {
|
|
p := pool.GetBuffer(16)
|
|
defer pool.PutBuffer(p)
|
|
rand.Read(p)
|
|
return base64.StdEncoding.EncodeToString(p)
|
|
}
|
|
|
|
func computeServerKey(clientKey string) string {
|
|
h := sha1.New()
|
|
h.Write([]byte(clientKey))
|
|
h.Write(keyGUID)
|
|
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
|
}
|