1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/test/test_websocket.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1510 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<head> 1.7 + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta> 1.8 + <title>WebSocket test</title> 1.9 + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.10 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 1.11 +</head> 1.12 +<body onload="testWebSocket()"> 1.13 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=472529">Mozilla Bug </a> 1.14 +<p id="display"> 1.15 + <input id="fileList" type="file"></input> 1.16 +</p> 1.17 +<div id="content"> 1.18 +</div> 1.19 +<pre id="test"> 1.20 +<script class="testbody" type="text/javascript"> 1.21 + 1.22 +/* 1.23 + * tests: 1.24 + * 1. client tries to connect to a http scheme location; 1.25 + * 2. assure serialization of the connections; 1.26 + * 3. client tries to connect to an non-existent ws server; 1.27 + * 4. client tries to connect using a relative url; 1.28 + * 5. client uses an invalid protocol value; 1.29 + * 6. counter and encoding check; 1.30 + * 7. onmessage event origin property check 1.31 + * 8. client calls close() and the server sends the close frame (with no code 1.32 + * or reason) in acknowledgement; 1.33 + * 9. client closes the connection before the ws connection is established; 1.34 + * 10. client sends a message before the ws connection is established; 1.35 + * 11. a simple hello echo; 1.36 + * 12. client sends a message containing unpaired surrogates 1.37 + * 13. server sends an invalid message; 1.38 + * 14. server sends the close frame, it doesn't close the tcp connection and 1.39 + * it keeps sending normal ws messages; 1.40 + * 15. server closes the tcp connection, but it doesn't send the close frame; 1.41 + * 16. client calls close() and tries to send a message; 1.42 + * 17. see bug 572975 - all event listeners set 1.43 + * 18. client tries to connect to an http resource; 1.44 + * 19. server closes the tcp connection before establishing the ws connection; 1.45 + * 20. see bug 572975 - only on error and onclose event listeners set 1.46 + * 21. see bug 572975 - same as test 17, but delete strong event listeners when 1.47 + * receiving the message event; 1.48 + * 22. server takes too long to establish the ws connection; 1.49 + * 23. should detect WebSocket on window object; 1.50 + * 24. server rejects sub-protocol string 1.51 + * 25. ctor with valid empty sub-protocol array 1.52 + * 26. ctor with invalid sub-protocol array containing 1 empty element 1.53 + * 27. ctor with invalid sub-protocol array containing an empty element in list 1.54 + * 28. ctor using valid 1 element sub-protocol array 1.55 + * 29. ctor using all valid 5 element sub-protocol array 1.56 + * 30. ctor using valid 1 element sub-protocol array with element server will 1.57 + * reject 1.58 + * 31. ctor using valid 2 element sub-protocol array with 1 element server 1.59 + * will reject and one server will accept. 1.60 + * 32. ctor using invalid sub-protocol array that contains duplicate items 1.61 + * 33. test for sending/receiving custom close code (but no close reason) 1.62 + * 34. test for receiving custom close code and reason 1.63 + * 35. test for sending custom close code and reason 1.64 + * 36. negative test for sending out of range close code 1.65 + * 37. negative test for too long of a close reason 1.66 + * 38. ensure extensions attribute is defined 1.67 + * 39. a basic wss:// connectivity test 1.68 + * 40. negative test for wss:// with no cert 1.69 + * 41. HSTS 1.70 + * 42. non-char utf-8 sequences 1.71 + * 43. Test setting binaryType attribute 1.72 + * 44. Test sending/receving binary ArrayBuffer 1.73 + * 45. Test sending/receving binary Blob 1.74 + * 46. Test that we don't dispatch incoming msgs once in CLOSING state 1.75 + * 47. Make sure onerror/onclose aren't called during close() 1.76 + */ 1.77 + 1.78 +var first_test = 1; 1.79 +var last_test = 47; 1.80 + 1.81 + 1.82 +// Set this to >1 if you want to run the suite multiple times to probe for 1.83 +// random orange failures. 1.84 +// - Do NOT check into mozilla-central with a value != 1. 1.85 +// - Too large a count will wind up causing tryserver to timeout the test (which 1.86 +// is ok, but means all testruns will be orange). If I set first_test to >22 1.87 +// (i.e don't run any of the tests that require waiting) I can get ~250-300 1.88 +// iterations of the remaining tests w/o a timeout. 1.89 +var testsuite_iterations = 1; 1.90 + 1.91 + 1.92 +var current_test = first_test; 1.93 +var testsuite_iteration = 1; 1.94 + 1.95 +var test_started = new Array(last_test); 1.96 +var all_ws = []; 1.97 + 1.98 +function shouldNotOpen(e) 1.99 +{ 1.100 + var ws = e.target; 1.101 + ok(false, "onopen shouldn't be called on test " + ws._testNumber + "!"); 1.102 +} 1.103 + 1.104 +function shouldNotReceiveCloseEvent(e) 1.105 +{ 1.106 + var ws = e.target; 1.107 + var extendedErrorInfo = ""; 1.108 + if (!ws._testNumber) { 1.109 + extendedErrorInfo += "\nws members:\n"; 1.110 + for (var i in ws) { 1.111 + extendedErrorInfo += (i + ": " + ws[i] + "\n"); 1.112 + } 1.113 + 1.114 + extendedErrorInfo += "\ne members:\n"; 1.115 + for (var i in e) { 1.116 + extendedErrorInfo += (i + ": " + e[i] + "\n"); 1.117 + } 1.118 + } 1.119 + 1.120 + // FIXME: see bug 578276. This should be a test failure, but it's too flaky on the tbox. 1.121 + ok(true, "onclose shouldn't be called on test " + ws._testNumber + "!" + extendedErrorInfo); 1.122 +} 1.123 + 1.124 +function shouldCloseCleanly(e) 1.125 +{ 1.126 + var ws = e.target; 1.127 + ok(e.wasClean, "the ws connection in test " + ws._testNumber + " should be closed cleanly"); 1.128 +} 1.129 + 1.130 +function shouldCloseNotCleanly(e) 1.131 +{ 1.132 + var ws = e.target; 1.133 + ok(!e.wasClean, "the ws connection in test " + ws._testNumber + " shouldn't be closed cleanly"); 1.134 +} 1.135 + 1.136 +function ignoreError(e) 1.137 +{ 1.138 +} 1.139 + 1.140 +function CreateTestWS(ws_location, ws_protocol, no_increment_test) 1.141 +{ 1.142 + var ws; 1.143 + 1.144 + try { 1.145 + if (ws_protocol == undefined) { 1.146 + ws = new WebSocket(ws_location); 1.147 + } else { 1.148 + ws = new WebSocket(ws_location, ws_protocol); 1.149 + } 1.150 + 1.151 + 1.152 + ws._testNumber = current_test; 1.153 + ws._receivedCloseEvent = false; 1.154 + ok(true, "Created websocket for test " + ws._testNumber +"\n"); 1.155 + 1.156 + ws.onerror = function(e) 1.157 + { 1.158 + ok(false, "onerror called on test " + e.target._testNumber + "!"); 1.159 + }; 1.160 + ws.addEventListener("close", function(e) 1.161 + { 1.162 + ws._receivedCloseEvent = true; 1.163 + }, false); 1.164 + } 1.165 + catch (e) { 1.166 + throw e; 1.167 + } 1.168 + finally { 1.169 + if (!no_increment_test) { 1.170 + current_test++; 1.171 + } 1.172 + } 1.173 + 1.174 + all_ws.push(ws); 1.175 + return ws; 1.176 +} 1.177 + 1.178 +function forcegc() 1.179 +{ 1.180 + SpecialPowers.forceGC(); 1.181 + SpecialPowers.gc(); 1.182 + setTimeout(function() 1.183 + { 1.184 + SpecialPowers.gc(); 1.185 + }, 1); 1.186 +} 1.187 + 1.188 +function doTest(number) 1.189 +{ 1.190 + if (number > last_test) { 1.191 + ranAllTests = true; 1.192 + maybeFinished(); 1.193 + return; 1.194 + } 1.195 + 1.196 + if (testsuite_iteration > 1) { 1.197 + $("feedback").innerHTML = "test suite iteration #" + testsuite_iteration + " of " + testsuite_iterations + 1.198 + ": executing test: " + number + " of " + last_test + " tests."; 1.199 + } else { 1.200 + $("feedback").innerHTML = "executing test: " + number + " of " + last_test + " tests."; 1.201 + } 1.202 + 1.203 + var fnTest = eval("test" + number + ""); 1.204 + 1.205 + if (test_started[number] === true) { 1.206 + doTest(number + 1); 1.207 + return; 1.208 + } 1.209 + 1.210 + test_started[number] = true; 1.211 + fnTest(); 1.212 +} 1.213 +doTest.timeoutId = null; 1.214 + 1.215 +function test1() 1.216 +{ 1.217 + try { 1.218 + var ws = CreateTestWS("http://mochi.test:8888/tests/content/base/test/file_websocket"); 1.219 + ok(false, "test1 failed"); 1.220 + } 1.221 + catch (e) { 1.222 + ok(true, "test1 failed"); 1.223 + } 1.224 + doTest(2); 1.225 +} 1.226 + 1.227 +// this test expects that the serialization list to connect to the proxy 1.228 +// is empty. Use different domain so we can run this in the background 1.229 +// and not delay other tests. 1.230 + 1.231 +var waitTest2Part1 = false; 1.232 +var waitTest2Part2 = false; 1.233 + 1.234 +function test2() 1.235 +{ 1.236 + waitTest2Part1 = true; 1.237 + waitTest2Part2 = true; 1.238 + 1.239 + var ws1 = CreateTestWS("ws://sub2.test2.example.com/tests/content/base/test/file_websocket", "test-2.1"); 1.240 + current_test--; // CreateTestWS incremented this 1.241 + var ws2 = CreateTestWS("ws://sub2.test2.example.com/tests/content/base/test/file_websocket", "test-2.2"); 1.242 + 1.243 + var ws2CanConnect = false; 1.244 + 1.245 + // the server will delay ws1 for 5 seconds, but the other tests can 1.246 + // proceed in parallel 1.247 + doTest(3); 1.248 + 1.249 + ws1.onopen = function() 1.250 + { 1.251 + ok(true, "ws1 open in test 2"); 1.252 + ws2CanConnect = true; 1.253 + ws1.close(); 1.254 + } 1.255 + 1.256 + ws1.onclose = function(e) 1.257 + { 1.258 + waitTest2Part1 = false; 1.259 + maybeFinished(); 1.260 + }; 1.261 + 1.262 + ws2.onopen = function() 1.263 + { 1.264 + ok(ws2CanConnect, "shouldn't connect yet in test-2!"); 1.265 + ws2.close(); 1.266 + } 1.267 + 1.268 + ws2.onclose = function(e) 1.269 + { 1.270 + waitTest2Part2 = false; 1.271 + maybeFinished(); 1.272 + }; 1.273 +} 1.274 + 1.275 +function test3() 1.276 +{ 1.277 + var hasError = false; 1.278 + var ws = CreateTestWS("ws://this.websocket.server.probably.does.not.exist"); 1.279 + ws.onopen = shouldNotOpen; 1.280 + ws.onerror = function (e) 1.281 + { 1.282 + hasError = true; 1.283 + } 1.284 + 1.285 + ws.onclose = function(e) 1.286 + { 1.287 + shouldCloseNotCleanly(e); 1.288 + ok(hasError, "rcvd onerror event"); 1.289 + ok(e.code == 1006, "test-3 close code should be 1006 but is:" + e.code); 1.290 + doTest(4); 1.291 + }; 1.292 +} 1.293 + 1.294 +function test4() 1.295 +{ 1.296 + try { 1.297 + var ws = CreateTestWS("file_websocket"); 1.298 + ok(false, "test-4 failed"); 1.299 + } 1.300 + catch (e) { 1.301 + ok(true, "test-4 failed"); 1.302 + } 1.303 + doTest(5); 1.304 +} 1.305 + 1.306 +function test5() 1.307 +{ 1.308 + try { 1.309 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", ""); 1.310 + ok(false, "couldn't accept an empty string in the protocol parameter"); 1.311 + } 1.312 + catch (e) { 1.313 + ok(true, "couldn't accept an empty string in the protocol parameter"); 1.314 + } 1.315 + current_test--; // CreateTestWS incremented this 1.316 + try { 1.317 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "\n"); 1.318 + ok(false, "couldn't accept any not printable ASCII character in the protocol parameter"); 1.319 + } 1.320 + catch (e) { 1.321 + ok(true, "couldn't accept any not printable ASCII character in the protocol parameter"); 1.322 + } 1.323 + current_test--; // CreateTestWS incremented this 1.324 + try { 1.325 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 5"); 1.326 + ok(false, "U+0020 not acceptable in protocol parameter"); 1.327 + } 1.328 + catch (e) { 1.329 + ok(true, "U+0020 not acceptable in protocol parameter"); 1.330 + } 1.331 + doTest(6); 1.332 +} 1.333 + 1.334 +function test6() 1.335 +{ 1.336 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-6"); 1.337 + var counter = 1; 1.338 + ws.onopen = function() 1.339 + { 1.340 + ws.send(counter); 1.341 + } 1.342 + ws.onmessage = function(e) 1.343 + { 1.344 + if (counter == 5) { 1.345 + ok(e.data == "あいうえお", "test-6 counter 5 data ok"); 1.346 + ws.close(); 1.347 + } else { 1.348 + ok(e.data == counter+1, "bad counter"); 1.349 + counter += 2; 1.350 + ws.send(counter); 1.351 + } 1.352 + } 1.353 + ws.onclose = function(e) 1.354 + { 1.355 + shouldCloseCleanly(e); 1.356 + doTest(7); 1.357 + }; 1.358 +} 1.359 + 1.360 +function test7() 1.361 +{ 1.362 + var ws = CreateTestWS("ws://sub2.test2.example.org/tests/content/base/test/file_websocket", "test-7"); 1.363 + var gotmsg = false; 1.364 + 1.365 + ws.onopen = function() 1.366 + { 1.367 + ok(true, "test 7 open"); 1.368 + } 1.369 + ws.onmessage = function(e) 1.370 + { 1.371 + ok(true, "test 7 message"); 1.372 + ok(e.origin == "ws://sub2.test2.example.org", "onmessage origin set to ws:// host"); 1.373 + gotmsg = true; 1.374 + ws.close(); 1.375 + } 1.376 + ws.onclose = function(e) 1.377 + { 1.378 + ok(gotmsg, "recvd message in test 7 before close"); 1.379 + shouldCloseCleanly(e); 1.380 + doTest(8); 1.381 + }; 1.382 +} 1.383 + 1.384 +function test8() 1.385 +{ 1.386 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-8"); 1.387 + ws.onopen = function() 1.388 + { 1.389 + ok(ws.protocol == "test-8", "test-8 subprotocol selection"); 1.390 + ws.close(); 1.391 + } 1.392 + ws.onclose = function(e) 1.393 + { 1.394 + shouldCloseCleanly(e); 1.395 + // We called close() with no close code: so pywebsocket will also send no 1.396 + // close code, which translates to code 1005 1.397 + ok(e.code == 1005, "test-8 close code has wrong value:" + e.code); 1.398 + ok(e.reason == "", "test-8 close reason has wrong value:" + e.reason); 1.399 + doTest(9); 1.400 + }; 1.401 +} 1.402 + 1.403 +var waitTest9 = false; 1.404 + 1.405 +function test9() 1.406 +{ 1.407 + waitTest9 = true; 1.408 + 1.409 + var ws = CreateTestWS("ws://test2.example.org/tests/content/base/test/file_websocket", "test-9"); 1.410 + ws._receivedErrorEvent = false; 1.411 + ws.onopen = shouldNotOpen; 1.412 + ws.onerror = function(e) 1.413 + { 1.414 + ws._receivedErrorEvent = true; 1.415 + }; 1.416 + ws.onclose = function(e) 1.417 + { 1.418 + ok(ws._receivedErrorEvent, "Didn't received the error event in test 9."); 1.419 + shouldCloseNotCleanly(e); 1.420 + waitTest9 = false; 1.421 + maybeFinished(); 1.422 + }; 1.423 + 1.424 + ws.close(); 1.425 + 1.426 + // the server injects a delay, so proceed with this in the background 1.427 + doTest(10); 1.428 +} 1.429 + 1.430 +var waitTest10 = false; 1.431 + 1.432 +function test10() 1.433 +{ 1.434 + waitTest10 = true; 1.435 + 1.436 + var ws = CreateTestWS("ws://sub1.test1.example.com/tests/content/base/test/file_websocket", "test-10"); 1.437 + ws.onclose = function(e) 1.438 + { 1.439 + shouldCloseCleanly(e); 1.440 + waitTest10 = false; 1.441 + maybeFinished(); 1.442 + } 1.443 + 1.444 + try { 1.445 + ws.send("client data"); 1.446 + ok(false, "Couldn't send data before connecting!"); 1.447 + } 1.448 + catch (e) { 1.449 + ok(true, "Couldn't send data before connecting!"); 1.450 + } 1.451 + ws.onopen = function() 1.452 + { 1.453 + ok(true, "test 10 opened"); 1.454 + ws.close(); 1.455 + } 1.456 + 1.457 + // proceed with this test in the background 1.458 + doTest(11); 1.459 +} 1.460 + 1.461 +function test11() 1.462 +{ 1.463 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-11"); 1.464 + ok(ws.readyState == 0, "create bad readyState in test-11!"); 1.465 + ws.onopen = function() 1.466 + { 1.467 + ok(ws.readyState == 1, "open bad readyState in test-11!"); 1.468 + ws.send("client data"); 1.469 + } 1.470 + ws.onmessage = function(e) 1.471 + { 1.472 + ok(e.data == "server data", "bad received message in test-11!"); 1.473 + ws.close(1000, "Have a nice day"); 1.474 + 1.475 +// this ok() is disabled due to a race condition - it state may have 1.476 +// advanced through 2 (closing) and into 3 (closed) before it is evald 1.477 +// ok(ws.readyState == 2, "onmessage bad readyState in test-11!"); 1.478 + } 1.479 + ws.onclose = function(e) 1.480 + { 1.481 + ok(ws.readyState == 3, "onclose bad readyState in test-11!"); 1.482 + shouldCloseCleanly(e); 1.483 + ok(e.code == 1000, "test 11 got wrong close code: " + e.code); 1.484 + ok(e.reason == "Have a nice day", "test 11 got wrong close reason: " + e.reason); 1.485 + doTest(12); 1.486 + } 1.487 +} 1.488 + 1.489 +function test12() 1.490 +{ 1.491 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-12"); 1.492 + ws.onopen = function() 1.493 + { 1.494 + try { 1.495 + // send an unpaired surrogate 1.496 + ws._gotMessage = false; 1.497 + ws.send("a\ud800b"); 1.498 + ok(true, "ok to send an unpaired surrogate"); 1.499 + } 1.500 + catch (e) { 1.501 + ok(false, "shouldn't fail any more when sending an unpaired surrogate!"); 1.502 + } 1.503 + } 1.504 + 1.505 + ws.onmessage = function(msg) 1.506 + { 1.507 + ok(msg.data == "SUCCESS", "Unpaired surrogate in UTF-16 not converted in test-12"); 1.508 + ws._gotMessage = true; 1.509 + // Must support unpaired surrogates in close reason, too 1.510 + ws.close(1000, "a\ud800b"); 1.511 + } 1.512 + 1.513 + ws.onclose = function(e) 1.514 + { 1.515 + ok(ws.readyState == 3, "onclose bad readyState in test-12!"); 1.516 + ok(ws._gotMessage, "didn't receive message!"); 1.517 + shouldCloseCleanly(e); 1.518 + ok(e.code == 1000, "test 12 got wrong close code: " + e.code); 1.519 + ok(e.reason == "a\ufffdb", "test 11 didn't get replacement char in close reason: " + e.reason); 1.520 + doTest(13); 1.521 + } 1.522 +} 1.523 + 1.524 +function test13() 1.525 +{ 1.526 + // previous versions of this test counted the number of protocol errors returned, but the 1.527 + // protocol stack typically closes down after reporting a protocol level error - trying 1.528 + // to resync is too dangerous 1.529 + 1.530 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-13"); 1.531 + ws._timesCalledOnError = 0; 1.532 + ws.onerror = function() 1.533 + { 1.534 + ws._timesCalledOnError++; 1.535 + } 1.536 + ws.onclose = function(e) 1.537 + { 1.538 + ok(ws._timesCalledOnError > 0, "no error events"); 1.539 + doTest(14); 1.540 + } 1.541 +} 1.542 + 1.543 +function test14() 1.544 +{ 1.545 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-14"); 1.546 + ws.onmessage = function() 1.547 + { 1.548 + ok(false, "shouldn't received message after the server sent the close frame"); 1.549 + } 1.550 + ws.onclose = function(e) 1.551 + { 1.552 + shouldCloseCleanly(e); 1.553 + // Skip test 15 for now: broken 1.554 + doTest(16); 1.555 + }; 1.556 +} 1.557 + 1.558 +/* 1.559 + * DISABLED: see comments for test-15 case in file_websocket_wsh.py 1.560 + * 1.561 +function test15() 1.562 +{ 1.563 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-15"); 1.564 + ws.onclose = function(e) 1.565 + { 1.566 + shouldCloseNotCleanly(e); 1.567 + doTest(16); 1.568 + }; 1.569 + 1.570 + // termination of the connection might cause an error event if it happens in OPEN 1.571 + ws.onerror = function() 1.572 + { 1.573 + } 1.574 + 1.575 +} 1.576 +*/ 1.577 + 1.578 +function test16() 1.579 +{ 1.580 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-16"); 1.581 + ws.onopen = function() 1.582 + { 1.583 + ws.close(); 1.584 + ok(!ws.send("client data"), "shouldn't send message after calling close()"); 1.585 + } 1.586 + ws.onmessage = function() 1.587 + { 1.588 + ok(false, "shouldn't send message after calling close()"); 1.589 + } 1.590 + 1.591 + ws.onerror = function() 1.592 + { 1.593 + } 1.594 + ws.onclose = function() 1.595 + { 1.596 + doTest(17); 1.597 + } 1.598 +} 1.599 + 1.600 +var status_test17 = "not started"; 1.601 + 1.602 +var waitTest17 = false; 1.603 + 1.604 +var test17func = function() 1.605 +{ 1.606 + waitTest17 = true; 1.607 + 1.608 + var local_ws = new WebSocket("ws://sub1.test2.example.org/tests/content/base/test/file_websocket", "test-17"); 1.609 + local_ws._testNumber = "local17"; 1.610 + local_ws._testNumber = current_test++; 1.611 + 1.612 + status_test17 = "started"; 1.613 + 1.614 + local_ws.onopen = function(e) 1.615 + { 1.616 + status_test17 = "opened"; 1.617 + e.target.send("client data"); 1.618 + forcegc(); 1.619 + }; 1.620 + 1.621 + local_ws.onerror = function() 1.622 + { 1.623 + ok(false, "onerror called on test " + e.target._testNumber + "!"); 1.624 + }; 1.625 + 1.626 + local_ws.onmessage = function(e) 1.627 + { 1.628 + ok(e.data == "server data", "Bad message in test-17"); 1.629 + status_test17 = "got message"; 1.630 + forcegc(); 1.631 + }; 1.632 + 1.633 + local_ws.onclose = function(e) 1.634 + { 1.635 + ok(status_test17 == "got message", "Didn't got message in test-17!"); 1.636 + shouldCloseCleanly(e); 1.637 + status_test17 = "closed"; 1.638 + forcegc(); 1.639 + waitTest17 = false; 1.640 + maybeFinished(); 1.641 + }; 1.642 + 1.643 + local_ws = null; 1.644 + window._test17 = null; 1.645 + forcegc(); 1.646 + 1.647 +// do this in the background 1.648 + doTest(18); 1.649 + forcegc(); 1.650 +} 1.651 + 1.652 +function test17() 1.653 +{ 1.654 + window._test17 = test17func; 1.655 + window._test17(); 1.656 +} 1.657 + 1.658 +// The tests that expects that their websockets neither open nor close MUST 1.659 +// be in the end of the tests, i.e. HERE, in order to prevent blocking the other 1.660 +// tests. 1.661 + 1.662 +function test18() 1.663 +{ 1.664 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket_http_resource.txt"); 1.665 + ws.onopen = shouldNotOpen; 1.666 + ws.onerror = ignoreError; 1.667 + ws.onclose = function(e) 1.668 + { 1.669 + shouldCloseNotCleanly(e); 1.670 + doTest(19); 1.671 + }; 1.672 +} 1.673 + 1.674 +function test19() 1.675 +{ 1.676 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-19"); 1.677 + ws.onopen = shouldNotOpen; 1.678 + ws.onerror = ignoreError; 1.679 + ws.onclose = function(e) 1.680 + { 1.681 + shouldCloseNotCleanly(e); 1.682 + doTest(20); 1.683 + }; 1.684 +} 1.685 + 1.686 +var waitTest20 = false; 1.687 + 1.688 +var test20func = function() 1.689 +{ 1.690 + waitTest20 = true; 1.691 + 1.692 + var local_ws = new WebSocket("ws://sub1.test1.example.org/tests/content/base/test/file_websocket", "test-20"); 1.693 + local_ws._testNumber = "local20"; 1.694 + local_ws._testNumber = current_test++; 1.695 + 1.696 + local_ws.onerror = function() 1.697 + { 1.698 + ok(false, "onerror called on test " + e.target._testNumber + "!"); 1.699 + }; 1.700 + 1.701 + local_ws.onclose = function(e) 1.702 + { 1.703 + ok(true, "test 20 closed despite gc"); 1.704 + waitTest20 = false; 1.705 + maybeFinished(); 1.706 + }; 1.707 + 1.708 + local_ws = null; 1.709 + window._test20 = null; 1.710 + forcegc(); 1.711 + 1.712 + // let test run in the background 1.713 + doTest(21); 1.714 +} 1.715 + 1.716 +function test20() 1.717 +{ 1.718 + window._test20 = test20func; 1.719 + window._test20(); 1.720 +} 1.721 + 1.722 +var waitTest21 = false; 1.723 + 1.724 +test21func = function() 1.725 +{ 1.726 + waitTest21 = true; 1.727 + 1.728 + var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-21"); 1.729 + local_ws._testNumber = current_test++; 1.730 + var received_message = false; 1.731 + 1.732 + local_ws.onopen = function(e) 1.733 + { 1.734 + e.target.send("client data"); 1.735 + forcegc(); 1.736 + e.target.onopen = null; 1.737 + forcegc(); 1.738 + }; 1.739 + 1.740 + local_ws.onerror = function() 1.741 + { 1.742 + ok(false, "onerror called on test " + e.target._testNumber + "!"); 1.743 + }; 1.744 + 1.745 + local_ws.onmessage = function(e) 1.746 + { 1.747 + ok(e.data == "server data", "Bad message in test-21"); 1.748 + received_message = true; 1.749 + forcegc(); 1.750 + e.target.onmessage = null; 1.751 + forcegc(); 1.752 + }; 1.753 + 1.754 + local_ws.onclose = function(e) 1.755 + { 1.756 + shouldCloseCleanly(e); 1.757 + ok(received_message, "close transitioned through onmessage"); 1.758 + waitTest21 = false; 1.759 + maybeFinished(); 1.760 + }; 1.761 + 1.762 + local_ws = null; 1.763 + window._test21 = null; 1.764 + forcegc(); 1.765 + 1.766 + doTest(22); 1.767 + 1.768 +} 1.769 + 1.770 +function test21() 1.771 +{ 1.772 + window._test21 = test21func; 1.773 + window._test21(); 1.774 +} 1.775 + 1.776 +var waitTest22 = false; 1.777 + 1.778 +function test22() 1.779 +{ 1.780 + waitTest22 = true; 1.781 + 1.782 + const pref_open = "network.websocket.timeout.open"; 1.783 + SpecialPowers.setIntPref(pref_open, 5); 1.784 + 1.785 + var ws = CreateTestWS("ws://sub2.test2.example.org/tests/content/base/test/file_websocket", "test-22"); 1.786 + ws.onopen = shouldNotOpen; 1.787 + ws.onerror = ignoreError; 1.788 + ws.onclose = function(e) 1.789 + { 1.790 + shouldCloseNotCleanly(e); 1.791 + waitTest22 = false; 1.792 + maybeFinished(); 1.793 + }; 1.794 + 1.795 + SpecialPowers.clearUserPref(pref_open); 1.796 + doTest(23); 1.797 +} 1.798 + 1.799 +function test23() 1.800 +{ 1.801 + current_test++; 1.802 + is(true, "WebSocket" in window, "WebSocket should be available on window object"); 1.803 + doTest(24); 1.804 +} 1.805 + 1.806 +function test24() 1.807 +{ 1.808 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-does-not-exist"); 1.809 + ws.onopen = shouldNotOpen; 1.810 + ws.onclose = function(e) 1.811 + { 1.812 + shouldCloseNotCleanly(e); 1.813 + doTest(25); 1.814 + }; 1.815 + ws.onerror = function() 1.816 + { 1.817 + } 1.818 +} 1.819 + 1.820 +function test25() 1.821 +{ 1.822 + var prots=[]; 1.823 + 1.824 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.825 + 1.826 + // This test errors because the server requires a sub-protocol, but 1.827 + // the test just wants to ensure that the ctor doesn't generate an 1.828 + // exception 1.829 + ws.onerror = ignoreError; 1.830 + ws.onopen = shouldNotOpen; 1.831 + 1.832 + ws.onclose = function(e) 1.833 + { 1.834 + ok(ws.protocol == "", "test25 subprotocol selection"); 1.835 + ok(true, "test 25 protocol array close"); 1.836 + doTest(26); 1.837 + }; 1.838 +} 1.839 + 1.840 +function test26() 1.841 +{ 1.842 + var prots=[""]; 1.843 + 1.844 + try { 1.845 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.846 + ok(false, "testing empty element sub protocol array"); 1.847 + } 1.848 + catch (e) { 1.849 + ok(true, "testing empty sub element protocol array"); 1.850 + } 1.851 + doTest(27); 1.852 +} 1.853 + 1.854 +function test27() 1.855 +{ 1.856 + var prots=["test27", ""]; 1.857 + 1.858 + try { 1.859 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.860 + ok(false, "testing empty element mixed sub protocol array"); 1.861 + } 1.862 + catch (e) { 1.863 + ok(true, "testing empty element mixed sub protocol array"); 1.864 + } 1.865 + doTest(28); 1.866 +} 1.867 + 1.868 +function test28() 1.869 +{ 1.870 + var prots=["test28"]; 1.871 + 1.872 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.873 + ws.onopen = function(e) 1.874 + { 1.875 + ok(true, "test 28 protocol array open"); 1.876 + ws.close(); 1.877 + }; 1.878 + 1.879 + ws.onclose = function(e) 1.880 + { 1.881 + ok(ws.protocol == "test28", "test28 subprotocol selection"); 1.882 + ok(true, "test 28 protocol array close"); 1.883 + doTest(29); 1.884 + }; 1.885 +} 1.886 + 1.887 +function test29() 1.888 +{ 1.889 + var prots=["test29a", "test29b"]; 1.890 + 1.891 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.892 + ws.onopen = function(e) 1.893 + { 1.894 + ok(true, "test 29 protocol array open"); 1.895 + ws.close(); 1.896 + }; 1.897 + 1.898 + ws.onclose = function(e) 1.899 + { 1.900 + ok(true, "test 29 protocol array close"); 1.901 + doTest(30); 1.902 + }; 1.903 +} 1.904 + 1.905 +function test30() 1.906 +{ 1.907 + var prots=["test-does-not-exist"]; 1.908 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.909 + 1.910 + ws.onopen = shouldNotOpen; 1.911 + ws.onclose = function(e) 1.912 + { 1.913 + shouldCloseNotCleanly(e); 1.914 + doTest(31); 1.915 + }; 1.916 + ws.onerror = function() 1.917 + { 1.918 + } 1.919 +} 1.920 + 1.921 +function test31() 1.922 +{ 1.923 + var prots=["test-does-not-exist", "test31"]; 1.924 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.925 + 1.926 + ws.onopen = function(e) 1.927 + { 1.928 + ok(true, "test 31 protocol array open"); 1.929 + ws.close(); 1.930 + }; 1.931 + 1.932 + ws.onclose = function(e) 1.933 + { 1.934 + ok(ws.protocol == "test31", "test31 subprotocol selection"); 1.935 + ok(true, "test 31 protocol array close"); 1.936 + doTest(32); 1.937 + }; 1.938 +} 1.939 + 1.940 +function test32() 1.941 +{ 1.942 + var prots=["test32","test32"]; 1.943 + 1.944 + try { 1.945 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.946 + ok(false, "testing duplicated element sub protocol array"); 1.947 + } 1.948 + catch (e) { 1.949 + ok(true, "testing duplicated sub element protocol array"); 1.950 + } 1.951 + doTest(33); 1.952 +} 1.953 + 1.954 +function test33() 1.955 +{ 1.956 + var prots=["test33"]; 1.957 + 1.958 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.959 + ws.onopen = function(e) 1.960 + { 1.961 + ok(true, "test 33 open"); 1.962 + ws.close(3131); // pass code but not reason 1.963 + }; 1.964 + 1.965 + ws.onclose = function(e) 1.966 + { 1.967 + ok(true, "test 33 close"); 1.968 + shouldCloseCleanly(e); 1.969 + ok(e.code == 3131, "test 33 got wrong close code: " + e.code); 1.970 + ok(e.reason === "", "test 33 got wrong close reason: " + e.reason); 1.971 + doTest(34); 1.972 + }; 1.973 +} 1.974 + 1.975 +function test34() 1.976 +{ 1.977 + var prots=["test-34"]; 1.978 + 1.979 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.980 + ws.onopen = function(e) 1.981 + { 1.982 + ok(true, "test 34 open"); 1.983 + ws.close(); 1.984 + }; 1.985 + 1.986 + ws.onclose = function(e) 1.987 + { 1.988 + ok(true, "test 34 close"); 1.989 + ok(e.wasClean, "test 34 closed cleanly"); 1.990 + ok(e.code == 1001, "test 34 custom server code"); 1.991 + ok(e.reason == "going away now", "test 34 custom server reason"); 1.992 + doTest(35); 1.993 + }; 1.994 +} 1.995 + 1.996 +function test35() 1.997 +{ 1.998 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-35a"); 1.999 + 1.1000 + ws.onopen = function(e) 1.1001 + { 1.1002 + ok(true, "test 35a open"); 1.1003 + ws.close(3500, "my code"); 1.1004 + }; 1.1005 + 1.1006 + ws.onclose = function(e) 1.1007 + { 1.1008 + ok(true, "test 35a close"); 1.1009 + ok(e.wasClean, "test 35a closed cleanly"); 1.1010 + current_test--; // CreateTestWS for 35a incremented this 1.1011 + var wsb = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-35b"); 1.1012 + 1.1013 + wsb.onopen = function(e) 1.1014 + { 1.1015 + ok(true, "test 35b open"); 1.1016 + wsb.close(); 1.1017 + }; 1.1018 + 1.1019 + wsb.onclose = function(e) 1.1020 + { 1.1021 + ok(true, "test 35b close"); 1.1022 + ok(e.wasClean, "test 35b closed cleanly"); 1.1023 + ok(e.code == 3501, "test 35 custom server code"); 1.1024 + ok(e.reason == "my code", "test 35 custom server reason"); 1.1025 + doTest(36); 1.1026 + }; 1.1027 + } 1.1028 +} 1.1029 + 1.1030 +function test36() 1.1031 +{ 1.1032 + var prots=["test-36"]; 1.1033 + 1.1034 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.1035 + ws.onopen = function(e) 1.1036 + { 1.1037 + ok(true, "test 36 open"); 1.1038 + 1.1039 + try { 1.1040 + ws.close(13200); 1.1041 + ok(false, "testing custom close code out of range"); 1.1042 + } 1.1043 + catch (e) { 1.1044 + ok(true, "testing custom close code out of range"); 1.1045 + ws.close(3200); 1.1046 + } 1.1047 + }; 1.1048 + 1.1049 + ws.onclose = function(e) 1.1050 + { 1.1051 + ok(true, "test 36 close"); 1.1052 + ok(e.wasClean, "test 36 closed cleanly"); 1.1053 + doTest(37); 1.1054 + }; 1.1055 +} 1.1056 + 1.1057 +function test37() 1.1058 +{ 1.1059 + var prots=["test-37"]; 1.1060 + 1.1061 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.1062 + ws.onopen = function(e) 1.1063 + { 1.1064 + ok(true, "test 37 open"); 1.1065 + 1.1066 + try { 1.1067 + ws.close(3100,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"); 1.1068 + ok(false, "testing custom close reason out of range"); 1.1069 + } 1.1070 + catch (e) { 1.1071 + ok(true, "testing custom close reason out of range"); 1.1072 + ws.close(3100,"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"); 1.1073 + } 1.1074 + }; 1.1075 + 1.1076 + ws.onclose = function(e) 1.1077 + { 1.1078 + ok(true, "test 37 close"); 1.1079 + ok(e.wasClean, "test 37 closed cleanly"); 1.1080 + 1.1081 + current_test--; // CreateTestWS for 37 incremented this 1.1082 + var wsb = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-37b"); 1.1083 + 1.1084 + wsb.onopen = function(e) 1.1085 + { 1.1086 + // now test that a rejected close code and reason dont persist 1.1087 + ok(true, "test 37b open"); 1.1088 + try { 1.1089 + wsb.close(3101,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"); 1.1090 + ok(false, "testing custom close reason out of range 37b"); 1.1091 + } 1.1092 + catch (e) { 1.1093 + ok(true, "testing custom close reason out of range 37b"); 1.1094 + wsb.close(); 1.1095 + } 1.1096 + } 1.1097 + 1.1098 + wsb.onclose = function(e) 1.1099 + { 1.1100 + ok(true, "test 37b close"); 1.1101 + ok(e.wasClean, "test 37b closed cleanly"); 1.1102 + 1.1103 + current_test--; // CreateTestWS for 37 incremented this 1.1104 + var wsc = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-37c"); 1.1105 + 1.1106 + wsc.onopen = function(e) 1.1107 + { 1.1108 + ok(true, "test 37c open"); 1.1109 + wsc.close(); 1.1110 + } 1.1111 + 1.1112 + wsc.onclose = function(e) 1.1113 + { 1.1114 + ok(e.code != 3101, "test 37c custom server code not present"); 1.1115 + ok(e.reason == "", "test 37c custom server reason not present"); 1.1116 + doTest(38); 1.1117 + } 1.1118 + } 1.1119 + } 1.1120 +} 1.1121 + 1.1122 +function test38() 1.1123 +{ 1.1124 + var prots=["test-38"]; 1.1125 + 1.1126 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.1127 + ws.onopen = function(e) 1.1128 + { 1.1129 + ok(true, "test 38 open"); 1.1130 + ok(ws.extensions != undefined, "extensions attribute defined"); 1.1131 +// ok(ws.extensions == "deflate-stream", "extensions attribute deflate-stream"); 1.1132 + ws.close(); 1.1133 + }; 1.1134 + 1.1135 + ws.onclose = function(e) 1.1136 + { 1.1137 + ok(true, "test 38 close"); 1.1138 + doTest(39); 1.1139 + }; 1.1140 +} 1.1141 + 1.1142 +function test39() 1.1143 +{ 1.1144 + var prots=["test-39"]; 1.1145 + 1.1146 + var ws = CreateTestWS("wss://example.com/tests/content/base/test/file_websocket", prots); 1.1147 + status_test39 = "started"; 1.1148 + ws.onopen = function(e) 1.1149 + { 1.1150 + status_test39 = "opened"; 1.1151 + ok(true, "test 39 open"); 1.1152 + ws.close(); 1.1153 + }; 1.1154 + 1.1155 + ws.onclose = function(e) 1.1156 + { 1.1157 + ok(true, "test 39 close"); 1.1158 + ok(status_test39 == "opened", "test 39 did open"); 1.1159 + doTest(40); 1.1160 + }; 1.1161 +} 1.1162 + 1.1163 +function test40() 1.1164 +{ 1.1165 + var prots=["test-40"]; 1.1166 + 1.1167 + var ws = CreateTestWS("wss://nocert.example.com/tests/content/base/test/file_websocket", prots); 1.1168 + 1.1169 + status_test40 = "started"; 1.1170 + ws.onerror = ignoreError; 1.1171 + 1.1172 + ws.onopen = function(e) 1.1173 + { 1.1174 + status_test40 = "opened"; 1.1175 + ok(false, "test 40 open"); 1.1176 + ws.close(); 1.1177 + }; 1.1178 + 1.1179 + ws.onclose = function(e) 1.1180 + { 1.1181 + ok(true, "test 40 close"); 1.1182 + ok(status_test40 == "started", "test 40 did not open"); 1.1183 + doTest(41); 1.1184 + }; 1.1185 +} 1.1186 + 1.1187 +function test41() 1.1188 +{ 1.1189 + var ws = CreateTestWS("ws://example.com/tests/content/base/test/file_websocket", "test-41a", 1); 1.1190 + 1.1191 + ws.onopen = function(e) 1.1192 + { 1.1193 + ok(true, "test 41a open"); 1.1194 + ok(ws.url == "ws://example.com/tests/content/base/test/file_websocket", 1.1195 + "test 41a initial ws should not be redirected"); 1.1196 + ws.close(); 1.1197 + }; 1.1198 + 1.1199 + ws.onclose = function(e) 1.1200 + { 1.1201 + ok(true, "test 41a close"); 1.1202 + 1.1203 + // establish a hsts policy for example.com 1.1204 + var wsb = CreateTestWS("wss://example.com/tests/content/base/test/file_websocket", "test-41b", 1); 1.1205 + wsb.onopen = function(e) 1.1206 + { 1.1207 + ok(true, "test 41b open"); 1.1208 + wsb.close(); 1.1209 + } 1.1210 + 1.1211 + wsb.onclose = function(e) 1.1212 + { 1.1213 + ok(true, "test 41b close"); 1.1214 + 1.1215 + // try ws:// again, it should be done over wss:// now due to hsts 1.1216 + var wsc = CreateTestWS("ws://example.com/tests/content/base/test/file_websocket", "test-41c"); 1.1217 + 1.1218 + wsc.onopen = function(e) 1.1219 + { 1.1220 + ok(true, "test 41c open"); 1.1221 + ok(wsc.url == "wss://example.com/tests/content/base/test/file_websocket", 1.1222 + "test 41c ws should be redirected by hsts to wss"); 1.1223 + wsc.close(); 1.1224 + } 1.1225 + 1.1226 + wsc.onclose = function(e) 1.1227 + { 1.1228 + ok(true, "test 41c close"); 1.1229 + 1.1230 + // clean up the STS state 1.1231 + const Cc = SpecialPowers.Cc; 1.1232 + const Ci = SpecialPowers.Ci; 1.1233 + var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); 1.1234 + var thehost = ios.newURI("http://example.com", null, null); 1.1235 + var sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); 1.1236 + var loadContext = SpecialPowers.wrap(window) 1.1237 + .QueryInterface(Ci.nsIInterfaceRequestor) 1.1238 + .getInterface(Ci.nsIWebNavigation) 1.1239 + .QueryInterface(Ci.nsILoadContext); 1.1240 + var flags = 0; 1.1241 + if (loadContext.usePrivateBrowsing) 1.1242 + flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE; 1.1243 + sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, thehost, flags); 1.1244 + doTest(42); 1.1245 + } 1.1246 + } 1.1247 + } 1.1248 +} 1.1249 + 1.1250 +function test42() 1.1251 +{ 1.1252 +// test some utf-8 non-characters. They should be allowed in the 1.1253 +// websockets context. Test via round trip echo. 1.1254 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-42"); 1.1255 + var data = ["U+FFFE \ufffe", 1.1256 + "U+FFFF \uffff", 1.1257 + "U+10FFFF \udbff\udfff"]; 1.1258 + var index = 0; 1.1259 + 1.1260 + ws.onopen = function() 1.1261 + { 1.1262 + ws.send(data[0]); 1.1263 + ws.send(data[1]); 1.1264 + ws.send(data[2]); 1.1265 + } 1.1266 + 1.1267 + ws.onmessage = function(e) 1.1268 + { 1.1269 + ok(e.data == data[index], "bad received message in test-42! index="+index); 1.1270 + index++; 1.1271 + if (index == 3) 1.1272 + ws.close(); 1.1273 + } 1.1274 + 1.1275 + ws.onclose = function(e) 1.1276 + { 1.1277 + doTest(43); 1.1278 + } 1.1279 +} 1.1280 + 1.1281 +function test43() 1.1282 +{ 1.1283 + var prots=["test-43"]; 1.1284 + 1.1285 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots); 1.1286 + ws.onopen = function(e) 1.1287 + { 1.1288 + ok(true, "test 43 open"); 1.1289 + // Test binaryType setting 1.1290 + ws.binaryType = "arraybuffer"; 1.1291 + ws.binaryType = "blob"; 1.1292 + ws.binaryType = ""; // illegal 1.1293 + is(ws.binaryType, "blob"); 1.1294 + ws.binaryType = "ArrayBuffer"; // illegal 1.1295 + is(ws.binaryType, "blob"); 1.1296 + ws.binaryType = "Blob"; // illegal 1.1297 + is(ws.binaryType, "blob"); 1.1298 + ws.binaryType = "mcfoofluu"; // illegal 1.1299 + is(ws.binaryType, "blob"); 1.1300 + ws.close(); 1.1301 + }; 1.1302 + 1.1303 + ws.onclose = function(e) 1.1304 + { 1.1305 + ok(true, "test 43 close"); 1.1306 + doTest(44); 1.1307 + }; 1.1308 +} 1.1309 + 1.1310 + 1.1311 +function test44() 1.1312 +{ 1.1313 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-44"); 1.1314 + ok(ws.readyState == 0, "bad readyState in test-44!"); 1.1315 + ws.binaryType = "arraybuffer"; 1.1316 + ws.onopen = function() 1.1317 + { 1.1318 + ok(ws.readyState == 1, "open bad readyState in test-44!"); 1.1319 + var buf = new ArrayBuffer(3); 1.1320 + // create byte view 1.1321 + var view = new Uint8Array(buf); 1.1322 + view[0] = 5; 1.1323 + view[1] = 0; // null byte 1.1324 + view[2] = 7; 1.1325 + ws.send(buf); 1.1326 + } 1.1327 + ws.onmessage = function(e) 1.1328 + { 1.1329 + ok(e.data instanceof ArrayBuffer, "Should receive an arraybuffer!"); 1.1330 + var view = new Uint8Array(e.data); 1.1331 + ok(view.length == 2 && view[0] == 0 && view[1] ==4, "testing Reply arraybuffer" ); 1.1332 + ws.close(); 1.1333 + } 1.1334 + ws.onclose = function(e) 1.1335 + { 1.1336 + ok(ws.readyState == 3, "onclose bad readyState in test-44!"); 1.1337 + shouldCloseCleanly(e); 1.1338 + doTest(45); 1.1339 + } 1.1340 +} 1.1341 + 1.1342 +function createDOMFile(fileName, fileData) 1.1343 +{ 1.1344 + // create File in profile dir 1.1345 + var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"] 1.1346 + .getService(SpecialPowers.Ci.nsIProperties); 1.1347 + var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile); 1.1348 + testFile.append(fileName); 1.1349 + var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"] 1.1350 + .createInstance(SpecialPowers.Ci.nsIFileOutputStream); 1.1351 + outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0); 1.1352 + outStream.write(fileData, fileData.length); 1.1353 + outStream.close(); 1.1354 + 1.1355 + // Set filename into DOM <input> field, as if selected by user 1.1356 + var fileList = document.getElementById('fileList'); 1.1357 + SpecialPowers.wrap(fileList).value = testFile.path; 1.1358 + 1.1359 + // return JS File object, aka Blob 1.1360 + return fileList.files[0]; 1.1361 +} 1.1362 + 1.1363 +function test45() 1.1364 +{ 1.1365 + var blobFile = createDOMFile("testBlobFile", "flob"); 1.1366 + 1.1367 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-45"); 1.1368 + ok(ws.readyState == 0, "bad readyState in test-45!"); 1.1369 + 1.1370 +// ws.binaryType = "blob"; // Don't need to specify: blob is the default 1.1371 + 1.1372 + ws.onopen = function() 1.1373 + { 1.1374 + ok(ws.readyState == 1, "open bad readyState in test-45!"); 1.1375 + ws.send(blobFile); 1.1376 + } 1.1377 + 1.1378 + var test45blob; 1.1379 + 1.1380 + ws.onmessage = function(e) 1.1381 + { 1.1382 + test45blob = e.data; 1.1383 + ok(test45blob instanceof Blob, "We should be receiving a Blob"); 1.1384 + 1.1385 + ws.close(); 1.1386 + } 1.1387 + 1.1388 + ws.onclose = function(e) 1.1389 + { 1.1390 + ok(ws.readyState == 3, "onclose bad readyState in test-45!"); 1.1391 + shouldCloseCleanly(e); 1.1392 + 1.1393 + // check blob contents 1.1394 + var reader = new FileReader(); 1.1395 + reader.onload = function(event) 1.1396 + { 1.1397 + ok(reader.result == "flob", "response should be 'flob': got '" 1.1398 + + reader.result + "'"); 1.1399 + }; 1.1400 + reader.onerror = function(event) 1.1401 + { 1.1402 + testFailed("Failed to read blob: error code = " + reader.error.code); 1.1403 + }; 1.1404 + reader.onloadend = function(event) 1.1405 + { 1.1406 + doTest(46); 1.1407 + }; 1.1408 + 1.1409 + reader.readAsBinaryString(test45blob); 1.1410 + } 1.1411 +} 1.1412 + 1.1413 +function test46() 1.1414 +{ 1.1415 + var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-46"); 1.1416 + ok(ws.readyState == 0, "create bad readyState in test-46!"); 1.1417 + ws.onopen = function() 1.1418 + { 1.1419 + ok(ws.readyState == 1, "open bad readyState in test-46!"); 1.1420 + ws.close() 1.1421 + ok(ws.readyState == 2, "close must set readyState to 2 in test-46!"); 1.1422 + } 1.1423 + ws.onmessage = function(e) 1.1424 + { 1.1425 + ok(false, "received message after calling close in test-46!"); 1.1426 + } 1.1427 + ws.onclose = function(e) 1.1428 + { 1.1429 + ok(ws.readyState == 3, "onclose bad readyState in test-46!"); 1.1430 + shouldCloseCleanly(e); 1.1431 + doTest(47); 1.1432 + } 1.1433 +} 1.1434 + 1.1435 +function test47() 1.1436 +{ 1.1437 + var hasError = false; 1.1438 + var ws = CreateTestWS("ws://another.websocket.server.that.probably.does.not.exist"); 1.1439 + ws.onopen = shouldNotOpen; 1.1440 + 1.1441 + ws.onerror = function (e) 1.1442 + { 1.1443 + ok(ws.readyState == 3, "test-47: readyState should be CLOSED(3) in onerror: got " 1.1444 + + ws.readyState); 1.1445 + ok(!ws._withinClose, "onerror() called during close()!"); 1.1446 + hasError = true; 1.1447 + } 1.1448 + 1.1449 + ws.onclose = function(e) 1.1450 + { 1.1451 + shouldCloseNotCleanly(e); 1.1452 + ok(hasError, "test-47: should have called onerror before onclose"); 1.1453 + ok(ws.readyState == 3, "test-47: readyState should be CLOSED(3) in onclose: got " 1.1454 + + ws.readyState); 1.1455 + ok(!ws._withinClose, "onclose() called during close()!"); 1.1456 + ok(e.code == 1006, "test-47 close code should be 1006 but is:" + e.code); 1.1457 + doTest(48); 1.1458 + }; 1.1459 + 1.1460 + // Call close before we're connected: throws error 1.1461 + // Make sure we call onerror/onclose asynchronously 1.1462 + ws._withinClose = 1; 1.1463 + ws.close(3333, "Closed before we were open: error"); 1.1464 + ws._withinClose = 0; 1.1465 + ok(ws.readyState == 2, "test-47: readyState should be CLOSING(2) after close(): got " 1.1466 + + ws.readyState); 1.1467 +} 1.1468 + 1.1469 + 1.1470 +var ranAllTests = false; 1.1471 + 1.1472 +function maybeFinished() 1.1473 +{ 1.1474 + if (!ranAllTests) 1.1475 + return; 1.1476 + 1.1477 + if (waitTest2Part1 || waitTest2Part2 || waitTest9 || waitTest10 || 1.1478 + waitTest17 || waitTest20 || waitTest21 || waitTest22) 1.1479 + return; 1.1480 + 1.1481 + for (i = 0; i < all_ws.length; ++i) { 1.1482 + if (all_ws[i] != shouldNotReceiveCloseEvent && 1.1483 + !all_ws[i]._receivedCloseEvent) { 1.1484 + ok(false, "didn't called close on test " + all_ws[i]._testNumber + "!"); 1.1485 + } 1.1486 + } 1.1487 + 1.1488 + if (testsuite_iteration++ < testsuite_iterations) { 1.1489 + // play it again, Sam... 1.1490 + ok(1, "starting testsuite iteration " + testsuite_iteration); 1.1491 + test_started = new Array(last_test); 1.1492 + doTest(current_test = first_test); 1.1493 + } else { 1.1494 + // all done 1.1495 + SimpleTest.finish(); 1.1496 + } 1.1497 +} 1.1498 + 1.1499 +function testWebSocket () 1.1500 +{ 1.1501 + doTest(first_test); 1.1502 +} 1.1503 + 1.1504 +SimpleTest.waitForExplicitFinish(); 1.1505 + 1.1506 +</script> 1.1507 +</pre> 1.1508 + 1.1509 +<div id="feedback"> 1.1510 +</div> 1.1511 + 1.1512 +</body> 1.1513 +</html>