2019-04-22 02:59:20 +00:00

57 lines
1.7 KiB
Go

package websocket
import (
"crypto/sha1"
"encoding/base64"
"errors"
"io"
"strings"
"go-common/app/service/main/broadcast/libs/bufio"
)
var (
keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
// ErrBadRequestMethod bad request method
ErrBadRequestMethod = errors.New("bad method")
// ErrNotWebSocket not websocket protocal
ErrNotWebSocket = errors.New("not websocket protocol")
// ErrBadWebSocketVersion bad websocket version
ErrBadWebSocketVersion = errors.New("missing or bad WebSocket Version")
// ErrChallengeResponse mismatch challenge response
ErrChallengeResponse = errors.New("mismatch challenge/response")
)
// Upgrade Switching Protocols
func Upgrade(rwc io.ReadWriteCloser, rr *bufio.Reader, wr *bufio.Writer, req *Request) (conn *Conn, err error) {
if req.Method != "GET" {
return nil, ErrBadRequestMethod
}
if req.Header.Get("Sec-Websocket-Version") != "13" {
return nil, ErrBadWebSocketVersion
}
if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" {
return nil, ErrNotWebSocket
}
if !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
return nil, ErrNotWebSocket
}
challengeKey := req.Header.Get("Sec-Websocket-Key")
if challengeKey == "" {
return nil, ErrChallengeResponse
}
wr.WriteString("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n")
wr.WriteString("Sec-WebSocket-Accept: " + computeAcceptKey(challengeKey) + "\r\n\r\n")
if err = wr.Flush(); err != nil {
return
}
return newConn(rwc, rr, wr), nil
}
func computeAcceptKey(challengeKey string) string {
h := sha1.New()
h.Write([]byte(challengeKey))
h.Write(keyGUID)
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}