Permalink
Browse files

Implement masking and unmasking.

  • Loading branch information...
1 parent ae51a78 commit 4c8dbe2568fdb9039ef81665ff6c1a490b9c655f @ahyatt committed May 19, 2012
Showing with 31 additions and 8 deletions.
  1. +6 −1 websocket-test.el
  2. +25 −7 websocket.el
View
@@ -51,6 +51,9 @@
(defconst websocket-test-hello "\x81\x05\x48\x65\x6c\x6c\x6f"
"'Hello' string example, taken from the RFC.")
+(defconst websocket-test-masked-hello
+ "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58"
+ "'Hello' masked string example, taken from the RFC.")
(ert-deftest websocket-get-bytes ()
(should (equal #x5 (websocket-get-bytes "\x5" 1)))
@@ -82,4 +85,6 @@
(ert-deftest websocket-read-frame ()
(should (equal (make-websocket-frame :opcode 'text :payload "Hello")
- (websocket-read-frame websocket-test-hello))))
+ (websocket-read-frame websocket-test-hello)))
+ (should (equal (make-websocket-frame :opcode 'text :payload "Hello")
+ (websocket-read-frame websocket-test-masked-hello))))
View
@@ -121,15 +121,33 @@ many bytes were consumed from the string."
(defstruct websocket-frame opcode payload)
+(defun websocket-mask (key data)
+ "Mask string DATA with string KEY according to the RFC.
+This is used to both mask and unmask data."
+ (apply
+ 'string
+ (loop for b across data
+ for i from 0 to (length data)
+ collect (logxor (websocket-get-bytes (substring key (mod i 4)) 1) b))))
+
(defun websocket-read-frame (s)
"Read a frame and return a `websocket-frame' struct with the contents."
- (let ((opcode (websocket-get-opcode s))
- (payload-len (websocket-get-payload-len (substring s 1)))
- (maskp (= 128 (logand 128 (websocket-get-bytes s 1)))))
- (make-websocket-frame :opcode opcode
- :payload (substring s (+ 1 (cdr payload-len))
- (+ 1 (car payload-len)
- (cdr payload-len))))))
+ (let* ((opcode (websocket-get-opcode s))
+ (payload-len (websocket-get-payload-len (substring s 1)))
+ (maskp (= 128 (logand 128 (websocket-get-bytes (substring s 1) 1))))
+ (unmasked-payload (substring
+ s
+ (+ (if maskp 5 1) (cdr payload-len))
+ (+ (if maskp 5 1) (car payload-len)
+ (cdr payload-len)))))
+ (if maskp
+ (let ((masking-key (substring s (+ 1 (cdr payload-len))
+ (+ 5 (cdr payload-len)))))
+ (make-websocket-frame :opcode opcode
+ :payload
+ (websocket-mask masking-key unmasked-payload)))
+ (make-websocket-frame :opcode opcode
+ :payload unmasked-payload))))
(defun websocket-open (url filter &optional close-callback)
"Open a websocket connection to URL.

0 comments on commit 4c8dbe2

Please sign in to comment.