Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added frame processing, and more of the structure to use it.

  • Loading branch information...
commit 3a7798fbe921b2eec3991ab113d4c2d3630afec5 1 parent 7900cda
@ahyatt authored
Showing with 55 additions and 19 deletions.
  1. +33 −1 websocket-test.el
  2. +22 −18 websocket.el
View
34 websocket-test.el
@@ -104,7 +104,7 @@
(- (length websocket-test-masked-hello) (+ i 1)))))))
(defun websocket-test-make-websocket-with-accept-string (s)
- (make-websocket :conn "fake-conn" :url "ws://fo/bar" :filter t :close-callback t
+ (make-websocket :conn "fake-conn" :url "ws://foo/bar" :filter t :close-callback t
:accept-string s))
(ert-deftest websocket-verify-handshake ()
@@ -115,3 +115,35 @@
(should-error (websocket-verify-handshake
(websocket-test-make-websocket-with-accept-string "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
"Sec-WebSocket-Accept: foo\r\n")))
+
+(ert-deftest websocket-process-frame ()
+ (let* ((sent)
+ (processed)
+ (deleted)
+ (websocket (make-websocket :conn "fake-conn"
+ :url "ws://foo/bar"
+ :filter (lambda (frame) (setq processed
+ (websocket-frame-payload frame)))
+ :close-callback t
+ :accept-string "accept-string")))
+ (dolist (opcode '(text binary continuation))
+ (setq processed nil)
+ (should (equal
+ "hello"
+ (progn
+ (websocket-process-frame websocket
+ (make-websocket-frame :opcode opcode :payload "hello"))
+ processed))))
+ (setq sent nil)
+ (flet ((websocket-send (websocket content) (setq sent content)))
+ (should (equal
+ "\xA"
+ (progn
+ (websocket-process-frame websocket
+ (make-websocket-frame :opcode 'ping))
+ sent))))
+ (flet ((delete-process (conn) (setq deleted t)))
+ (should (progn
+ (websocket-process-frame websocket
+ (make-websocket-frame :opcode 'close))
+ deleted)))))
View
40 websocket.el
@@ -252,6 +252,20 @@ either return t or call `error'."
t)
(error "Incorrect handshake from websocket: is this really a websocket connection?"))))
+(defun websocket-process-frame (websocket frame)
+ "Process FRAME returned from WEBSOCKET.
+If the frame has a payload, the frame is passed to the filter
+slot of WEBSOCKET. If the frame is a ping, we reply with a pong.
+If the frame is a close, we terminate the connection."
+ (let ((opcode (websocket-frame-opcode frame)))
+ (cond ((memq opcode '(continuation text binary))
+ (funcall (websocket-filter websocket) frame))
+ ((eq opcode 'ping)
+ ;; \xA == pong opcode
+ (websocket-send websocket "\xA"))
+ ((eq opcode 'close)
+ (delete-process (websocket-conn websocket))))))
+
(defun websocket-outer-filter (websocket output)
"Removes connection strings, only passes packets."
(websocket-debug websocket "Received: %s" output)
@@ -265,21 +279,13 @@ either return t or call `error'."
(not (websocket-handshake-accept-passed-p websocket))
start-point)
(websocket-verify-handshake websocket text))
- (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)))
- (let* ((next-start (or start-point
- (when end-point
- (or (string-match "\0" text end-point)
- (- (length text) 1)))
- 0))
- (next-end (or (string-match "\377" text next-start)
- (length text))))
- (setf (websocket-inflight-packet websocket)
- (concat (substring text next-start next-end))))))
+ (let ((current-frame))
+ (while (and start-point
+ (setq current-frame (websocket-read-frame (substring text start-point))))
+ (websocket-process-frame websocket current-frame)
+ (incf start-point (websocket-frame-length current-frame))))
+ ;; TODO(ahyatt) Rename websocket-inflight-packet (it isn't a packet)
+ (setf (websocket-inflight-packet websocket) (substring text (or start-point 0)))))
(defun websocket-send (websocket text)
"Send the raw TEXT as a websocket packet."
@@ -287,9 +293,7 @@ either return t or call `error'."
(websocket-ensure-connected websocket)
(unless (websocket-openp websocket)
(error "No webserver process to send data to!"))
- (process-send-string (websocket-conn websocket)
- (concat (unibyte-string ?\0) text
- (unibyte-string ?\377))))
+ (process-send-string (websocket-conn websocket)))
(defun websocket-openp (websocket)
"Returns true if the websocket exists and is open."
Please sign in to comment.
Something went wrong with that request. Please try again.