Permalink
Browse files

Get opening handshake to work correctly. Framing does not yet work,

and because of this the handshake test does also not happen yet.
  • Loading branch information...
1 parent b5bbce1 commit 07050bcc310ddf7c85fc63b751c0a4a07c7e236d @ahyatt committed May 9, 2012
Showing with 36 additions and 33 deletions.
  1. +1 −1 testserver.py
  2. +1 −1 websocket-test.el
  3. +34 −31 websocket.el
View
@@ -19,7 +19,7 @@ def on_close(self):
logging.info("ON_CLOSE")
def allow_draft76(self):
- return True
+ return False
if __name__ == "__main__":
View
@@ -41,7 +41,7 @@
(ert-deftest websocket-genbytes-length ()
(loop repeat 100
- do (should (= (string-bytes (websocket-genbytes)) 8))))
+ do (should (= (string-bytes (websocket-genbytes)) 16))))
(ert-deftest websocket-filter-basic ()
(should (equal
View
@@ -34,6 +34,8 @@
(filter (assert nil) :read-only t)
(close-callback (assert nil) :read-only t)
(url (assert nil) :read-only t)
+ (accept-string (assert nil))
+ (handshake-accept-passed-p nil)
(inflight-packet nil))
(defvar websocket-debug nil
@@ -45,10 +47,14 @@ URL of the connection.")
"The websocket GUID as defined in RFC 6455. Do not change
unless the RFC changes.")
+(defvar websocket-require-server-accept t
+ "If true, we require the correct Sec-WebSocket-Accept header
+as part of the connection handshake.")
+
(defun websocket-genbytes ()
"Generate bytes used at the end of the handshake."
- (let ((s " "))
- (dotimes (i 8)
+ (let ((s " "))
+ (dotimes (i 16)
(aset s i (random 256)))
s))
@@ -60,20 +66,7 @@ URL of the connection.")
(defun websocket-genkey ()
"Generate a key suitable for the websocket handshake."
- (let* ((num-spaces (+ 1 (random 12)))
- (max-num-str (calc-eval (format "floor(random(4294967295 / %d)) * %d"
- num-spaces num-spaces)))
- (num max-num-str))
- (dotimes (_ num-spaces)
- (setq max-num-str (websocket-random-insert " " max-num-str)))
- (dotimes (_ (+ 1 (random 12)))
- (setq max-num-str (websocket-random-insert
- (let ((r (random 82)))
- (char-to-string
- (if (< r 15) (+ 33 r)
- (+ 58 (- r 15)))))
- max-num-str)))
- (cons max-num-str num)))
+ (base64-encode-string (websocket-genbytes)))
(defun websocket-calculate-accept (key)
"Calculate the expect value of the accept header.
@@ -87,9 +80,7 @@ Websocket packets are sent as the only argument to FILTER, and if
the connection is closed, then CLOSE-CALLBACK is called."
(let* ((name (format "websocket to %s" url))
(url-struct (url-generic-parse-url url))
- (key1-cons (websocket-genkey))
- (key2-cons (websocket-genkey))
- (bytes (websocket-genbytes))
+ (key (websocket-genkey))
(buf-name (format " *%s*" name))
(coding-system-for-read 'binary)
(coding-system-for-write 'binary)
@@ -103,7 +94,9 @@ the connection is closed, then CLOSE-CALLBACK is called."
(error "Not implemented yet")
(error "Unknown protocol"))))
(websocket (make-websocket :conn conn :url url :filter filter
- :close-callback close-callback)))
+ :close-callback close-callback
+ :accept-string
+ (websocket-calculate-accept key))))
(lexical-let ((websocket websocket))
(set-process-filter conn
(lambda (process output)
@@ -124,19 +117,16 @@ the connection is closed, then CLOSE-CALLBACK is called."
(websocket-debug websocket "Sending handshake")
(process-send-string
conn
- (format (concat "Upgrade: WebSocket\r\n"
+ (format (concat "Host: %s\r\n"
+ "Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
- "Host: %s\r\n"
+ "Sec-WebSocket-Key: %s\r\n"
"Origin: %s\r\n"
- "Sec-WebSocket-Key1: %s\r\n"
- "Sec-WebSocket-Key2: %s\r\n"
+ "Sec-WebSocket-Version: 13\r\n"
"\r\n")
(url-host (url-generic-parse-url url))
system-name
- (car key1-cons)
- (car key2-cons)))
- (websocket-debug websocket "Sending bytes")
- (process-send-string conn bytes)
+ key))
(websocket-debug websocket "Websocket opened")
websocket))
@@ -162,9 +152,22 @@ the connection is closed, then CLOSE-CALLBACK is called."
(end-point 0)
(text (concat (websocket-inflight-packet websocket) output)))
(setq start-point (string-match "\0" text))
- (while (and start-point
- (setq end-point
- (string-match "\377" text start-point)))
+ ;; If we've received the first packet, check to see if we've
+ ;; received the desired handshake.
+ (when (and websocket-require-server-accept
+ (not (websocket-handshake-accept-passed-p websocket))
+ start-point)
+ (let ((accept-string
+ (concat "Sec-WebSocket-Accept: " (websocket-accept-string websocket))))
+ (websocket-debug websocket "Handshake received, checking for: %s" accept-string)
+ (if (string-match (regexp-quote accept-string) text)
+ (progn
+ (setf (websocket-handshake-accept-passed-p websocket) t)
+ (websocket-debug websocket "Handshake accepted"))
+ (error "Incorrect handshake from websocket: is this really a websocket connection?"))))
+ (while (and start-point
+ (setq end-point
+ (string-match "\377" text start-point)))
(funcall (websocket-filter websocket)
(substring text (+ 1 start-point) end-point))
(setq start-point (string-match "\0" text end-point)))

0 comments on commit 07050bc

Please sign in to comment.