Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 574 lines (543 sloc) 27.659 kb
0202adc Andrew Hyatt Finish and test the server filter function.
authored
1 ;; websocket-test.el --- Unit tests for the websocket layer
59697b4 Andrew Hyatt Initial checkin of files. These files were initially part of the
authored
2
3 ;; Copyright (c) 2010 Andrew Hyatt
4 ;;
5 ;; Author: Andrew Hyatt <ahyatt at gmail dot com>
6 ;; Maintainer: Andrew Hyatt <ahyatt at gmail dot com>
7 ;;
8 ;; This program is free software; you can redistribute it and/or
9 ;; modify it under the terms of the GNU General Public License as
10 ;; published by the Free Software Foundation; either version 2 of the
11 ;; License, or (at your option) any later version.
12 ;;
13 ;; This program is distributed in the hope that it will be useful, but
14 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ;; General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program; if not, write to the Free Software
20 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 ;; 02110-1301, USA.
22
23 ;;; Commentary:
24 ;; This defines and runs ert unit tests. You can download ert from:
25 ;; http://github.com/ohler/ert, it also comes with Emacs 24 and above.
26
27 (require 'ert)
9d8794a Takafumi Arakaki Suppress compilation warning in websocket-test.el
tkf authored
28 (require 'websocket)
29 (eval-when-compile (require 'cl))
59697b4 Andrew Hyatt Initial checkin of files. These files were initially part of the
authored
30
45245a4 Takafumi Arakaki Add test websocket-genbytes-length
tkf authored
31 (ert-deftest websocket-genbytes-length ()
32 (loop repeat 100
82e85aa Andrew Hyatt Fix test for websocket-genbytes
authored
33 do (should (= (string-bytes (websocket-genbytes 16)) 16))))
45245a4 Takafumi Arakaki Add test websocket-genbytes-length
tkf authored
34
b5bbce1 Andrew Hyatt Add a function to calculate the accept header expected.
authored
35 (ert-deftest websocket-calculate-accept ()
36 ;; This example comes straight from RFC 6455
37 (should
38 (equal "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
237b190 Andrew Hyatt Various whitespace changes
authored
39 (websocket-calculate-accept "dGhlIHNhbXBsZSBub25jZQ=="))))
b5bbce1 Andrew Hyatt Add a function to calculate the accept header expected.
authored
40
f4e1aa8 Andrew Hyatt Add helper functions for websocket-get-opcode and
authored
41 (defconst websocket-test-hello "\x81\x05\x48\x65\x6c\x6c\x6f"
42 "'Hello' string example, taken from the RFC.")
237b190 Andrew Hyatt Various whitespace changes
authored
43
4c8dbe2 Andrew Hyatt Implement masking and unmasking.
authored
44 (defconst websocket-test-masked-hello
45 "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58"
46 "'Hello' masked string example, taken from the RFC.")
f4e1aa8 Andrew Hyatt Add helper functions for websocket-get-opcode and
authored
47
39f1f28 Takafumi Arakaki Force test to pass in 32-bit Emacs
tkf authored
48 (defconst websocket-test-64-bit-p
49 (calc-eval '("2^32 <= $") 'pred most-positive-fixnum))
50
b948e95 Andrew Hyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
51 (ert-deftest websocket-get-bytes ()
52 (should (equal #x5 (websocket-get-bytes "\x5" 1)))
53 (should (equal #x101 (websocket-get-bytes "\x1\x1" 2)))
39f1f28 Takafumi Arakaki Force test to pass in 32-bit Emacs
tkf authored
54 (let ((f (lambda () (websocket-get-bytes "\x0\x0\x0\x1\x0\x0\x0\x1" 8))))
55 (if websocket-test-64-bit-p
56 (should (equal #x100000001 (funcall f)))
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
57 (should-error (funcall f) :type 'websocket-unparseable-frame)))
b948e95 Andrew Hyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
58 (should-error (websocket-get-bytes "\x0\x0\x0" 3))
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
59 (should-error (websocket-get-bytes "\x0" 2) :type 'websocket-unparseable-frame))
b948e95 Andrew Hyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
60
f4e1aa8 Andrew Hyatt Add helper functions for websocket-get-opcode and
authored
61 (ert-deftest websocket-get-opcode ()
62 (should (equal 'text (websocket-get-opcode websocket-test-hello))))
63
64 (ert-deftest websocket-get-payload-len ()
b948e95 Andrew Hyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
65 (should (equal '(5 . 1)
66 (websocket-get-payload-len
67 (substring websocket-test-hello 1))))
f4e1aa8 Andrew Hyatt Add helper functions for websocket-get-opcode and
authored
68 (should (equal '(200 . 3)
69 (websocket-get-payload-len
b948e95 Andrew Hyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
70 (bindat-pack '((:len u8) (:val u16))
71 `((:len . 126)
f4e1aa8 Andrew Hyatt Add helper functions for websocket-get-opcode and
authored
72 (:val . 200))))))
73 ;; we don't want to hit up any limits even on strange emacs builds,
74 ;; so this test has a pretty small test value
75 (should (equal '(70000 . 9)
76 (websocket-get-payload-len
b948e95 Andrew Hyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
77 (bindat-pack '((:len u8) (:val vec 2 u32))
78 `((:len . 127)
f4e1aa8 Andrew Hyatt Add helper functions for websocket-get-opcode and
authored
79 (:val . [0 70000])))))))
ae51a78 Andrew Hyatt Code to read a frame. Does not yet support masking.
authored
80
81 (ert-deftest websocket-read-frame ()
7900cda Andrew Hyatt Return the length of the websocket frame from websocket-read-frame.
authored
82 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 Andrew Hyatt Add completep in frame
authored
83 :length (length websocket-test-hello)
84 :completep t)
4c8dbe2 Andrew Hyatt Implement masking and unmasking.
authored
85 (websocket-read-frame websocket-test-hello)))
7900cda Andrew Hyatt Return the length of the websocket frame from websocket-read-frame.
authored
86 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 Andrew Hyatt Add completep in frame
authored
87 :length (length websocket-test-hello)
88 :completep t)
7900cda Andrew Hyatt Return the length of the websocket frame from websocket-read-frame.
authored
89 (websocket-read-frame (concat websocket-test-hello
90 "should-not-be-read"))))
91 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 Andrew Hyatt Add completep in frame
authored
92 :length (length websocket-test-masked-hello)
93 :completep t)
51b5764 Andrew Hyatt Ensure the websocket frame is complete, and return NIL if not.
authored
94 (websocket-read-frame websocket-test-masked-hello)))
b0a2970 Andrew Hyatt Add completep in frame
authored
95 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
96 :length (length websocket-test-hello)
97 :completep nil)
1081075 Andrew Hyatt More whitespace changes
authored
98 (websocket-read-frame
99 (concat (unibyte-string
100 (logand (string-to-char
101 (substring websocket-test-hello 0 1))
102 127))
103 (substring websocket-test-hello 1)))))
51b5764 Andrew Hyatt Ensure the websocket frame is complete, and return NIL if not.
authored
104 (dotimes (i (- (length websocket-test-hello) 1))
105 (should-not (websocket-read-frame
106 (substring websocket-test-hello 0
107 (- (length websocket-test-hello) (+ i 1))))))
108 (dotimes (i (- (length websocket-test-masked-hello) 1))
109 (should-not (websocket-read-frame
110 (substring websocket-test-masked-hello 0
111 (- (length websocket-test-masked-hello) (+ i 1)))))))
8da9119 Andrew Hyatt Separate out the handshake verification logic, and test it. Look for
authored
112
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
113 (defun websocket-test-header-with-lines (&rest lines)
114 (mapconcat 'identity (append lines '("\r\n")) "\r\n"))
8da9119 Andrew Hyatt Separate out the handshake verification logic, and test it. Look for
authored
115
6c42988 Andrew Hyatt Check for HTTP 101 response code, and if there is any failure in the
authored
116 (ert-deftest websocket-verify-response-code ()
117 (should (websocket-verify-response-code "HTTP/1.1 101"))
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
118 (should
119 (eq 400 (cdr (should-error (websocket-verify-response-code "HTTP/1.1 400")
120 :type 'websocket-received-error-http-response))))
121 (should
122 (eq 200 (cdr (should-error (websocket-verify-response-code "HTTP/1.1 200"))))))
6c42988 Andrew Hyatt Check for HTTP 101 response code, and if there is any failure in the
authored
123
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
124 (ert-deftest websocket-verify-headers ()
125 (let ((accept "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
126 (invalid-accept "Sec-WebSocket-Accept: bad")
127 (upgrade "Upgrade: websocket")
128 (connection "Connection: upgrade")
129 (ws (websocket-inner-create
130 :conn "fake-conn" :url "ws://foo/bar"
131 :accept-string "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="))
132 (ws-with-protocol
133 (websocket-inner-create
134 :conn "fake-conn" :url "ws://foo/bar"
135 :accept-string "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
5a8b995 Andrew Hyatt Add server header generation, and refactor protocol and extension handli...
authored
136 :protocols '("myprotocol")))
881c6ca Andrew Hyatt Implement support for specifying extensions.
authored
137 (ws-with-extensions
138 (websocket-inner-create
139 :conn "fake-conn" :url "ws://foo/bar"
140 :accept-string "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
141 :extensions '("ext1" "ext2"))))
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
142 (should (websocket-verify-headers
143 ws
144 (websocket-test-header-with-lines accept upgrade connection)))
145 (should-error
146 (websocket-verify-headers
147 ws
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
148 (websocket-test-header-with-lines invalid-accept upgrade connection))
149 :type 'websocket-invalid-header)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
150 (should-error (websocket-verify-headers
151 ws
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
152 (websocket-test-header-with-lines upgrade connection))
153 :type 'websocket-invalid-header)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
154 (should-error (websocket-verify-headers
155 ws
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
156 (websocket-test-header-with-lines accept connection))
157 :type 'websocket-invalid-header)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
158 (should-error (websocket-verify-headers
159 ws
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
160 (websocket-test-header-with-lines accept upgrade))
161 :type 'websocket-invalid-header)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
162 (should-error (websocket-verify-headers
163 ws-with-protocol
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
164 (websocket-test-header-with-lines accept upgrade connection))
165 :type 'websocket-invalid-header)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
166 (should-error
167 (websocket-verify-headers
168 ws-with-protocol
169 (websocket-test-header-with-lines accept upgrade connection
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
170 "Sec-Websocket-Protocol: foo"))
171 :type 'websocket-invalid-header)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
172 (should
173 (websocket-verify-headers
174 ws-with-protocol
175 (websocket-test-header-with-lines accept upgrade connection
881c6ca Andrew Hyatt Implement support for specifying extensions.
authored
176 "Sec-Websocket-Protocol: myprotocol")))
5a8b995 Andrew Hyatt Add server header generation, and refactor protocol and extension handli...
authored
177 (should (equal '("myprotocol")
178 (websocket-negotiated-protocols ws-with-protocol)))
881c6ca Andrew Hyatt Implement support for specifying extensions.
authored
179 (should-error
180 (websocket-verify-headers
181 ws-with-extensions
182 (websocket-test-header-with-lines accept upgrade connection
183 "Sec-Websocket-Extensions: foo")))
184 (should
185 (websocket-verify-headers
186 ws-with-extensions
187 (websocket-test-header-with-lines
188 accept upgrade connection "Sec-Websocket-Extensions: ext1, ext2; a=1")))
189 (should (equal '("ext1" "ext2; a=1")
5a8b995 Andrew Hyatt Add server header generation, and refactor protocol and extension handli...
authored
190 (websocket-negotiated-extensions ws-with-extensions)))
881c6ca Andrew Hyatt Implement support for specifying extensions.
authored
191 (should
192 (websocket-verify-headers
193 ws-with-extensions
194 (websocket-test-header-with-lines accept upgrade connection
195 "Sec-Websocket-Extensions: ext1"
196 "Sec-Websocket-Extensions: ext2; a=1")))
197 (should (equal '("ext1" "ext2; a=1")
5a8b995 Andrew Hyatt Add server header generation, and refactor protocol and extension handli...
authored
198 (websocket-negotiated-extensions ws-with-extensions)))))
881c6ca Andrew Hyatt Implement support for specifying extensions.
authored
199
200 (ert-deftest websocket-create-headers ()
201 (let ((system-name "mysystem")
202 (base-headers (concat "Host: www.example.com\r\n"
203 "Upgrade: websocket\r\n"
204 "Connection: Upgrade\r\n"
23b132e Andrew Hyatt Fix failing ert tests
authored
205 "Sec-WebSocket-Key: key\r\n"
881c6ca Andrew Hyatt Implement support for specifying extensions.
authored
206 "Origin: mysystem\r\n"
207 "Sec-WebSocket-Version: 13\r\n")))
208 (should (equal (concat base-headers "\r\n")
209 (websocket-create-headers "ws://www.example.com/path"
210 "key" nil nil)))
211 (should (equal (concat base-headers
212 "Sec-WebSocket-Protocol: protocol\r\n\r\n")
213 (websocket-create-headers "ws://www.example.com/path"
5a8b995 Andrew Hyatt Add server header generation, and refactor protocol and extension handli...
authored
214 "key" '("protocol") nil)))
881c6ca Andrew Hyatt Implement support for specifying extensions.
authored
215 (should (equal
216 (concat base-headers
217 "Sec-WebSocket-Extensions: ext1; a; b=2, ext2\r\n\r\n")
218 (websocket-create-headers "ws://www.example.com/path"
219 "key" nil
220 '(("ext1" . ("a" "b=2"))
221 ("ext2")))))))
3a7798f Andrew Hyatt Added frame processing, and more of the structure to use it.
authored
222
223 (ert-deftest websocket-process-frame ()
224 (let* ((sent)
225 (processed)
226 (deleted)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
227 (websocket (websocket-inner-create
228 :conn t :url t
229 :on-message (lambda (websocket frame)
230 (setq
231 processed
232 (websocket-frame-payload frame)))
233 :accept-string t)))
3a7798f Andrew Hyatt Added frame processing, and more of the structure to use it.
authored
234 (dolist (opcode '(text binary continuation))
235 (setq processed nil)
236 (should (equal
237 "hello"
238 (progn
14e94a4 Andrew Hyatt Revamp how error processing works, increasing user control and
authored
239 (funcall (websocket-process-frame
240 websocket
241 (make-websocket-frame :opcode opcode :payload "hello")))
3a7798f Andrew Hyatt Added frame processing, and more of the structure to use it.
authored
242 processed))))
243 (setq sent nil)
244 (flet ((websocket-send (websocket content) (setq sent content)))
245 (should (equal
7bc2aae Andrew Hyatt Make websocket-send work on frames, and use it to send pongs.
authored
246 (make-websocket-frame :opcode 'pong :completep t)
3a7798f Andrew Hyatt Added frame processing, and more of the structure to use it.
authored
247 (progn
14e94a4 Andrew Hyatt Revamp how error processing works, increasing user control and
authored
248 (funcall (websocket-process-frame websocket
249 (make-websocket-frame :opcode 'ping)))
3a7798f Andrew Hyatt Added frame processing, and more of the structure to use it.
authored
250 sent))))
251 (flet ((delete-process (conn) (setq deleted t)))
252 (should (progn
14e94a4 Andrew Hyatt Revamp how error processing works, increasing user control and
authored
253 (funcall
254 (websocket-process-frame websocket
255 (make-websocket-frame :opcode 'close)))
3a7798f Andrew Hyatt Added frame processing, and more of the structure to use it.
authored
256 deleted)))))
2148c5a Andrew Hyatt Create the websocket-to-bytes function, to encode a number in a
authored
257
14e94a4 Andrew Hyatt Revamp how error processing works, increasing user control and
authored
258 (ert-deftest websocket-process-frame-error-handling ()
259 (let* ((error-called)
260 (websocket (websocket-inner-create
261 :conn t :url t :accept-string t
262 :on-message (lambda (websocket frame)
263 (message "In on-message")
264 (error "err"))
265 :on-error (lambda (ws type err)
266 (should (eq 'on-message type))
267 (setq error-called t)))))
268 (funcall (websocket-process-frame websocket
269 (make-websocket-frame :opcode 'text
270 :payload "hello")))
271 (should error-called)))
272
2148c5a Andrew Hyatt Create the websocket-to-bytes function, to encode a number in a
authored
273 (ert-deftest websocket-to-bytes ()
274 ;; We've tested websocket-get-bytes by itself, now we can use it to
275 ;; help test websocket-to-bytes.
276 (should (equal 30 (websocket-get-bytes (websocket-to-bytes 30 1) 1)))
277 (should (equal 300 (websocket-get-bytes (websocket-to-bytes 300 2) 2)))
39f1f28 Takafumi Arakaki Force test to pass in 32-bit Emacs
tkf authored
278 (let ((f (lambda () (websocket-to-bytes 70000 8))))
279 (if websocket-test-64-bit-p
280 (should (equal 70000 (websocket-get-bytes (funcall f) 8)))
281 (should-error (funcall f))))
2148c5a Andrew Hyatt Create the websocket-to-bytes function, to encode a number in a
authored
282 (should-error (websocket-to-bytes 30 3))
cf885f0 Andrew Hyatt Fix issue on < 64-bit systems in packing an 8 byte value.
authored
283 (should-error (websocket-to-bytes 300 1))
284 ;; I'd like to test the error for 32-byte systems on 8-byte lengths,
285 ;; but elisp does not allow us to temporarily set constants such as
286 ;; most-positive-fixnum.
287 )
2148c5a Andrew Hyatt Create the websocket-to-bytes function, to encode a number in a
authored
288
3596d84 Andrew Hyatt Write and test websocket-encode-frame.
authored
289 (ert-deftest websocket-encode-frame ()
290 ;; We've tested websocket-read-frame, now we can use that to help
291 ;; test websocket-encode-frame.
655cf1e Andrew Hyatt Support outbound masking
authored
292 (let ((websocket-mask-frames nil))
293 (should (equal
294 websocket-test-hello
295 (websocket-encode-frame
296 (make-websocket-frame :opcode 'text :payload "Hello" :completep t))))
39f1f28 Takafumi Arakaki Force test to pass in 32-bit Emacs
tkf authored
297 (dolist (len (if websocket-test-64-bit-p '(200 70000) '(200 60000)))
237b190 Andrew Hyatt Various whitespace changes
authored
298 (let ((long-string (make-string len ?x)))
299 (should (equal long-string
300 (websocket-frame-payload
301 (websocket-read-frame
302 (websocket-encode-frame
1081075 Andrew Hyatt More whitespace changes
authored
303 (make-websocket-frame :opcode 'text
304 :payload long-string)))))))))
655cf1e Andrew Hyatt Support outbound masking
authored
305 (let ((websocket-mask-frames t))
306 (flet ((websocket-genbytes (n) (substring websocket-test-masked-hello 2 6)))
237b190 Andrew Hyatt Various whitespace changes
authored
307 (should (equal websocket-test-masked-hello
308 (websocket-encode-frame
1081075 Andrew Hyatt More whitespace changes
authored
309 (make-websocket-frame :opcode 'text :payload "Hello"
310 :completep t))))))
3596d84 Andrew Hyatt Write and test websocket-encode-frame.
authored
311 (should-not
312 (websocket-frame-completep
313 (websocket-read-frame
1081075 Andrew Hyatt More whitespace changes
authored
314 (websocket-encode-frame (make-websocket-frame :opcode 'text
315 :payload "Hello"
316 :completep nil)))))
0e04e15 Andrew Hyatt Fix issue with encoding & decoding non-payload frames, and fix the
authored
317 (dolist (opcode '(close ping pong))
3596d84 Andrew Hyatt Write and test websocket-encode-frame.
authored
318 (should (equal
319 opcode
320 (websocket-frame-opcode
321 (websocket-read-frame
0e04e15 Andrew Hyatt Fix issue with encoding & decoding non-payload frames, and fix the
authored
322 (websocket-encode-frame (make-websocket-frame :opcode opcode
323 :completep t))))))))
3596d84 Andrew Hyatt Write and test websocket-encode-frame.
authored
324
33ff92c Andrew Hyatt Update websocket-close and test
authored
325 (ert-deftest websocket-close ()
5c2b235 Andrew Hyatt Implement proper behavior on closing of server.
authored
326 (let ((sent-frames)
327 (processes-deleted))
33ff92c Andrew Hyatt Update websocket-close and test
authored
328 (flet ((websocket-send (websocket frame) (push frame sent-frames))
329 (websocket-openp (websocket) t)
330 (kill-buffer (buffer))
5c2b235 Andrew Hyatt Implement proper behavior on closing of server.
authored
331 (delete-process (proc))
332 (process-buffer (conn) (add-to-list 'processes-deleted conn)))
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
333 (websocket-close (websocket-inner-create
334 :conn "fake-conn"
335 :url t
336 :accept-string t))
33ff92c Andrew Hyatt Update websocket-close and test
authored
337 (should (equal sent-frames (list
338 (make-websocket-frame :opcode 'close
5c2b235 Andrew Hyatt Implement proper behavior on closing of server.
authored
339 :completep t))))
340 (should (equal processes-deleted '("fake-conn"))))))
b89e002 Andrew Hyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
341
342 (ert-deftest websocket-outer-filter ()
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
343 (let* ((fake-ws (websocket-inner-create
344 :conn t :url t :accept-string t
345 :on-open (lambda (websocket)
346 (should (eq (websocket-ready-state websocket)
347 'open))
348 (setq open-callback-called t)
14e94a4 Andrew Hyatt Revamp how error processing works, increasing user control and
authored
349 (error "Ignore me!"))
350 :on-error (lambda (ws type err))))
b89e002 Andrew Hyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
351 (processed-frames)
352 (frame1 (make-websocket-frame :opcode 'text :payload "foo" :completep t
353 :length 9))
354 (frame2 (make-websocket-frame :opcode 'text :payload "bar" :completep t
355 :length 9))
078fbf3 Andrew Hyatt Implemented onopen callback. Soon to be renamed.
authored
356 (open-callback-called)
b89e002 Andrew Hyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
357 (websocket-frames
358 (concat
359 (websocket-encode-frame frame1)
360 (websocket-encode-frame frame2))))
14e94a4 Andrew Hyatt Revamp how error processing works, increasing user control and
authored
361 (flet ((websocket-process-frame
362 (websocket frame)
363 (lexical-let ((frame frame))
364 (lambda () (push frame processed-frames))))
6c42988 Andrew Hyatt Check for HTTP 101 response code, and if there is any failure in the
authored
365 (websocket-verify-response-code (output) t)
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
366 (websocket-verify-headers (websocket output) t))
b89e002 Andrew Hyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
367 (websocket-outer-filter fake-ws "Sec-")
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
368 (should (eq (websocket-ready-state fake-ws) 'connecting))
078fbf3 Andrew Hyatt Implemented onopen callback. Soon to be renamed.
authored
369 (should-not open-callback-called)
b89e002 Andrew Hyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
370 (websocket-outer-filter fake-ws "WebSocket-Accept: acceptstring")
078fbf3 Andrew Hyatt Implemented onopen callback. Soon to be renamed.
authored
371 (should-not open-callback-called)
b89e002 Andrew Hyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
372 (websocket-outer-filter fake-ws (concat
373 "\r\n\r\n"
374 (substring websocket-frames 0 2)))
078fbf3 Andrew Hyatt Implemented onopen callback. Soon to be renamed.
authored
375 (should open-callback-called)
b89e002 Andrew Hyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
376 (websocket-outer-filter fake-ws (substring websocket-frames 2))
a723952 Andrew Hyatt Fix issue with inflight-input not being cleared out.
authored
377 (should (equal (list frame2 frame1) processed-frames))
378 (should-not (websocket-inflight-input fake-ws)))
4040ae0 Julian Scheid Add test case for bugfix in 8513a7e38d7bf3538d235668ec16081cbd561460.
jscheid authored
379 (flet ((websocket-ready-state (websocket) 'connecting)
380 (websocket-close (websocket)))
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
381 (should (eq 500 (cdr (should-error
382 (websocket-outer-filter fake-ws "HTTP/1.1 500\r\n\r\n")
383 :type 'websocket-received-error-http-response)))))))
6c42988 Andrew Hyatt Check for HTTP 101 response code, and if there is any failure in the
authored
384
385 (ert-deftest websocket-outer-filter-bad-connection ()
386 (let* ((on-open-calledp)
387 (websocket-closed-calledp)
388 (fake-ws (websocket-inner-create
389 :conn t :url t :accept-string t
390 :on-open (lambda (websocket)
391 (setq on-open-calledp t)))))
392 (flet ((websocket-verify-response-code (output) t)
393 (websocket-verify-headers (websocket output) (error "Bad headers!"))
394 (websocket-close (websocket) (setq websocket-closed-calledp t)))
395 (condition-case err
396 (progn (websocket-outer-filter fake-ws "HTTP/1.1 101\r\n\r\n")
397 (error "Should have thrown an error!"))
398 (error
399 (should-not on-open-calledp)
400 (should websocket-closed-calledp))))))
a5f1895 Andrew Hyatt Re-apply the error handling, removed by accident during the merge.
authored
401
d2e4272 Andrew Hyatt Check frame validity, and test it as part of websocket-send
authored
402 (ert-deftest websocket-send ()
fb26aa7 Andrew Hyatt Make the API more like W3C's API.
authored
403 (let ((ws (websocket-inner-create :conn t :url t :accept-string t)))
d2e4272 Andrew Hyatt Check frame validity, and test it as part of websocket-send
authored
404 (flet ((websocket-ensure-connected (websocket))
405 (websocket-openp (websocket) t)
406 (process-send-string (conn string)))
407 ;; Just make sure there is no error.
408 (websocket-send ws (make-websocket-frame :opcode 'ping
409 :completep t)))
410 (should-error (websocket-send ws
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
411 (make-websocket-frame :opcode 'text)))
d2e4272 Andrew Hyatt Check frame validity, and test it as part of websocket-send
authored
412 (should-error (websocket-send ws
413 (make-websocket-frame :opcode 'close
414 :payload "bye!"
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
415 :completep t))
416 :type 'websocket-illegal-frame)
d2e4272 Andrew Hyatt Check frame validity, and test it as part of websocket-send
authored
417 (should-error (websocket-send ws
8904556 Andrew Hyatt Switch from using generic errors, to using named symbols.
authored
418 (make-websocket-frame :opcode :close))
419 :type 'websocket-illegal-frame)))
d2e4272 Andrew Hyatt Check frame validity, and test it as part of websocket-send
authored
420
a98e56f Andrew Hyatt Beginning of server functionality. Completed header checking.
authored
421 (ert-deftest websocket-verify-client-headers ()
422 (let* ((http "HTTP/1.1")
423 (host "Host: authority")
424 (upgrade "Upgrade: websocket")
23b132e Andrew Hyatt Fix failing ert tests
authored
425 (key (format "Sec-Websocket-Key: %s" "key"))
a98e56f Andrew Hyatt Beginning of server functionality. Completed header checking.
authored
426 (version "Sec-Websocket-Version: 13")
427 (origin "Origin: origin")
428 (protocol "Sec-Websocket-Protocol: protocol")
429 (extensions1 "Sec-Websocket-Extensions: foo")
430 (extensions2 "Sec-Websocket-Extensions: bar; baz=2")
431 (all-required-headers (list host upgrade key version)))
432 ;; Test that all these headers are necessary
433 (should (equal
434 '(:key "key" :protocols ("protocol") :extensions ("foo" "bar; baz=2"))
435 (websocket-verify-client-headers
436 (mapconcat 'identity (append (list http "" protocol extensions1 extensions2)
437 all-required-headers) "\r\n"))))
438 (should (websocket-verify-client-headers
439 (mapconcat 'identity
440 (mapcar 'upcase
441 (append (list http "" protocol extensions1 extensions2)
442 all-required-headers)) "\r\n")))
443 (dolist (header all-required-headers)
444 (should-not (websocket-verify-client-headers
445 (mapconcat 'identity (append (list http "")
446 (remove header all-required-headers))
447 "\r\n"))))
448 (should-not (websocket-verify-client-headers
449 (mapconcat 'identity (append (list "HTTP/1.0" "") all-required-headers)
450 "\r\n")))))
451
5a8b995 Andrew Hyatt Add server header generation, and refactor protocol and extension handli...
authored
452 (ert-deftest websocket-intersect ()
453 (should (equal '(2) (websocket-intersect '(1 2) '(2 3))))
454 (should (equal nil (websocket-intersect '(1 2) '(3 4))))
455 (should (equal '(1 2) (websocket-intersect '(1 2) '(1 2)))))
456
457 (ert-deftest websocket-get-server-response ()
458 (let ((ws (websocket-inner-create :conn t :url t :accept-string "key"
459 :protocols '("spa" "spb")
460 :extensions '("sea" "seb"))))
461 (should (equal (concat
462 "HTTP/1.1 101 Switching Protocols\r\n"
463 "Upgrade: websocket\r\n"
464 "Connection: Upgrade\r\n"
465 "Sec-WebSocket-Accept: key\r\n\r\n")
466 (websocket-get-server-response ws nil nil)))
467 (should (string-match "Sec-Websocket-Protocol: spb\r\n"
468 (websocket-get-server-response ws '("spb" "spc") nil)))
469 (should-not (string-match "Sec-Websocket-Protocol:"
470 (websocket-get-server-response ws '("spc") nil)))
471 (let ((output (websocket-get-server-response ws '("spa" "spb") nil)))
472 (should (string-match "Sec-Websocket-Protocol: spa\r\n" output))
473 (should (string-match "Sec-Websocket-Protocol: spb\r\n" output)))
474 (should (string-match "Sec-Websocket-Extensions: sea"
475 (websocket-get-server-response ws nil '("sea" "sec"))))
476 (should-not (string-match "Sec-Websocket-Extensions:"
477 (websocket-get-server-response ws nil '("sec"))))
478 (let ((output (websocket-get-server-response ws nil '("sea" "seb"))))
479 (should (string-match "Sec-Websocket-Extensions: sea\r\n" output))
480 (should (string-match "Sec-Websocket-Extensions: seb\r\n" output)))))
481
0202adc Andrew Hyatt Finish and test the server filter function.
authored
482 (ert-deftest websocket-server-filter ()
483 (let ((on-open-called)
484 (ws (websocket-inner-create :conn t :url t :accept-string "key"
485 :on-open (lambda (ws) (setq on-open-called t))))
486 (closed)
487 (response)
488 (processed))
489 (flet ((process-send-string (p text) (setq response text))
490 (websocket-close (ws) (setq closed t))
491 (process-get (process sym) ws))
492 ;; Bad request, in two parts
23b132e Andrew Hyatt Fix failing ert tests
authored
493 (flet ((websocket-verify-client-headers (text) nil))
0202adc Andrew Hyatt Finish and test the server filter function.
authored
494 (websocket-server-filter nil "HTTP/1.0 GET /foo \r\n")
495 (should-not closed)
496 (websocket-server-filter nil "\r\n")
497 (should (equal response "HTTP/1.1 400 Bad Request\r\n\r\n"))
498 (should-not (websocket-inflight-input ws)))
499 ;; Good request, followed by packet
500 (setq closed nil
501 response nil)
502 (setf (websocket-inflight-input ws) nil)
23b132e Andrew Hyatt Fix failing ert tests
authored
503 (flet ((websocket-verify-client-headers (text) t)
0202adc Andrew Hyatt Finish and test the server filter function.
authored
504 (websocket-get-server-response (ws protocols extensions)
505 "response")
506 (websocket-process-input-on-open-ws (ws text)
507 (setq processed t)
508 (should
509 (equal text websocket-test-hello))))
510 (websocket-server-filter nil
511 (concat "\r\n\r\n" websocket-test-hello))
512 (should (equal (websocket-ready-state ws) 'open))
513 (should-not closed)
514 (should (equal response "response"))
515 (should processed)))))
74d5c10 Andrew Hyatt Fix many issues with server connections.
authored
516
517 (ert-deftest websocket-complete-server-response-test ()
518 ;; Example taken from RFC
519 (should (equal
520 (concat "HTTP/1.1 101 Switching Protocols\r\n"
521 "Upgrade: websocket\r\n"
522 "Connection: Upgrade\r\n"
523 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
524 "Sec-WebSocket-Protocol: chat\r\n\r\n"
525 )
526 (let ((header-info
527 (websocket-verify-client-headers
528 (concat "GET /chat HTTP/1.1\r\n"
529 "Host: server.example.com\r\n"
530 "Upgrade: websocket\r\n"
531 "Connection: Upgrade\r\n"
532 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
533 "Origin: http://example.com\r\n"
534 "Sec-WebSocket-Protocol: chat, superchat\r\n"
535 "Sec-WebSocket-Version: 13\r\n"))))
536 (should header-info)
537 (let ((ws (websocket-inner-create
538 :conn t :url t
539 :accept-string (websocket-calculate-accept
540 (plist-get header-info :key))
541 :protocols '("chat"))))
542 (websocket-get-server-response
543 ws
544 (plist-get header-info :protocols)
545 (plist-get header-info :extension)))))))
5c2b235 Andrew Hyatt Implement proper behavior on closing of server.
authored
546
547 (ert-deftest websocket-server-close ()
548 (let ((websocket-server-websockets
549 (list (websocket-inner-create :conn 'conn-a :url t :accept-string t
550 :server-conn 'a
551 :ready-state 'open)
552 (websocket-inner-create :conn 'conn-b :url t :accept-string t
553 :server-conn 'b
554 :ready-state 'open)
555 (websocket-inner-create :conn 'conn-c :url t :accept-string t
556 :server-conn 'b
557 :ready-state 'closed)))
558 (deleted-processes)
559 (closed-websockets))
560 (flet ((delete-process (conn) (add-to-list 'deleted-processes conn))
561 (websocket-close (ws)
562 ;; we always remove on closing in the
563 ;; actual code.
564 (setq websocket-server-websockets
565 (remove ws websocket-server-websockets))
566 (should-not (eq (websocket-ready-state ws) 'closed))
567 (add-to-list 'closed-websockets ws)))
568 (websocket-server-close 'b))
569 (should (equal deleted-processes '(b)))
570 (should (eq 1 (length closed-websockets)))
571 (should (eq 'conn-b (websocket-conn (car closed-websockets))))
572 (should (eq 1 (length websocket-server-websockets)))
573 (should (eq 'conn-a (websocket-conn (car websocket-server-websockets))))))
Something went wrong with that request. Please try again.