server.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package websocket
  2. import (
  3. "crypto/sha1"
  4. "encoding/base64"
  5. "errors"
  6. "io"
  7. "strings"
  8. "go-common/app/service/main/broadcast/libs/bufio"
  9. )
  10. var (
  11. keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
  12. // ErrBadRequestMethod bad request method
  13. ErrBadRequestMethod = errors.New("bad method")
  14. // ErrNotWebSocket not websocket protocal
  15. ErrNotWebSocket = errors.New("not websocket protocol")
  16. // ErrBadWebSocketVersion bad websocket version
  17. ErrBadWebSocketVersion = errors.New("missing or bad WebSocket Version")
  18. // ErrChallengeResponse mismatch challenge response
  19. ErrChallengeResponse = errors.New("mismatch challenge/response")
  20. )
  21. // Upgrade Switching Protocols
  22. func Upgrade(rwc io.ReadWriteCloser, rr *bufio.Reader, wr *bufio.Writer, req *Request) (conn *Conn, err error) {
  23. if req.Method != "GET" {
  24. return nil, ErrBadRequestMethod
  25. }
  26. if req.Header.Get("Sec-Websocket-Version") != "13" {
  27. return nil, ErrBadWebSocketVersion
  28. }
  29. if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" {
  30. return nil, ErrNotWebSocket
  31. }
  32. if !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
  33. return nil, ErrNotWebSocket
  34. }
  35. challengeKey := req.Header.Get("Sec-Websocket-Key")
  36. if challengeKey == "" {
  37. return nil, ErrChallengeResponse
  38. }
  39. wr.WriteString("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n")
  40. wr.WriteString("Sec-WebSocket-Accept: " + computeAcceptKey(challengeKey) + "\r\n\r\n")
  41. if err = wr.Flush(); err != nil {
  42. return
  43. }
  44. return newConn(rwc, rr, wr), nil
  45. }
  46. func computeAcceptKey(challengeKey string) string {
  47. h := sha1.New()
  48. h.Write([]byte(challengeKey))
  49. h.Write(keyGUID)
  50. return base64.StdEncoding.EncodeToString(h.Sum(nil))
  51. }