|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <head> |
|
4 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta> |
|
5 <title>WebSocket test</title> |
|
6 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
8 </head> |
|
9 <body onload="testWebSocket()"> |
|
10 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=472529">Mozilla Bug </a> |
|
11 <p id="display"> |
|
12 <input id="fileList" type="file"></input> |
|
13 </p> |
|
14 <div id="content"> |
|
15 </div> |
|
16 <pre id="test"> |
|
17 <script class="testbody" type="text/javascript"> |
|
18 |
|
19 /* |
|
20 * tests: |
|
21 * 1. client tries to connect to a http scheme location; |
|
22 * 2. assure serialization of the connections; |
|
23 * 3. client tries to connect to an non-existent ws server; |
|
24 * 4. client tries to connect using a relative url; |
|
25 * 5. client uses an invalid protocol value; |
|
26 * 6. counter and encoding check; |
|
27 * 7. onmessage event origin property check |
|
28 * 8. client calls close() and the server sends the close frame (with no code |
|
29 * or reason) in acknowledgement; |
|
30 * 9. client closes the connection before the ws connection is established; |
|
31 * 10. client sends a message before the ws connection is established; |
|
32 * 11. a simple hello echo; |
|
33 * 12. client sends a message containing unpaired surrogates |
|
34 * 13. server sends an invalid message; |
|
35 * 14. server sends the close frame, it doesn't close the tcp connection and |
|
36 * it keeps sending normal ws messages; |
|
37 * 15. server closes the tcp connection, but it doesn't send the close frame; |
|
38 * 16. client calls close() and tries to send a message; |
|
39 * 17. see bug 572975 - all event listeners set |
|
40 * 18. client tries to connect to an http resource; |
|
41 * 19. server closes the tcp connection before establishing the ws connection; |
|
42 * 20. see bug 572975 - only on error and onclose event listeners set |
|
43 * 21. see bug 572975 - same as test 17, but delete strong event listeners when |
|
44 * receiving the message event; |
|
45 * 22. server takes too long to establish the ws connection; |
|
46 * 23. should detect WebSocket on window object; |
|
47 * 24. server rejects sub-protocol string |
|
48 * 25. ctor with valid empty sub-protocol array |
|
49 * 26. ctor with invalid sub-protocol array containing 1 empty element |
|
50 * 27. ctor with invalid sub-protocol array containing an empty element in list |
|
51 * 28. ctor using valid 1 element sub-protocol array |
|
52 * 29. ctor using all valid 5 element sub-protocol array |
|
53 * 30. ctor using valid 1 element sub-protocol array with element server will |
|
54 * reject |
|
55 * 31. ctor using valid 2 element sub-protocol array with 1 element server |
|
56 * will reject and one server will accept. |
|
57 * 32. ctor using invalid sub-protocol array that contains duplicate items |
|
58 * 33. test for sending/receiving custom close code (but no close reason) |
|
59 * 34. test for receiving custom close code and reason |
|
60 * 35. test for sending custom close code and reason |
|
61 * 36. negative test for sending out of range close code |
|
62 * 37. negative test for too long of a close reason |
|
63 * 38. ensure extensions attribute is defined |
|
64 * 39. a basic wss:// connectivity test |
|
65 * 40. negative test for wss:// with no cert |
|
66 * 41. HSTS |
|
67 * 42. non-char utf-8 sequences |
|
68 * 43. Test setting binaryType attribute |
|
69 * 44. Test sending/receving binary ArrayBuffer |
|
70 * 45. Test sending/receving binary Blob |
|
71 * 46. Test that we don't dispatch incoming msgs once in CLOSING state |
|
72 * 47. Make sure onerror/onclose aren't called during close() |
|
73 */ |
|
74 |
|
75 var first_test = 1; |
|
76 var last_test = 47; |
|
77 |
|
78 |
|
79 // Set this to >1 if you want to run the suite multiple times to probe for |
|
80 // random orange failures. |
|
81 // - Do NOT check into mozilla-central with a value != 1. |
|
82 // - Too large a count will wind up causing tryserver to timeout the test (which |
|
83 // is ok, but means all testruns will be orange). If I set first_test to >22 |
|
84 // (i.e don't run any of the tests that require waiting) I can get ~250-300 |
|
85 // iterations of the remaining tests w/o a timeout. |
|
86 var testsuite_iterations = 1; |
|
87 |
|
88 |
|
89 var current_test = first_test; |
|
90 var testsuite_iteration = 1; |
|
91 |
|
92 var test_started = new Array(last_test); |
|
93 var all_ws = []; |
|
94 |
|
95 function shouldNotOpen(e) |
|
96 { |
|
97 var ws = e.target; |
|
98 ok(false, "onopen shouldn't be called on test " + ws._testNumber + "!"); |
|
99 } |
|
100 |
|
101 function shouldNotReceiveCloseEvent(e) |
|
102 { |
|
103 var ws = e.target; |
|
104 var extendedErrorInfo = ""; |
|
105 if (!ws._testNumber) { |
|
106 extendedErrorInfo += "\nws members:\n"; |
|
107 for (var i in ws) { |
|
108 extendedErrorInfo += (i + ": " + ws[i] + "\n"); |
|
109 } |
|
110 |
|
111 extendedErrorInfo += "\ne members:\n"; |
|
112 for (var i in e) { |
|
113 extendedErrorInfo += (i + ": " + e[i] + "\n"); |
|
114 } |
|
115 } |
|
116 |
|
117 // FIXME: see bug 578276. This should be a test failure, but it's too flaky on the tbox. |
|
118 ok(true, "onclose shouldn't be called on test " + ws._testNumber + "!" + extendedErrorInfo); |
|
119 } |
|
120 |
|
121 function shouldCloseCleanly(e) |
|
122 { |
|
123 var ws = e.target; |
|
124 ok(e.wasClean, "the ws connection in test " + ws._testNumber + " should be closed cleanly"); |
|
125 } |
|
126 |
|
127 function shouldCloseNotCleanly(e) |
|
128 { |
|
129 var ws = e.target; |
|
130 ok(!e.wasClean, "the ws connection in test " + ws._testNumber + " shouldn't be closed cleanly"); |
|
131 } |
|
132 |
|
133 function ignoreError(e) |
|
134 { |
|
135 } |
|
136 |
|
137 function CreateTestWS(ws_location, ws_protocol, no_increment_test) |
|
138 { |
|
139 var ws; |
|
140 |
|
141 try { |
|
142 if (ws_protocol == undefined) { |
|
143 ws = new WebSocket(ws_location); |
|
144 } else { |
|
145 ws = new WebSocket(ws_location, ws_protocol); |
|
146 } |
|
147 |
|
148 |
|
149 ws._testNumber = current_test; |
|
150 ws._receivedCloseEvent = false; |
|
151 ok(true, "Created websocket for test " + ws._testNumber +"\n"); |
|
152 |
|
153 ws.onerror = function(e) |
|
154 { |
|
155 ok(false, "onerror called on test " + e.target._testNumber + "!"); |
|
156 }; |
|
157 ws.addEventListener("close", function(e) |
|
158 { |
|
159 ws._receivedCloseEvent = true; |
|
160 }, false); |
|
161 } |
|
162 catch (e) { |
|
163 throw e; |
|
164 } |
|
165 finally { |
|
166 if (!no_increment_test) { |
|
167 current_test++; |
|
168 } |
|
169 } |
|
170 |
|
171 all_ws.push(ws); |
|
172 return ws; |
|
173 } |
|
174 |
|
175 function forcegc() |
|
176 { |
|
177 SpecialPowers.forceGC(); |
|
178 SpecialPowers.gc(); |
|
179 setTimeout(function() |
|
180 { |
|
181 SpecialPowers.gc(); |
|
182 }, 1); |
|
183 } |
|
184 |
|
185 function doTest(number) |
|
186 { |
|
187 if (number > last_test) { |
|
188 ranAllTests = true; |
|
189 maybeFinished(); |
|
190 return; |
|
191 } |
|
192 |
|
193 if (testsuite_iteration > 1) { |
|
194 $("feedback").innerHTML = "test suite iteration #" + testsuite_iteration + " of " + testsuite_iterations + |
|
195 ": executing test: " + number + " of " + last_test + " tests."; |
|
196 } else { |
|
197 $("feedback").innerHTML = "executing test: " + number + " of " + last_test + " tests."; |
|
198 } |
|
199 |
|
200 var fnTest = eval("test" + number + ""); |
|
201 |
|
202 if (test_started[number] === true) { |
|
203 doTest(number + 1); |
|
204 return; |
|
205 } |
|
206 |
|
207 test_started[number] = true; |
|
208 fnTest(); |
|
209 } |
|
210 doTest.timeoutId = null; |
|
211 |
|
212 function test1() |
|
213 { |
|
214 try { |
|
215 var ws = CreateTestWS("http://mochi.test:8888/tests/content/base/test/file_websocket"); |
|
216 ok(false, "test1 failed"); |
|
217 } |
|
218 catch (e) { |
|
219 ok(true, "test1 failed"); |
|
220 } |
|
221 doTest(2); |
|
222 } |
|
223 |
|
224 // this test expects that the serialization list to connect to the proxy |
|
225 // is empty. Use different domain so we can run this in the background |
|
226 // and not delay other tests. |
|
227 |
|
228 var waitTest2Part1 = false; |
|
229 var waitTest2Part2 = false; |
|
230 |
|
231 function test2() |
|
232 { |
|
233 waitTest2Part1 = true; |
|
234 waitTest2Part2 = true; |
|
235 |
|
236 var ws1 = CreateTestWS("ws://sub2.test2.example.com/tests/content/base/test/file_websocket", "test-2.1"); |
|
237 current_test--; // CreateTestWS incremented this |
|
238 var ws2 = CreateTestWS("ws://sub2.test2.example.com/tests/content/base/test/file_websocket", "test-2.2"); |
|
239 |
|
240 var ws2CanConnect = false; |
|
241 |
|
242 // the server will delay ws1 for 5 seconds, but the other tests can |
|
243 // proceed in parallel |
|
244 doTest(3); |
|
245 |
|
246 ws1.onopen = function() |
|
247 { |
|
248 ok(true, "ws1 open in test 2"); |
|
249 ws2CanConnect = true; |
|
250 ws1.close(); |
|
251 } |
|
252 |
|
253 ws1.onclose = function(e) |
|
254 { |
|
255 waitTest2Part1 = false; |
|
256 maybeFinished(); |
|
257 }; |
|
258 |
|
259 ws2.onopen = function() |
|
260 { |
|
261 ok(ws2CanConnect, "shouldn't connect yet in test-2!"); |
|
262 ws2.close(); |
|
263 } |
|
264 |
|
265 ws2.onclose = function(e) |
|
266 { |
|
267 waitTest2Part2 = false; |
|
268 maybeFinished(); |
|
269 }; |
|
270 } |
|
271 |
|
272 function test3() |
|
273 { |
|
274 var hasError = false; |
|
275 var ws = CreateTestWS("ws://this.websocket.server.probably.does.not.exist"); |
|
276 ws.onopen = shouldNotOpen; |
|
277 ws.onerror = function (e) |
|
278 { |
|
279 hasError = true; |
|
280 } |
|
281 |
|
282 ws.onclose = function(e) |
|
283 { |
|
284 shouldCloseNotCleanly(e); |
|
285 ok(hasError, "rcvd onerror event"); |
|
286 ok(e.code == 1006, "test-3 close code should be 1006 but is:" + e.code); |
|
287 doTest(4); |
|
288 }; |
|
289 } |
|
290 |
|
291 function test4() |
|
292 { |
|
293 try { |
|
294 var ws = CreateTestWS("file_websocket"); |
|
295 ok(false, "test-4 failed"); |
|
296 } |
|
297 catch (e) { |
|
298 ok(true, "test-4 failed"); |
|
299 } |
|
300 doTest(5); |
|
301 } |
|
302 |
|
303 function test5() |
|
304 { |
|
305 try { |
|
306 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", ""); |
|
307 ok(false, "couldn't accept an empty string in the protocol parameter"); |
|
308 } |
|
309 catch (e) { |
|
310 ok(true, "couldn't accept an empty string in the protocol parameter"); |
|
311 } |
|
312 current_test--; // CreateTestWS incremented this |
|
313 try { |
|
314 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "\n"); |
|
315 ok(false, "couldn't accept any not printable ASCII character in the protocol parameter"); |
|
316 } |
|
317 catch (e) { |
|
318 ok(true, "couldn't accept any not printable ASCII character in the protocol parameter"); |
|
319 } |
|
320 current_test--; // CreateTestWS incremented this |
|
321 try { |
|
322 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 5"); |
|
323 ok(false, "U+0020 not acceptable in protocol parameter"); |
|
324 } |
|
325 catch (e) { |
|
326 ok(true, "U+0020 not acceptable in protocol parameter"); |
|
327 } |
|
328 doTest(6); |
|
329 } |
|
330 |
|
331 function test6() |
|
332 { |
|
333 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-6"); |
|
334 var counter = 1; |
|
335 ws.onopen = function() |
|
336 { |
|
337 ws.send(counter); |
|
338 } |
|
339 ws.onmessage = function(e) |
|
340 { |
|
341 if (counter == 5) { |
|
342 ok(e.data == "あいうえお", "test-6 counter 5 data ok"); |
|
343 ws.close(); |
|
344 } else { |
|
345 ok(e.data == counter+1, "bad counter"); |
|
346 counter += 2; |
|
347 ws.send(counter); |
|
348 } |
|
349 } |
|
350 ws.onclose = function(e) |
|
351 { |
|
352 shouldCloseCleanly(e); |
|
353 doTest(7); |
|
354 }; |
|
355 } |
|
356 |
|
357 function test7() |
|
358 { |
|
359 var ws = CreateTestWS("ws://sub2.test2.example.org/tests/content/base/test/file_websocket", "test-7"); |
|
360 var gotmsg = false; |
|
361 |
|
362 ws.onopen = function() |
|
363 { |
|
364 ok(true, "test 7 open"); |
|
365 } |
|
366 ws.onmessage = function(e) |
|
367 { |
|
368 ok(true, "test 7 message"); |
|
369 ok(e.origin == "ws://sub2.test2.example.org", "onmessage origin set to ws:// host"); |
|
370 gotmsg = true; |
|
371 ws.close(); |
|
372 } |
|
373 ws.onclose = function(e) |
|
374 { |
|
375 ok(gotmsg, "recvd message in test 7 before close"); |
|
376 shouldCloseCleanly(e); |
|
377 doTest(8); |
|
378 }; |
|
379 } |
|
380 |
|
381 function test8() |
|
382 { |
|
383 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-8"); |
|
384 ws.onopen = function() |
|
385 { |
|
386 ok(ws.protocol == "test-8", "test-8 subprotocol selection"); |
|
387 ws.close(); |
|
388 } |
|
389 ws.onclose = function(e) |
|
390 { |
|
391 shouldCloseCleanly(e); |
|
392 // We called close() with no close code: so pywebsocket will also send no |
|
393 // close code, which translates to code 1005 |
|
394 ok(e.code == 1005, "test-8 close code has wrong value:" + e.code); |
|
395 ok(e.reason == "", "test-8 close reason has wrong value:" + e.reason); |
|
396 doTest(9); |
|
397 }; |
|
398 } |
|
399 |
|
400 var waitTest9 = false; |
|
401 |
|
402 function test9() |
|
403 { |
|
404 waitTest9 = true; |
|
405 |
|
406 var ws = CreateTestWS("ws://test2.example.org/tests/content/base/test/file_websocket", "test-9"); |
|
407 ws._receivedErrorEvent = false; |
|
408 ws.onopen = shouldNotOpen; |
|
409 ws.onerror = function(e) |
|
410 { |
|
411 ws._receivedErrorEvent = true; |
|
412 }; |
|
413 ws.onclose = function(e) |
|
414 { |
|
415 ok(ws._receivedErrorEvent, "Didn't received the error event in test 9."); |
|
416 shouldCloseNotCleanly(e); |
|
417 waitTest9 = false; |
|
418 maybeFinished(); |
|
419 }; |
|
420 |
|
421 ws.close(); |
|
422 |
|
423 // the server injects a delay, so proceed with this in the background |
|
424 doTest(10); |
|
425 } |
|
426 |
|
427 var waitTest10 = false; |
|
428 |
|
429 function test10() |
|
430 { |
|
431 waitTest10 = true; |
|
432 |
|
433 var ws = CreateTestWS("ws://sub1.test1.example.com/tests/content/base/test/file_websocket", "test-10"); |
|
434 ws.onclose = function(e) |
|
435 { |
|
436 shouldCloseCleanly(e); |
|
437 waitTest10 = false; |
|
438 maybeFinished(); |
|
439 } |
|
440 |
|
441 try { |
|
442 ws.send("client data"); |
|
443 ok(false, "Couldn't send data before connecting!"); |
|
444 } |
|
445 catch (e) { |
|
446 ok(true, "Couldn't send data before connecting!"); |
|
447 } |
|
448 ws.onopen = function() |
|
449 { |
|
450 ok(true, "test 10 opened"); |
|
451 ws.close(); |
|
452 } |
|
453 |
|
454 // proceed with this test in the background |
|
455 doTest(11); |
|
456 } |
|
457 |
|
458 function test11() |
|
459 { |
|
460 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-11"); |
|
461 ok(ws.readyState == 0, "create bad readyState in test-11!"); |
|
462 ws.onopen = function() |
|
463 { |
|
464 ok(ws.readyState == 1, "open bad readyState in test-11!"); |
|
465 ws.send("client data"); |
|
466 } |
|
467 ws.onmessage = function(e) |
|
468 { |
|
469 ok(e.data == "server data", "bad received message in test-11!"); |
|
470 ws.close(1000, "Have a nice day"); |
|
471 |
|
472 // this ok() is disabled due to a race condition - it state may have |
|
473 // advanced through 2 (closing) and into 3 (closed) before it is evald |
|
474 // ok(ws.readyState == 2, "onmessage bad readyState in test-11!"); |
|
475 } |
|
476 ws.onclose = function(e) |
|
477 { |
|
478 ok(ws.readyState == 3, "onclose bad readyState in test-11!"); |
|
479 shouldCloseCleanly(e); |
|
480 ok(e.code == 1000, "test 11 got wrong close code: " + e.code); |
|
481 ok(e.reason == "Have a nice day", "test 11 got wrong close reason: " + e.reason); |
|
482 doTest(12); |
|
483 } |
|
484 } |
|
485 |
|
486 function test12() |
|
487 { |
|
488 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-12"); |
|
489 ws.onopen = function() |
|
490 { |
|
491 try { |
|
492 // send an unpaired surrogate |
|
493 ws._gotMessage = false; |
|
494 ws.send("a\ud800b"); |
|
495 ok(true, "ok to send an unpaired surrogate"); |
|
496 } |
|
497 catch (e) { |
|
498 ok(false, "shouldn't fail any more when sending an unpaired surrogate!"); |
|
499 } |
|
500 } |
|
501 |
|
502 ws.onmessage = function(msg) |
|
503 { |
|
504 ok(msg.data == "SUCCESS", "Unpaired surrogate in UTF-16 not converted in test-12"); |
|
505 ws._gotMessage = true; |
|
506 // Must support unpaired surrogates in close reason, too |
|
507 ws.close(1000, "a\ud800b"); |
|
508 } |
|
509 |
|
510 ws.onclose = function(e) |
|
511 { |
|
512 ok(ws.readyState == 3, "onclose bad readyState in test-12!"); |
|
513 ok(ws._gotMessage, "didn't receive message!"); |
|
514 shouldCloseCleanly(e); |
|
515 ok(e.code == 1000, "test 12 got wrong close code: " + e.code); |
|
516 ok(e.reason == "a\ufffdb", "test 11 didn't get replacement char in close reason: " + e.reason); |
|
517 doTest(13); |
|
518 } |
|
519 } |
|
520 |
|
521 function test13() |
|
522 { |
|
523 // previous versions of this test counted the number of protocol errors returned, but the |
|
524 // protocol stack typically closes down after reporting a protocol level error - trying |
|
525 // to resync is too dangerous |
|
526 |
|
527 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-13"); |
|
528 ws._timesCalledOnError = 0; |
|
529 ws.onerror = function() |
|
530 { |
|
531 ws._timesCalledOnError++; |
|
532 } |
|
533 ws.onclose = function(e) |
|
534 { |
|
535 ok(ws._timesCalledOnError > 0, "no error events"); |
|
536 doTest(14); |
|
537 } |
|
538 } |
|
539 |
|
540 function test14() |
|
541 { |
|
542 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-14"); |
|
543 ws.onmessage = function() |
|
544 { |
|
545 ok(false, "shouldn't received message after the server sent the close frame"); |
|
546 } |
|
547 ws.onclose = function(e) |
|
548 { |
|
549 shouldCloseCleanly(e); |
|
550 // Skip test 15 for now: broken |
|
551 doTest(16); |
|
552 }; |
|
553 } |
|
554 |
|
555 /* |
|
556 * DISABLED: see comments for test-15 case in file_websocket_wsh.py |
|
557 * |
|
558 function test15() |
|
559 { |
|
560 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-15"); |
|
561 ws.onclose = function(e) |
|
562 { |
|
563 shouldCloseNotCleanly(e); |
|
564 doTest(16); |
|
565 }; |
|
566 |
|
567 // termination of the connection might cause an error event if it happens in OPEN |
|
568 ws.onerror = function() |
|
569 { |
|
570 } |
|
571 |
|
572 } |
|
573 */ |
|
574 |
|
575 function test16() |
|
576 { |
|
577 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-16"); |
|
578 ws.onopen = function() |
|
579 { |
|
580 ws.close(); |
|
581 ok(!ws.send("client data"), "shouldn't send message after calling close()"); |
|
582 } |
|
583 ws.onmessage = function() |
|
584 { |
|
585 ok(false, "shouldn't send message after calling close()"); |
|
586 } |
|
587 |
|
588 ws.onerror = function() |
|
589 { |
|
590 } |
|
591 ws.onclose = function() |
|
592 { |
|
593 doTest(17); |
|
594 } |
|
595 } |
|
596 |
|
597 var status_test17 = "not started"; |
|
598 |
|
599 var waitTest17 = false; |
|
600 |
|
601 var test17func = function() |
|
602 { |
|
603 waitTest17 = true; |
|
604 |
|
605 var local_ws = new WebSocket("ws://sub1.test2.example.org/tests/content/base/test/file_websocket", "test-17"); |
|
606 local_ws._testNumber = "local17"; |
|
607 local_ws._testNumber = current_test++; |
|
608 |
|
609 status_test17 = "started"; |
|
610 |
|
611 local_ws.onopen = function(e) |
|
612 { |
|
613 status_test17 = "opened"; |
|
614 e.target.send("client data"); |
|
615 forcegc(); |
|
616 }; |
|
617 |
|
618 local_ws.onerror = function() |
|
619 { |
|
620 ok(false, "onerror called on test " + e.target._testNumber + "!"); |
|
621 }; |
|
622 |
|
623 local_ws.onmessage = function(e) |
|
624 { |
|
625 ok(e.data == "server data", "Bad message in test-17"); |
|
626 status_test17 = "got message"; |
|
627 forcegc(); |
|
628 }; |
|
629 |
|
630 local_ws.onclose = function(e) |
|
631 { |
|
632 ok(status_test17 == "got message", "Didn't got message in test-17!"); |
|
633 shouldCloseCleanly(e); |
|
634 status_test17 = "closed"; |
|
635 forcegc(); |
|
636 waitTest17 = false; |
|
637 maybeFinished(); |
|
638 }; |
|
639 |
|
640 local_ws = null; |
|
641 window._test17 = null; |
|
642 forcegc(); |
|
643 |
|
644 // do this in the background |
|
645 doTest(18); |
|
646 forcegc(); |
|
647 } |
|
648 |
|
649 function test17() |
|
650 { |
|
651 window._test17 = test17func; |
|
652 window._test17(); |
|
653 } |
|
654 |
|
655 // The tests that expects that their websockets neither open nor close MUST |
|
656 // be in the end of the tests, i.e. HERE, in order to prevent blocking the other |
|
657 // tests. |
|
658 |
|
659 function test18() |
|
660 { |
|
661 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket_http_resource.txt"); |
|
662 ws.onopen = shouldNotOpen; |
|
663 ws.onerror = ignoreError; |
|
664 ws.onclose = function(e) |
|
665 { |
|
666 shouldCloseNotCleanly(e); |
|
667 doTest(19); |
|
668 }; |
|
669 } |
|
670 |
|
671 function test19() |
|
672 { |
|
673 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-19"); |
|
674 ws.onopen = shouldNotOpen; |
|
675 ws.onerror = ignoreError; |
|
676 ws.onclose = function(e) |
|
677 { |
|
678 shouldCloseNotCleanly(e); |
|
679 doTest(20); |
|
680 }; |
|
681 } |
|
682 |
|
683 var waitTest20 = false; |
|
684 |
|
685 var test20func = function() |
|
686 { |
|
687 waitTest20 = true; |
|
688 |
|
689 var local_ws = new WebSocket("ws://sub1.test1.example.org/tests/content/base/test/file_websocket", "test-20"); |
|
690 local_ws._testNumber = "local20"; |
|
691 local_ws._testNumber = current_test++; |
|
692 |
|
693 local_ws.onerror = function() |
|
694 { |
|
695 ok(false, "onerror called on test " + e.target._testNumber + "!"); |
|
696 }; |
|
697 |
|
698 local_ws.onclose = function(e) |
|
699 { |
|
700 ok(true, "test 20 closed despite gc"); |
|
701 waitTest20 = false; |
|
702 maybeFinished(); |
|
703 }; |
|
704 |
|
705 local_ws = null; |
|
706 window._test20 = null; |
|
707 forcegc(); |
|
708 |
|
709 // let test run in the background |
|
710 doTest(21); |
|
711 } |
|
712 |
|
713 function test20() |
|
714 { |
|
715 window._test20 = test20func; |
|
716 window._test20(); |
|
717 } |
|
718 |
|
719 var waitTest21 = false; |
|
720 |
|
721 test21func = function() |
|
722 { |
|
723 waitTest21 = true; |
|
724 |
|
725 var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-21"); |
|
726 local_ws._testNumber = current_test++; |
|
727 var received_message = false; |
|
728 |
|
729 local_ws.onopen = function(e) |
|
730 { |
|
731 e.target.send("client data"); |
|
732 forcegc(); |
|
733 e.target.onopen = null; |
|
734 forcegc(); |
|
735 }; |
|
736 |
|
737 local_ws.onerror = function() |
|
738 { |
|
739 ok(false, "onerror called on test " + e.target._testNumber + "!"); |
|
740 }; |
|
741 |
|
742 local_ws.onmessage = function(e) |
|
743 { |
|
744 ok(e.data == "server data", "Bad message in test-21"); |
|
745 received_message = true; |
|
746 forcegc(); |
|
747 e.target.onmessage = null; |
|
748 forcegc(); |
|
749 }; |
|
750 |
|
751 local_ws.onclose = function(e) |
|
752 { |
|
753 shouldCloseCleanly(e); |
|
754 ok(received_message, "close transitioned through onmessage"); |
|
755 waitTest21 = false; |
|
756 maybeFinished(); |
|
757 }; |
|
758 |
|
759 local_ws = null; |
|
760 window._test21 = null; |
|
761 forcegc(); |
|
762 |
|
763 doTest(22); |
|
764 |
|
765 } |
|
766 |
|
767 function test21() |
|
768 { |
|
769 window._test21 = test21func; |
|
770 window._test21(); |
|
771 } |
|
772 |
|
773 var waitTest22 = false; |
|
774 |
|
775 function test22() |
|
776 { |
|
777 waitTest22 = true; |
|
778 |
|
779 const pref_open = "network.websocket.timeout.open"; |
|
780 SpecialPowers.setIntPref(pref_open, 5); |
|
781 |
|
782 var ws = CreateTestWS("ws://sub2.test2.example.org/tests/content/base/test/file_websocket", "test-22"); |
|
783 ws.onopen = shouldNotOpen; |
|
784 ws.onerror = ignoreError; |
|
785 ws.onclose = function(e) |
|
786 { |
|
787 shouldCloseNotCleanly(e); |
|
788 waitTest22 = false; |
|
789 maybeFinished(); |
|
790 }; |
|
791 |
|
792 SpecialPowers.clearUserPref(pref_open); |
|
793 doTest(23); |
|
794 } |
|
795 |
|
796 function test23() |
|
797 { |
|
798 current_test++; |
|
799 is(true, "WebSocket" in window, "WebSocket should be available on window object"); |
|
800 doTest(24); |
|
801 } |
|
802 |
|
803 function test24() |
|
804 { |
|
805 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-does-not-exist"); |
|
806 ws.onopen = shouldNotOpen; |
|
807 ws.onclose = function(e) |
|
808 { |
|
809 shouldCloseNotCleanly(e); |
|
810 doTest(25); |
|
811 }; |
|
812 ws.onerror = function() |
|
813 { |
|
814 } |
|
815 } |
|
816 |
|
817 function test25() |
|
818 { |
|
819 var prots=[]; |
|
820 |
|
821 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
822 |
|
823 // This test errors because the server requires a sub-protocol, but |
|
824 // the test just wants to ensure that the ctor doesn't generate an |
|
825 // exception |
|
826 ws.onerror = ignoreError; |
|
827 ws.onopen = shouldNotOpen; |
|
828 |
|
829 ws.onclose = function(e) |
|
830 { |
|
831 ok(ws.protocol == "", "test25 subprotocol selection"); |
|
832 ok(true, "test 25 protocol array close"); |
|
833 doTest(26); |
|
834 }; |
|
835 } |
|
836 |
|
837 function test26() |
|
838 { |
|
839 var prots=[""]; |
|
840 |
|
841 try { |
|
842 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
843 ok(false, "testing empty element sub protocol array"); |
|
844 } |
|
845 catch (e) { |
|
846 ok(true, "testing empty sub element protocol array"); |
|
847 } |
|
848 doTest(27); |
|
849 } |
|
850 |
|
851 function test27() |
|
852 { |
|
853 var prots=["test27", ""]; |
|
854 |
|
855 try { |
|
856 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
857 ok(false, "testing empty element mixed sub protocol array"); |
|
858 } |
|
859 catch (e) { |
|
860 ok(true, "testing empty element mixed sub protocol array"); |
|
861 } |
|
862 doTest(28); |
|
863 } |
|
864 |
|
865 function test28() |
|
866 { |
|
867 var prots=["test28"]; |
|
868 |
|
869 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
870 ws.onopen = function(e) |
|
871 { |
|
872 ok(true, "test 28 protocol array open"); |
|
873 ws.close(); |
|
874 }; |
|
875 |
|
876 ws.onclose = function(e) |
|
877 { |
|
878 ok(ws.protocol == "test28", "test28 subprotocol selection"); |
|
879 ok(true, "test 28 protocol array close"); |
|
880 doTest(29); |
|
881 }; |
|
882 } |
|
883 |
|
884 function test29() |
|
885 { |
|
886 var prots=["test29a", "test29b"]; |
|
887 |
|
888 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
889 ws.onopen = function(e) |
|
890 { |
|
891 ok(true, "test 29 protocol array open"); |
|
892 ws.close(); |
|
893 }; |
|
894 |
|
895 ws.onclose = function(e) |
|
896 { |
|
897 ok(true, "test 29 protocol array close"); |
|
898 doTest(30); |
|
899 }; |
|
900 } |
|
901 |
|
902 function test30() |
|
903 { |
|
904 var prots=["test-does-not-exist"]; |
|
905 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
906 |
|
907 ws.onopen = shouldNotOpen; |
|
908 ws.onclose = function(e) |
|
909 { |
|
910 shouldCloseNotCleanly(e); |
|
911 doTest(31); |
|
912 }; |
|
913 ws.onerror = function() |
|
914 { |
|
915 } |
|
916 } |
|
917 |
|
918 function test31() |
|
919 { |
|
920 var prots=["test-does-not-exist", "test31"]; |
|
921 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
922 |
|
923 ws.onopen = function(e) |
|
924 { |
|
925 ok(true, "test 31 protocol array open"); |
|
926 ws.close(); |
|
927 }; |
|
928 |
|
929 ws.onclose = function(e) |
|
930 { |
|
931 ok(ws.protocol == "test31", "test31 subprotocol selection"); |
|
932 ok(true, "test 31 protocol array close"); |
|
933 doTest(32); |
|
934 }; |
|
935 } |
|
936 |
|
937 function test32() |
|
938 { |
|
939 var prots=["test32","test32"]; |
|
940 |
|
941 try { |
|
942 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
943 ok(false, "testing duplicated element sub protocol array"); |
|
944 } |
|
945 catch (e) { |
|
946 ok(true, "testing duplicated sub element protocol array"); |
|
947 } |
|
948 doTest(33); |
|
949 } |
|
950 |
|
951 function test33() |
|
952 { |
|
953 var prots=["test33"]; |
|
954 |
|
955 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
956 ws.onopen = function(e) |
|
957 { |
|
958 ok(true, "test 33 open"); |
|
959 ws.close(3131); // pass code but not reason |
|
960 }; |
|
961 |
|
962 ws.onclose = function(e) |
|
963 { |
|
964 ok(true, "test 33 close"); |
|
965 shouldCloseCleanly(e); |
|
966 ok(e.code == 3131, "test 33 got wrong close code: " + e.code); |
|
967 ok(e.reason === "", "test 33 got wrong close reason: " + e.reason); |
|
968 doTest(34); |
|
969 }; |
|
970 } |
|
971 |
|
972 function test34() |
|
973 { |
|
974 var prots=["test-34"]; |
|
975 |
|
976 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
977 ws.onopen = function(e) |
|
978 { |
|
979 ok(true, "test 34 open"); |
|
980 ws.close(); |
|
981 }; |
|
982 |
|
983 ws.onclose = function(e) |
|
984 { |
|
985 ok(true, "test 34 close"); |
|
986 ok(e.wasClean, "test 34 closed cleanly"); |
|
987 ok(e.code == 1001, "test 34 custom server code"); |
|
988 ok(e.reason == "going away now", "test 34 custom server reason"); |
|
989 doTest(35); |
|
990 }; |
|
991 } |
|
992 |
|
993 function test35() |
|
994 { |
|
995 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-35a"); |
|
996 |
|
997 ws.onopen = function(e) |
|
998 { |
|
999 ok(true, "test 35a open"); |
|
1000 ws.close(3500, "my code"); |
|
1001 }; |
|
1002 |
|
1003 ws.onclose = function(e) |
|
1004 { |
|
1005 ok(true, "test 35a close"); |
|
1006 ok(e.wasClean, "test 35a closed cleanly"); |
|
1007 current_test--; // CreateTestWS for 35a incremented this |
|
1008 var wsb = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-35b"); |
|
1009 |
|
1010 wsb.onopen = function(e) |
|
1011 { |
|
1012 ok(true, "test 35b open"); |
|
1013 wsb.close(); |
|
1014 }; |
|
1015 |
|
1016 wsb.onclose = function(e) |
|
1017 { |
|
1018 ok(true, "test 35b close"); |
|
1019 ok(e.wasClean, "test 35b closed cleanly"); |
|
1020 ok(e.code == 3501, "test 35 custom server code"); |
|
1021 ok(e.reason == "my code", "test 35 custom server reason"); |
|
1022 doTest(36); |
|
1023 }; |
|
1024 } |
|
1025 } |
|
1026 |
|
1027 function test36() |
|
1028 { |
|
1029 var prots=["test-36"]; |
|
1030 |
|
1031 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
1032 ws.onopen = function(e) |
|
1033 { |
|
1034 ok(true, "test 36 open"); |
|
1035 |
|
1036 try { |
|
1037 ws.close(13200); |
|
1038 ok(false, "testing custom close code out of range"); |
|
1039 } |
|
1040 catch (e) { |
|
1041 ok(true, "testing custom close code out of range"); |
|
1042 ws.close(3200); |
|
1043 } |
|
1044 }; |
|
1045 |
|
1046 ws.onclose = function(e) |
|
1047 { |
|
1048 ok(true, "test 36 close"); |
|
1049 ok(e.wasClean, "test 36 closed cleanly"); |
|
1050 doTest(37); |
|
1051 }; |
|
1052 } |
|
1053 |
|
1054 function test37() |
|
1055 { |
|
1056 var prots=["test-37"]; |
|
1057 |
|
1058 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
1059 ws.onopen = function(e) |
|
1060 { |
|
1061 ok(true, "test 37 open"); |
|
1062 |
|
1063 try { |
|
1064 ws.close(3100,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"); |
|
1065 ok(false, "testing custom close reason out of range"); |
|
1066 } |
|
1067 catch (e) { |
|
1068 ok(true, "testing custom close reason out of range"); |
|
1069 ws.close(3100,"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"); |
|
1070 } |
|
1071 }; |
|
1072 |
|
1073 ws.onclose = function(e) |
|
1074 { |
|
1075 ok(true, "test 37 close"); |
|
1076 ok(e.wasClean, "test 37 closed cleanly"); |
|
1077 |
|
1078 current_test--; // CreateTestWS for 37 incremented this |
|
1079 var wsb = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-37b"); |
|
1080 |
|
1081 wsb.onopen = function(e) |
|
1082 { |
|
1083 // now test that a rejected close code and reason dont persist |
|
1084 ok(true, "test 37b open"); |
|
1085 try { |
|
1086 wsb.close(3101,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"); |
|
1087 ok(false, "testing custom close reason out of range 37b"); |
|
1088 } |
|
1089 catch (e) { |
|
1090 ok(true, "testing custom close reason out of range 37b"); |
|
1091 wsb.close(); |
|
1092 } |
|
1093 } |
|
1094 |
|
1095 wsb.onclose = function(e) |
|
1096 { |
|
1097 ok(true, "test 37b close"); |
|
1098 ok(e.wasClean, "test 37b closed cleanly"); |
|
1099 |
|
1100 current_test--; // CreateTestWS for 37 incremented this |
|
1101 var wsc = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-37c"); |
|
1102 |
|
1103 wsc.onopen = function(e) |
|
1104 { |
|
1105 ok(true, "test 37c open"); |
|
1106 wsc.close(); |
|
1107 } |
|
1108 |
|
1109 wsc.onclose = function(e) |
|
1110 { |
|
1111 ok(e.code != 3101, "test 37c custom server code not present"); |
|
1112 ok(e.reason == "", "test 37c custom server reason not present"); |
|
1113 doTest(38); |
|
1114 } |
|
1115 } |
|
1116 } |
|
1117 } |
|
1118 |
|
1119 function test38() |
|
1120 { |
|
1121 var prots=["test-38"]; |
|
1122 |
|
1123 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
1124 ws.onopen = function(e) |
|
1125 { |
|
1126 ok(true, "test 38 open"); |
|
1127 ok(ws.extensions != undefined, "extensions attribute defined"); |
|
1128 // ok(ws.extensions == "deflate-stream", "extensions attribute deflate-stream"); |
|
1129 ws.close(); |
|
1130 }; |
|
1131 |
|
1132 ws.onclose = function(e) |
|
1133 { |
|
1134 ok(true, "test 38 close"); |
|
1135 doTest(39); |
|
1136 }; |
|
1137 } |
|
1138 |
|
1139 function test39() |
|
1140 { |
|
1141 var prots=["test-39"]; |
|
1142 |
|
1143 var ws = CreateTestWS("wss://example.com/tests/content/base/test/file_websocket", prots); |
|
1144 status_test39 = "started"; |
|
1145 ws.onopen = function(e) |
|
1146 { |
|
1147 status_test39 = "opened"; |
|
1148 ok(true, "test 39 open"); |
|
1149 ws.close(); |
|
1150 }; |
|
1151 |
|
1152 ws.onclose = function(e) |
|
1153 { |
|
1154 ok(true, "test 39 close"); |
|
1155 ok(status_test39 == "opened", "test 39 did open"); |
|
1156 doTest(40); |
|
1157 }; |
|
1158 } |
|
1159 |
|
1160 function test40() |
|
1161 { |
|
1162 var prots=["test-40"]; |
|
1163 |
|
1164 var ws = CreateTestWS("wss://nocert.example.com/tests/content/base/test/file_websocket", prots); |
|
1165 |
|
1166 status_test40 = "started"; |
|
1167 ws.onerror = ignoreError; |
|
1168 |
|
1169 ws.onopen = function(e) |
|
1170 { |
|
1171 status_test40 = "opened"; |
|
1172 ok(false, "test 40 open"); |
|
1173 ws.close(); |
|
1174 }; |
|
1175 |
|
1176 ws.onclose = function(e) |
|
1177 { |
|
1178 ok(true, "test 40 close"); |
|
1179 ok(status_test40 == "started", "test 40 did not open"); |
|
1180 doTest(41); |
|
1181 }; |
|
1182 } |
|
1183 |
|
1184 function test41() |
|
1185 { |
|
1186 var ws = CreateTestWS("ws://example.com/tests/content/base/test/file_websocket", "test-41a", 1); |
|
1187 |
|
1188 ws.onopen = function(e) |
|
1189 { |
|
1190 ok(true, "test 41a open"); |
|
1191 ok(ws.url == "ws://example.com/tests/content/base/test/file_websocket", |
|
1192 "test 41a initial ws should not be redirected"); |
|
1193 ws.close(); |
|
1194 }; |
|
1195 |
|
1196 ws.onclose = function(e) |
|
1197 { |
|
1198 ok(true, "test 41a close"); |
|
1199 |
|
1200 // establish a hsts policy for example.com |
|
1201 var wsb = CreateTestWS("wss://example.com/tests/content/base/test/file_websocket", "test-41b", 1); |
|
1202 wsb.onopen = function(e) |
|
1203 { |
|
1204 ok(true, "test 41b open"); |
|
1205 wsb.close(); |
|
1206 } |
|
1207 |
|
1208 wsb.onclose = function(e) |
|
1209 { |
|
1210 ok(true, "test 41b close"); |
|
1211 |
|
1212 // try ws:// again, it should be done over wss:// now due to hsts |
|
1213 var wsc = CreateTestWS("ws://example.com/tests/content/base/test/file_websocket", "test-41c"); |
|
1214 |
|
1215 wsc.onopen = function(e) |
|
1216 { |
|
1217 ok(true, "test 41c open"); |
|
1218 ok(wsc.url == "wss://example.com/tests/content/base/test/file_websocket", |
|
1219 "test 41c ws should be redirected by hsts to wss"); |
|
1220 wsc.close(); |
|
1221 } |
|
1222 |
|
1223 wsc.onclose = function(e) |
|
1224 { |
|
1225 ok(true, "test 41c close"); |
|
1226 |
|
1227 // clean up the STS state |
|
1228 const Cc = SpecialPowers.Cc; |
|
1229 const Ci = SpecialPowers.Ci; |
|
1230 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); |
|
1231 var thehost = ios.newURI("http://example.com", null, null); |
|
1232 var sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); |
|
1233 var loadContext = SpecialPowers.wrap(window) |
|
1234 .QueryInterface(Ci.nsIInterfaceRequestor) |
|
1235 .getInterface(Ci.nsIWebNavigation) |
|
1236 .QueryInterface(Ci.nsILoadContext); |
|
1237 var flags = 0; |
|
1238 if (loadContext.usePrivateBrowsing) |
|
1239 flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE; |
|
1240 sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, thehost, flags); |
|
1241 doTest(42); |
|
1242 } |
|
1243 } |
|
1244 } |
|
1245 } |
|
1246 |
|
1247 function test42() |
|
1248 { |
|
1249 // test some utf-8 non-characters. They should be allowed in the |
|
1250 // websockets context. Test via round trip echo. |
|
1251 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-42"); |
|
1252 var data = ["U+FFFE \ufffe", |
|
1253 "U+FFFF \uffff", |
|
1254 "U+10FFFF \udbff\udfff"]; |
|
1255 var index = 0; |
|
1256 |
|
1257 ws.onopen = function() |
|
1258 { |
|
1259 ws.send(data[0]); |
|
1260 ws.send(data[1]); |
|
1261 ws.send(data[2]); |
|
1262 } |
|
1263 |
|
1264 ws.onmessage = function(e) |
|
1265 { |
|
1266 ok(e.data == data[index], "bad received message in test-42! index="+index); |
|
1267 index++; |
|
1268 if (index == 3) |
|
1269 ws.close(); |
|
1270 } |
|
1271 |
|
1272 ws.onclose = function(e) |
|
1273 { |
|
1274 doTest(43); |
|
1275 } |
|
1276 } |
|
1277 |
|
1278 function test43() |
|
1279 { |
|
1280 var prots=["test-43"]; |
|
1281 |
|
1282 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); |
|
1283 ws.onopen = function(e) |
|
1284 { |
|
1285 ok(true, "test 43 open"); |
|
1286 // Test binaryType setting |
|
1287 ws.binaryType = "arraybuffer"; |
|
1288 ws.binaryType = "blob"; |
|
1289 ws.binaryType = ""; // illegal |
|
1290 is(ws.binaryType, "blob"); |
|
1291 ws.binaryType = "ArrayBuffer"; // illegal |
|
1292 is(ws.binaryType, "blob"); |
|
1293 ws.binaryType = "Blob"; // illegal |
|
1294 is(ws.binaryType, "blob"); |
|
1295 ws.binaryType = "mcfoofluu"; // illegal |
|
1296 is(ws.binaryType, "blob"); |
|
1297 ws.close(); |
|
1298 }; |
|
1299 |
|
1300 ws.onclose = function(e) |
|
1301 { |
|
1302 ok(true, "test 43 close"); |
|
1303 doTest(44); |
|
1304 }; |
|
1305 } |
|
1306 |
|
1307 |
|
1308 function test44() |
|
1309 { |
|
1310 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-44"); |
|
1311 ok(ws.readyState == 0, "bad readyState in test-44!"); |
|
1312 ws.binaryType = "arraybuffer"; |
|
1313 ws.onopen = function() |
|
1314 { |
|
1315 ok(ws.readyState == 1, "open bad readyState in test-44!"); |
|
1316 var buf = new ArrayBuffer(3); |
|
1317 // create byte view |
|
1318 var view = new Uint8Array(buf); |
|
1319 view[0] = 5; |
|
1320 view[1] = 0; // null byte |
|
1321 view[2] = 7; |
|
1322 ws.send(buf); |
|
1323 } |
|
1324 ws.onmessage = function(e) |
|
1325 { |
|
1326 ok(e.data instanceof ArrayBuffer, "Should receive an arraybuffer!"); |
|
1327 var view = new Uint8Array(e.data); |
|
1328 ok(view.length == 2 && view[0] == 0 && view[1] ==4, "testing Reply arraybuffer" ); |
|
1329 ws.close(); |
|
1330 } |
|
1331 ws.onclose = function(e) |
|
1332 { |
|
1333 ok(ws.readyState == 3, "onclose bad readyState in test-44!"); |
|
1334 shouldCloseCleanly(e); |
|
1335 doTest(45); |
|
1336 } |
|
1337 } |
|
1338 |
|
1339 function createDOMFile(fileName, fileData) |
|
1340 { |
|
1341 // create File in profile dir |
|
1342 var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"] |
|
1343 .getService(SpecialPowers.Ci.nsIProperties); |
|
1344 var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile); |
|
1345 testFile.append(fileName); |
|
1346 var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"] |
|
1347 .createInstance(SpecialPowers.Ci.nsIFileOutputStream); |
|
1348 outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0); |
|
1349 outStream.write(fileData, fileData.length); |
|
1350 outStream.close(); |
|
1351 |
|
1352 // Set filename into DOM <input> field, as if selected by user |
|
1353 var fileList = document.getElementById('fileList'); |
|
1354 SpecialPowers.wrap(fileList).value = testFile.path; |
|
1355 |
|
1356 // return JS File object, aka Blob |
|
1357 return fileList.files[0]; |
|
1358 } |
|
1359 |
|
1360 function test45() |
|
1361 { |
|
1362 var blobFile = createDOMFile("testBlobFile", "flob"); |
|
1363 |
|
1364 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-45"); |
|
1365 ok(ws.readyState == 0, "bad readyState in test-45!"); |
|
1366 |
|
1367 // ws.binaryType = "blob"; // Don't need to specify: blob is the default |
|
1368 |
|
1369 ws.onopen = function() |
|
1370 { |
|
1371 ok(ws.readyState == 1, "open bad readyState in test-45!"); |
|
1372 ws.send(blobFile); |
|
1373 } |
|
1374 |
|
1375 var test45blob; |
|
1376 |
|
1377 ws.onmessage = function(e) |
|
1378 { |
|
1379 test45blob = e.data; |
|
1380 ok(test45blob instanceof Blob, "We should be receiving a Blob"); |
|
1381 |
|
1382 ws.close(); |
|
1383 } |
|
1384 |
|
1385 ws.onclose = function(e) |
|
1386 { |
|
1387 ok(ws.readyState == 3, "onclose bad readyState in test-45!"); |
|
1388 shouldCloseCleanly(e); |
|
1389 |
|
1390 // check blob contents |
|
1391 var reader = new FileReader(); |
|
1392 reader.onload = function(event) |
|
1393 { |
|
1394 ok(reader.result == "flob", "response should be 'flob': got '" |
|
1395 + reader.result + "'"); |
|
1396 }; |
|
1397 reader.onerror = function(event) |
|
1398 { |
|
1399 testFailed("Failed to read blob: error code = " + reader.error.code); |
|
1400 }; |
|
1401 reader.onloadend = function(event) |
|
1402 { |
|
1403 doTest(46); |
|
1404 }; |
|
1405 |
|
1406 reader.readAsBinaryString(test45blob); |
|
1407 } |
|
1408 } |
|
1409 |
|
1410 function test46() |
|
1411 { |
|
1412 var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-46"); |
|
1413 ok(ws.readyState == 0, "create bad readyState in test-46!"); |
|
1414 ws.onopen = function() |
|
1415 { |
|
1416 ok(ws.readyState == 1, "open bad readyState in test-46!"); |
|
1417 ws.close() |
|
1418 ok(ws.readyState == 2, "close must set readyState to 2 in test-46!"); |
|
1419 } |
|
1420 ws.onmessage = function(e) |
|
1421 { |
|
1422 ok(false, "received message after calling close in test-46!"); |
|
1423 } |
|
1424 ws.onclose = function(e) |
|
1425 { |
|
1426 ok(ws.readyState == 3, "onclose bad readyState in test-46!"); |
|
1427 shouldCloseCleanly(e); |
|
1428 doTest(47); |
|
1429 } |
|
1430 } |
|
1431 |
|
1432 function test47() |
|
1433 { |
|
1434 var hasError = false; |
|
1435 var ws = CreateTestWS("ws://another.websocket.server.that.probably.does.not.exist"); |
|
1436 ws.onopen = shouldNotOpen; |
|
1437 |
|
1438 ws.onerror = function (e) |
|
1439 { |
|
1440 ok(ws.readyState == 3, "test-47: readyState should be CLOSED(3) in onerror: got " |
|
1441 + ws.readyState); |
|
1442 ok(!ws._withinClose, "onerror() called during close()!"); |
|
1443 hasError = true; |
|
1444 } |
|
1445 |
|
1446 ws.onclose = function(e) |
|
1447 { |
|
1448 shouldCloseNotCleanly(e); |
|
1449 ok(hasError, "test-47: should have called onerror before onclose"); |
|
1450 ok(ws.readyState == 3, "test-47: readyState should be CLOSED(3) in onclose: got " |
|
1451 + ws.readyState); |
|
1452 ok(!ws._withinClose, "onclose() called during close()!"); |
|
1453 ok(e.code == 1006, "test-47 close code should be 1006 but is:" + e.code); |
|
1454 doTest(48); |
|
1455 }; |
|
1456 |
|
1457 // Call close before we're connected: throws error |
|
1458 // Make sure we call onerror/onclose asynchronously |
|
1459 ws._withinClose = 1; |
|
1460 ws.close(3333, "Closed before we were open: error"); |
|
1461 ws._withinClose = 0; |
|
1462 ok(ws.readyState == 2, "test-47: readyState should be CLOSING(2) after close(): got " |
|
1463 + ws.readyState); |
|
1464 } |
|
1465 |
|
1466 |
|
1467 var ranAllTests = false; |
|
1468 |
|
1469 function maybeFinished() |
|
1470 { |
|
1471 if (!ranAllTests) |
|
1472 return; |
|
1473 |
|
1474 if (waitTest2Part1 || waitTest2Part2 || waitTest9 || waitTest10 || |
|
1475 waitTest17 || waitTest20 || waitTest21 || waitTest22) |
|
1476 return; |
|
1477 |
|
1478 for (i = 0; i < all_ws.length; ++i) { |
|
1479 if (all_ws[i] != shouldNotReceiveCloseEvent && |
|
1480 !all_ws[i]._receivedCloseEvent) { |
|
1481 ok(false, "didn't called close on test " + all_ws[i]._testNumber + "!"); |
|
1482 } |
|
1483 } |
|
1484 |
|
1485 if (testsuite_iteration++ < testsuite_iterations) { |
|
1486 // play it again, Sam... |
|
1487 ok(1, "starting testsuite iteration " + testsuite_iteration); |
|
1488 test_started = new Array(last_test); |
|
1489 doTest(current_test = first_test); |
|
1490 } else { |
|
1491 // all done |
|
1492 SimpleTest.finish(); |
|
1493 } |
|
1494 } |
|
1495 |
|
1496 function testWebSocket () |
|
1497 { |
|
1498 doTest(first_test); |
|
1499 } |
|
1500 |
|
1501 SimpleTest.waitForExplicitFinish(); |
|
1502 |
|
1503 </script> |
|
1504 </pre> |
|
1505 |
|
1506 <div id="feedback"> |
|
1507 </div> |
|
1508 |
|
1509 </body> |
|
1510 </html> |