Skip to content
Browse files

Fix many issues with server connections.

There is still an issue with multibyte strings, though.
  • Loading branch information...
1 parent 0202adc commit 74d5c10c17eacbfd2f70ac5b8e9f73592040ded2 @ahyatt committed
Showing with 47 additions and 14 deletions.
  1. +32 −1 websocket-test.el
  2. +15 −13 websocket.el
View
33 websocket-test.el
@@ -202,7 +202,8 @@
(base-headers (concat "Host: www.example.com\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
- "Sec-WebSocket-Key: key\r\n"
+ (format "Sec-WebSocket-Key: %s\r\n"
+ (websocket-calculate-accept "key"))
"Origin: mysystem\r\n"
"Sec-WebSocket-Version: 13\r\n")))
(should (equal (concat base-headers "\r\n")
@@ -509,3 +510,33 @@
(should-not closed)
(should (equal response "response"))
(should processed)))))
+
+(ert-deftest websocket-complete-server-response-test ()
+ ;; Example taken from RFC
+ (should (equal
+ (concat "HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
+ "Sec-WebSocket-Protocol: chat\r\n\r\n"
+ )
+ (let ((header-info
+ (websocket-verify-client-headers
+ (concat "GET /chat HTTP/1.1\r\n"
+ "Host: server.example.com\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
+ "Origin: http://example.com\r\n"
+ "Sec-WebSocket-Protocol: chat, superchat\r\n"
+ "Sec-WebSocket-Version: 13\r\n"))))
+ (should header-info)
+ (let ((ws (websocket-inner-create
+ :conn t :url t
+ :accept-string (websocket-calculate-accept
+ (plist-get header-info :key))
+ :protocols '("chat"))))
+ (websocket-get-server-response
+ ws
+ (plist-get header-info :protocols)
+ (plist-get header-info :extension)))))))
View
28 websocket.el
@@ -521,11 +521,12 @@ describing the problem with the frame.
(message "Connected from %S: %s" client message)
(let ((ws (websocket-inner-create
:conn client
- :on-open (or (process-get proc :on-open) 'identity)
- :on-message (or (process-get proc :on-message) (lambda (ws frame)))
- :on-error (or (process-get proc :on-error) 'identity)
- :protocol (process-get proc :protocol)
- :extensions (mapcar 'car (process-get proc :extensions)))))
+ :url client
+ :on-open (or (process-get server :on-open) 'identity)
+ :on-message (or (process-get server :on-message) (lambda (ws frame)))
+ :on-error (or (process-get server :on-error) 'identity)
+ :protocols (process-get server :protocol)
+ :extensions (mapcar 'car (process-get server :extensions)))))
(process-put client :websocket ws)
(set-process-filter client 'websocket-server-filter)))
@@ -538,7 +539,7 @@ messages and a plist containing `:key', the websocket key,
(block nil
(let ((case-fold-search t)
(plist))
- (unless (string-match "^HTTP/1.1" output)
+ (unless (string-match "HTTP/1.1" output)
(message "Websocket client connection: HTTP/1.1 not found")
(return nil))
(unless (string-match "^Host: " output)
@@ -548,18 +549,17 @@ messages and a plist containing `:key', the websocket key,
(message "Websocket client connection: Upgrade: websocket not found")
(return nil))
(if (string-match "^Sec-WebSocket-Key: \\([[:graph:]]+\\)\r\n" output)
- (setq plist (plist-put plist :key (base64-decode-string
- (match-string 1 output))))
+ (setq plist (plist-put plist :key (match-string 1 output)))
(message "Websocket client connect: No key sent")
(return nil))
(unless (string-match "^Sec-WebSocket-Version: 13" output)
(message "Websocket client connect: Websocket version 13 not found")
(return nil))
- (when (string-match "^Sec-WebSocket-Protocol: \\([[:graph:]]+\\)\r\n" output)
+ (when (string-match "^Sec-WebSocket-Protocol:" output)
(setq plist (plist-put plist :protocols (websocket-parse-repeated-field
output
"Sec-Websocket-Protocol"))))
- (when (string-match "^Sec-WebSocket-Extensions: \\([[:graph:]]+\\)\r\n" output)
+ (when (string-match "^Sec-WebSocket-Extensions:" output)
(setq plist (plist-put plist :extensions (websocket-parse-repeated-field
output
"Sec-Websocket-Extensions"))))
@@ -577,7 +577,7 @@ messages and a plist containing `:key', the websocket key,
(when pos (+ 4 pos)))))
(if end-of-header-pos
(progn
- (let ((header-info (websocket-verify-client-headers ws text)))
+ (let ((header-info (websocket-verify-client-headers text)))
(if header-info
(progn (setf (websocket-accept-string ws)
(websocket-calculate-accept
@@ -639,12 +639,14 @@ messages and a plist containing `:key', the websocket key,
separator)))
(defun* websocket-server (port &rest plist)
- "Open a websocket server on PORT."
+ "Open a websocket server on PORT.
+PORT can be `t' to get a random port."
(let* ((conn (make-network-process
:name (format "websocket server on port %d" port)
:server t
:family 'ipv4
:log 'websocket-server-accept
+ :filter-multibyte nil
:plist plist
:host 'local
:service port
@@ -832,7 +834,7 @@ connection is invalid, the connection will be closed."
(setf (websocket-inflight-input websocket)
(substring text start-point)))
(dolist (to-process (nreverse processing-queue))
- (funcall to-process)))))
+ (funcall to-process))))
(defun websocket-send-text (websocket text)
"To the WEBSOCKET, send TEXT as a complete frame."

0 comments on commit 74d5c10

Please sign in to comment.
Something went wrong with that request. Please try again.