1import time 2import struct 3import unittest 4from unit.applications.lang.node import TestApplicationNode 5from unit.applications.websockets import TestApplicationWebsocket 6 7class TestNodeWebsockets(TestApplicationNode): 8 prerequisites = ['node'] 9 10 ws = TestApplicationWebsocket() 11 12 def setUp(self): 13 super().setUp() 14 15 self.skip_alerts.extend( 16 [ 17 r'last message send failed', 18 r'socket close\(\d+\) failed', 19 ] 20 ) 21 22 def close_connection(self, sock): 23 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty sock') 24 25 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 26 27 self.check_close(sock) 28 29 def check_close(self, sock, code = 1000, no_close = False): 30 frame = self.ws.frame_read(sock) 31 32 self.assertEqual(frame['fin'], True, 'close fin') 33 self.assertEqual(frame['opcode'], self.ws.OP_CLOSE, 'close opcode') 34 self.assertEqual(frame['code'], code, 'close code') 35 36 if not no_close: 37 sock.close() 38 39 def check_frame(self, frame, fin, opcode, payload, decode=True): 40 if opcode == self.ws.OP_BINARY or not decode: 41 data = frame['data'] 42 else: 43 data = frame['data'].decode('utf-8') 44 45 self.assertEqual(frame['fin'], fin, 'fin') 46 self.assertEqual(frame['opcode'], opcode, 'opcode') 47 self.assertEqual(data, payload, 'payload') 48 49 def test_node_websockets_handshake(self): 50 self.load('websockets/mirror') 51 52 resp, sock, key = self.ws.upgrade() 53 sock.close() 54 55 self.assertEqual(resp['status'], 101, 'status') 56 self.assertEqual( 57 resp['headers']['Upgrade'], 'websocket', 'upgrade' 58 ) 59 self.assertEqual( 60 resp['headers']['Connection'], 'Upgrade', 'connection' 61 ) 62 self.assertEqual( 63 resp['headers']['Sec-WebSocket-Accept'], self.ws.accept(key), 'key' 64 ) 65 66 def test_node_websockets_mirror(self): 67 self.load('websockets/mirror') 68 69 message = 'blah' 70 71 _, sock, _ = self.ws.upgrade() 72 73 self.ws.frame_write(sock, self.ws.OP_TEXT, message) 74 frame = self.ws.frame_read(sock) 75 76 self.assertEqual( 77 message, frame['data'].decode('utf-8'), 'mirror' 78 ) 79 80 self.ws.frame_write(sock, self.ws.OP_TEXT, message) 81 frame = self.ws.frame_read(sock) 82 83 self.assertEqual( 84 message, frame['data'].decode('utf-8'), 'mirror 2' 85 ) 86 87 sock.close() 88 89 def test_node_websockets_no_mask(self): 90 self.load('websockets/mirror') 91 92 message = 'blah' 93 94 _, sock, _ = self.ws.upgrade() 95 96 self.ws.frame_write(sock, self.ws.OP_TEXT, message, mask=False) 97 98 frame = self.ws.frame_read(sock) 99 100 self.assertEqual(frame['opcode'], self.ws.OP_CLOSE, 'no mask opcode') 101 self.assertEqual(frame['code'], 1002, 'no mask close code') 102 103 sock.close() 104 105 def test_node_websockets_fragmentation(self): 106 self.load('websockets/mirror') 107 108 message = 'blah' 109 110 _, sock, _ = self.ws.upgrade() 111 112 self.ws.frame_write(sock, self.ws.OP_TEXT, message, fin=False) 113 self.ws.frame_write(sock, self.ws.OP_CONT, ' ', fin=False) 114 self.ws.frame_write(sock, self.ws.OP_CONT, message) 115 116 frame = self.ws.frame_read(sock) 117 118 self.assertEqual( 119 message + ' ' + message, 120 frame['data'].decode('utf-8'), 121 'mirror framing', 122 ) 123 124 sock.close() 125 126 def test_node_websockets_frame_fragmentation_invalid(self): 127 self.load('websockets/mirror') 128 129 message = 'blah' 130 131 _, sock, _ = self.ws.upgrade() 132 133 self.ws.frame_write(sock, self.ws.OP_PING, message, fin=False) 134 135 frame = self.ws.frame_read(sock) 136 137 frame.pop('data') 138 self.assertDictEqual( 139 frame, 140 { 141 'fin': True, 142 'rsv1': False, 143 'rsv2': False, 144 'rsv3': False, 145 'opcode': self.ws.OP_CLOSE, 146 'mask': 0, 147 'code': 1002, 148 'reason': 'Fragmented control frame', 149 }, 150 'close frame', 151 ) 152 153 sock.close() 154 155 def test_node_websockets_partial_send(self): 156 self.load('websockets/mirror') 157 158 message = 'blah' 159 160 _, sock, _ = self.ws.upgrade() 161 162 frame = self.ws.frame_to_send(self.ws.OP_TEXT, message) 163 sock.sendall(frame[:1]) 164 sock.sendall(frame[1:2]) 165 sock.sendall(frame[2:3]) 166 sock.sendall(frame[3:]) 167 168 frame = self.ws.frame_read(sock) 169 170 self.assertEqual( 171 message, 172 frame['data'].decode('utf-8'), 173 'partial send', 174 ) 175 176 sock.close() 177 178 def test_node_websockets_large(self): 179 self.load('websockets/mirror_fragmentation') 180 181 message = '0123456789' * 3000 182 183 _, sock, _ = self.ws.upgrade() 184 185 self.ws.frame_write(sock, self.ws.OP_TEXT, message) 186 187 frame = self.ws.frame_read(sock) 188 data = frame['data'].decode('utf-8') 189 190 frame = self.ws.frame_read(sock) 191 data += frame['data'].decode('utf-8') 192 193 self.assertEqual(message, data, 'large') 194 195 sock.close() 196 197 def test_node_websockets_frame_invalid_opcode(self): 198 self.load('websockets/mirror') 199 200 message = 'blah' 201 202 _, sock, _ = self.ws.upgrade() 203 204 self.ws.frame_write(sock, self.ws.OP_TEXT, message, fin=False) 205 self.ws.frame_write(sock, self.ws.OP_TEXT, message) 206 207 frame = self.ws.frame_read(sock) 208 209 frame.pop('data') 210 frame.pop('reason') 211 self.assertDictEqual( 212 frame, 213 { 214 'fin': True, 215 'rsv1': False, 216 'rsv2': False, 217 'rsv3': False, 218 'opcode': self.ws.OP_CLOSE, 219 'mask': 0, 220 'code': 1002, 221 }, 222 'close frame', 223 ) 224 225 sock.close() 226 227 def test_node_websockets_frame_invalid_opcode_2(self): 228 self.load('websockets/mirror') 229 230 message = 'blah' 231 232 _, sock, _ = self.ws.upgrade() 233 234 self.ws.frame_write(sock, self.ws.OP_CONT, message) 235 236 frame = self.ws.frame_read(sock) 237 238 frame.pop('data') 239 self.assertDictEqual( 240 frame, 241 { 242 'fin': True, 243 'rsv1': False, 244 'rsv2': False, 245 'rsv3': False, 246 'opcode': self.ws.OP_CLOSE, 247 'mask': 0, 248 'code': 1002, 249 'reason': 'Unrecognized opcode 0', 250 }, 251 'close frame', 252 ) 253 254 sock.close() 255 256 def test_node_websockets_two_clients(self): 257 self.load('websockets/mirror') 258 259 message1 = 'blah1' 260 message2 = 'blah2' 261 262 _, sock1, _ = self.ws.upgrade() 263 _, sock2, _ = self.ws.upgrade() 264 265 self.ws.frame_write(sock1, self.ws.OP_TEXT, message1) 266 self.ws.frame_write(sock2, self.ws.OP_TEXT, message2) 267 268 frame1 = self.ws.frame_read(sock1) 269 frame2 = self.ws.frame_read(sock2) 270 271 self.assertEqual( 272 message1, frame1['data'].decode('utf-8'), 'client 1' 273 ) 274 self.assertEqual( 275 message2, frame2['data'].decode('utf-8'), 'client 2' 276 ) 277 278 sock1.close() 279 sock2.close() 280 281 @unittest.skip('not yet') 282 def test_node_websockets_handshake_upgrade_absent(self): # FAIL https://tools.ietf.org/html/rfc6455#section-4.2.1 283 self.load('websockets/mirror') 284 285 key = self.ws.key() 286 resp = self.get(headers={ 287 'Host': 'localhost', 288 'Connection': 'Upgrade', 289 'Sec-WebSocket-Key': key, 290 'Sec-WebSocket-Protocol': 'chat', 291 'Sec-WebSocket-Version': 13, 292 }, read_timeout=1) 293 294 self.assertEqual(resp['status'], 400, 'upgrade absent') 295 296 def test_node_websockets_handshake_case_insensitive(self): 297 self.load('websockets/mirror') 298 299 key = self.ws.key() 300 resp = self.get(headers={ 301 'Host': 'localhost', 302 'Upgrade': 'WEBSOCKET', 303 'Connection': 'UPGRADE', 304 'Sec-WebSocket-Key': key, 305 'Sec-WebSocket-Protocol': 'chat', 306 'Sec-WebSocket-Version': 13, 307 }, read_timeout=1) 308 309 self.assertEqual(resp['status'], 101, 'status') 310 311 @unittest.skip('not yet') 312 def test_node_websockets_handshake_connection_absent(self): # FAIL 313 self.load('websockets/mirror') 314 315 key = self.ws.key() 316 resp = self.get(headers={ 317 'Host': 'localhost', 318 'Upgrade': 'websocket', 319 'Sec-WebSocket-Key': key, 320 'Sec-WebSocket-Protocol': 'chat', 321 'Sec-WebSocket-Version': 13, 322 }, read_timeout=1) 323 324 self.assertEqual(resp['status'], 400, 'status') 325 326 def test_node_websockets_handshake_version_absent(self): 327 self.load('websockets/mirror') 328 329 key = self.ws.key() 330 resp = self.get(headers={ 331 'Host': 'localhost', 332 'Upgrade': 'websocket', 333 'Connection': 'Upgrade', 334 'Sec-WebSocket-Key': key, 335 'Sec-WebSocket-Protocol': 'chat' 336 }, read_timeout=1) 337 338 self.assertEqual(resp['status'], 426, 'status') 339 340 @unittest.skip('not yet') 341 def test_node_websockets_handshake_key_invalid(self): 342 self.load('websockets/mirror') 343 344 resp = self.get(headers={ 345 'Host': 'localhost', 346 'Upgrade': 'websocket', 347 'Connection': 'Upgrade', 348 'Sec-WebSocket-Key': '!', 349 'Sec-WebSocket-Protocol': 'chat', 350 'Sec-WebSocket-Version': 13 351 }, read_timeout=1) 352 353 self.assertEqual(resp['status'], 400, 'key length') 354 355 key = self.ws.key() 356 resp = self.get(headers={ 357 'Host': 'localhost', 358 'Upgrade': 'websocket', 359 'Connection': 'Upgrade', 360 'Sec-WebSocket-Key': [key, key], 361 'Sec-WebSocket-Protocol': 'chat', 362 'Sec-WebSocket-Version': 13 363 }, read_timeout=1) 364 365 self.assertEqual(resp['status'], 400, 'key double') # FAIL https://tools.ietf.org/html/rfc6455#section-11.3.1 366 367 def test_node_websockets_handshake_method_invalid(self): 368 self.load('websockets/mirror') 369 370 key = self.ws.key() 371 resp = self.post(headers={ 372 'Host': 'localhost', 373 'Upgrade': 'websocket', 374 'Connection': 'Upgrade', 375 'Sec-WebSocket-Key': key, 376 'Sec-WebSocket-Protocol': 'chat', 377 'Sec-WebSocket-Version': 13 378 }, read_timeout=1) 379 380 self.assertEqual(resp['status'], 400, 'status') 381 382 def test_node_websockets_handshake_http_10(self): 383 self.load('websockets/mirror') 384 385 key = self.ws.key() 386 resp = self.get(headers={ 387 'Host': 'localhost', 388 'Upgrade': 'websocket', 389 'Connection': 'Upgrade', 390 'Sec-WebSocket-Key': key, 391 'Sec-WebSocket-Protocol': 'chat', 392 'Sec-WebSocket-Version': 13 393 }, http_10=True, read_timeout=1) 394 395 self.assertEqual(resp['status'], 400, 'status') 396 397 def test_node_websockets_handshake_uri_invalid(self): 398 self.load('websockets/mirror') 399 400 key = self.ws.key() 401 resp = self.get(headers={ 402 'Host': 'localhost', 403 'Upgrade': 'websocket', 404 'Connection': 'Upgrade', 405 'Sec-WebSocket-Key': key, 406 'Sec-WebSocket-Protocol': 'chat', 407 'Sec-WebSocket-Version': 13 408 }, url='!', read_timeout=1) 409 410 self.assertEqual(resp['status'], 400, 'status') 411 412 def test_node_websockets_protocol_absent(self): 413 self.load('websockets/mirror') 414 415 key = self.ws.key() 416 resp = self.get(headers={ 417 'Host': 'localhost', 418 'Upgrade': 'websocket', 419 'Connection': 'Upgrade', 420 'Sec-WebSocket-Key': key, 421 'Sec-WebSocket-Version': 13 422 }, read_timeout=1) 423 424 self.assertEqual(resp['status'], 101, 'status') 425 self.assertEqual( 426 resp['headers']['Upgrade'], 'websocket', 'upgrade' 427 ) 428 self.assertEqual( 429 resp['headers']['Connection'], 'Upgrade', 'connection' 430 ) 431 self.assertEqual( 432 resp['headers']['Sec-WebSocket-Accept'], self.ws.accept(key), 'key' 433 ) 434 435 # autobahn-testsuite 436 437 # Some following tests fail because of Unit does not support UTF-8 438 # validation for websocket frames. It should be implemented 439 # by application, if necessary. 440 441 @unittest.skip('not yet') 442 def test_node_websockets_1_1_1__1_1_8(self): 443 self.load('websockets/mirror') 444 445 opcode = self.ws.OP_TEXT 446 447 _, sock, _ = self.ws.upgrade() 448 449 def check_length(length, chopsize=None): 450 payload = '*' * length 451 452 self.ws.frame_write(sock, opcode, payload, chopsize=chopsize) 453 454 frame = self.ws.frame_read(sock) 455 self.check_frame(frame, True, opcode, payload) 456 457 check_length(0) # 1_1_1 458 check_length(125) # 1_1_2 459 check_length(126) # 1_1_3 460 check_length(127) # 1_1_4 461 check_length(128) # 1_1_5 462 check_length(65535) # 1_1_6 463 check_length(65536) # 1_1_7 464 check_length(65536, chopsize = 997) # 1_1_8 465 466 self.close_connection(sock) 467 468 @unittest.skip('not yet') 469 def test_node_websockets_1_2_1__1_2_8(self): 470 self.load('websockets/mirror') 471 472 opcode = self.ws.OP_BINARY 473 474 _, sock, _ = self.ws.upgrade() 475 476 def check_length(length, chopsize=None): 477 payload = b'\xfe' * length 478 479 self.ws.frame_write(sock, opcode, payload, chopsize=chopsize) 480 frame = self.ws.frame_read(sock) 481 482 self.check_frame(frame, True, opcode, payload) 483 484 check_length(0) # 1_2_1 485 check_length(125) # 1_2_2 486 check_length(126) # 1_2_3 487 check_length(127) # 1_2_4 488 check_length(128) # 1_2_5 489 check_length(65535) # 1_2_6 490 check_length(65536) # 1_2_7 491 check_length(65536, chopsize = 997) # 1_2_8 492 493 self.close_connection(sock) 494 495 def test_node_websockets_2_1__2_6(self): 496 self.load('websockets/mirror') 497 498 op_ping = self.ws.OP_PING 499 op_pong = self.ws.OP_PONG 500 501 _, sock, _ = self.ws.upgrade() 502 503 def check_ping(payload, chopsize=None, decode=True): 504 self.ws.frame_write(sock, op_ping, payload, chopsize=chopsize) 505 frame = self.ws.frame_read(sock) 506 507 self.check_frame(frame, True, op_pong, payload, decode=decode) 508 509 check_ping('') # 2_1 510 check_ping('Hello, world!') # 2_2 511 check_ping(b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff', decode=False) # 2_3 512 check_ping(b'\xfe' * 125, decode=False) # 2_4 513 check_ping(b'\xfe' * 125, chopsize=1, decode=False) # 2_6 514 515 self.close_connection(sock) 516 517 # 2_5 518 519 _, sock, _ = self.ws.upgrade() 520 521 self.ws.frame_write(sock, self.ws.OP_PING, b'\xfe' * 126) 522 self.check_close(sock, 1002) 523 524 def test_node_websockets_2_7__2_9(self): 525 self.load('websockets/mirror') 526 527 # 2_7 528 529 _, sock, _ = self.ws.upgrade() 530 531 self.ws.frame_write(sock, self.ws.OP_PONG, '') 532 self.assertEqual(self.recvall(sock, read_timeout=1), b'', '2_7') 533 534 # 2_8 535 536 self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload') 537 self.assertEqual(self.recvall(sock, read_timeout=1), b'', '2_8') 538 539 # 2_9 540 541 payload = 'ping payload' 542 543 self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload') 544 self.ws.frame_write(sock, self.ws.OP_PING, payload) 545 546 frame = self.ws.frame_read(sock) 547 self.check_frame(frame, True, self.ws.OP_PONG, payload) 548 549 self.close_connection(sock) 550 551 def test_node_websockets_2_10__2_11(self): 552 self.load('websockets/mirror') 553 554 # 2_10 555 556 _, sock, _ = self.ws.upgrade() 557 558 for i in range(0, 10): 559 self.ws.frame_write(sock, self.ws.OP_PING, 'payload-%d' % i) 560 561 for i in range(0, 10): 562 frame = self.ws.frame_read(sock) 563 self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) 564 565 # 2_11 566 567 for i in range(0, 10): 568 opcode = self.ws.OP_PING 569 self.ws.frame_write(sock, opcode, 'payload-%d' % i, chopsize=1) 570 571 for i in range(0, 10): 572 frame = self.ws.frame_read(sock) 573 self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) 574 575 self.close_connection(sock) 576 577 @unittest.skip('not yet') 578 def test_node_websockets_3_1__3_7(self): 579 self.load('websockets/mirror') 580 581 payload = 'Hello, world!' 582 583 # 3_1 584 585 _, sock, _ = self.ws.upgrade() 586 587 self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv1=True) 588 self.check_close(sock, 1002) 589 590 # 3_2 591 592 _, sock, _ = self.ws.upgrade() 593 594 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 595 self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv2=True) 596 self.ws.frame_write(sock, self.ws.OP_PING, '') 597 598 frame = self.ws.frame_read(sock) 599 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 600 601 self.check_close(sock, 1002, no_close = True) 602 603 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty 3_2') 604 sock.close() 605 606 # 3_3 607 608 _, sock, _ = self.ws.upgrade() 609 610 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 611 612 frame = self.ws.frame_read(sock) 613 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 614 615 self.ws.frame_write( 616 sock, 617 self.ws.OP_TEXT, 618 payload, 619 rsv1=True, 620 rsv2=True, 621 ) 622 623 self.check_close(sock, 1002, no_close = True) 624 625 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty 3_3') 626 sock.close() 627 628 # 3_4 629 630 _, sock, _ = self.ws.upgrade() 631 632 self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1) 633 self.ws.frame_write( 634 sock, 635 self.ws.OP_TEXT, 636 payload, 637 rsv3=True, 638 chopsize=1 639 ) 640 self.ws.frame_write(sock, self.ws.OP_PING, '') 641 642 frame = self.ws.frame_read(sock) 643 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 644 645 self.check_close(sock, 1002, no_close = True) 646 647 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty 3_4') 648 sock.close() 649 650 # 3_5 651 652 _, sock, _ = self.ws.upgrade() 653 654 self.ws.frame_write( 655 sock, 656 self.ws.OP_BINARY, 657 b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff', 658 rsv1=True, 659 rsv3=True, 660 ) 661 662 self.check_close(sock, 1002) 663 664 # 3_6 665 666 _, sock, _ = self.ws.upgrade() 667 668 self.ws.frame_write( 669 sock, 670 self.ws.OP_PING, 671 payload, 672 rsv2=True, 673 rsv3=True, 674 ) 675 676 self.check_close(sock, 1002) 677 678 # 3_7 679 680 _, sock, _ = self.ws.upgrade() 681 682 self.ws.frame_write( 683 sock, 684 self.ws.OP_CLOSE, 685 payload, 686 rsv1=True, 687 rsv2=True, 688 rsv3=True, 689 ) 690 691 self.check_close(sock, 1002) 692 693 def test_node_websockets_4_1_1__4_2_5(self): 694 self.load('websockets/mirror') 695 696 payload = 'Hello, world!' 697 698 # 4_1_1 699 700 _, sock, _ = self.ws.upgrade() 701 702 self.ws.frame_write(sock, 0x03, '') 703 self.check_close(sock, 1002) 704 705 # 4_1_2 706 707 _, sock, _ = self.ws.upgrade() 708 709 self.ws.frame_write(sock, 0x04, 'reserved opcode payload') 710 self.check_close(sock, 1002) 711 712 # 4_1_3 713 714 _, sock, _ = self.ws.upgrade() 715 716 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 717 718 frame = self.ws.frame_read(sock) 719 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 720 721 self.ws.frame_write(sock, 0x05, '') 722 self.ws.frame_write(sock, self.ws.OP_PING, '') 723 724 self.check_close(sock, 1002) 725 726 # 4_1_4 727 728 _, sock, _ = self.ws.upgrade() 729 730 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 731 732 frame = self.ws.frame_read(sock) 733 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 734 735 self.ws.frame_write(sock, 0x06, payload) 736 self.ws.frame_write(sock, self.ws.OP_PING, '') 737 738 self.check_close(sock, 1002) 739 740 # 4_1_5 741 742 _, sock, _ = self.ws.upgrade() 743 744 self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1) 745 746 frame = self.ws.frame_read(sock) 747 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 748 749 self.ws.frame_write(sock, 0x07, payload, chopsize=1) 750 self.ws.frame_write(sock, self.ws.OP_PING, '') 751 752 self.check_close(sock, 1002) 753 754 # 4_2_1 755 756 _, sock, _ = self.ws.upgrade() 757 758 self.ws.frame_write(sock, 0x0B, '') 759 self.check_close(sock, 1002) 760 761 # 4_2_2 762 763 _, sock, _ = self.ws.upgrade() 764 765 self.ws.frame_write(sock, 0x0C, 'reserved opcode payload') 766 self.check_close(sock, 1002) 767 768 # 4_2_3 769 770 _, sock, _ = self.ws.upgrade() 771 772 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 773 774 frame = self.ws.frame_read(sock) 775 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 776 777 self.ws.frame_write(sock, 0x0D, '') 778 self.ws.frame_write(sock, self.ws.OP_PING, '') 779 780 self.check_close(sock, 1002) 781 782 # 4_2_4 783 784 _, sock, _ = self.ws.upgrade() 785 786 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 787 788 frame = self.ws.frame_read(sock) 789 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 790 791 self.ws.frame_write(sock, 0x0E, payload) 792 self.ws.frame_write(sock, self.ws.OP_PING, '') 793 794 self.check_close(sock, 1002) 795 796 # 4_2_5 797 798 _, sock, _ = self.ws.upgrade() 799 800 self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1) 801 802 frame = self.ws.frame_read(sock) 803 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 804 805 self.ws.frame_write(sock, 0x0F, payload, chopsize=1) 806 self.ws.frame_write(sock, self.ws.OP_PING, '') 807 808 self.check_close(sock, 1002) 809 810 @unittest.skip('not yet') 811 def test_node_websockets_5_1__5_20(self): 812 self.load('websockets/mirror') 813 814 # 5_1 815 816 _, sock, _ = self.ws.upgrade() 817 818 self.ws.frame_write(sock, self.ws.OP_PING, 'fragment1', fin=False) 819 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 820 self.check_close(sock, 1002) 821 822 # 5_2 823 824 _, sock, _ = self.ws.upgrade() 825 826 self.ws.frame_write(sock, self.ws.OP_PONG, 'fragment1', fin=False) 827 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 828 self.check_close(sock, 1002) 829 830 # 5_3 831 832 _, sock, _ = self.ws.upgrade() 833 834 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 835 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 836 837 frame = self.ws.frame_read(sock) 838 self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 839 840 # 5_4 841 842 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 843 self.assertEqual(self.recvall(sock, read_timeout=1), b'', '5_4') 844 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 845 846 frame = self.ws.frame_read(sock) 847 self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 848 849 # 5_5 850 851 self.ws.frame_write( 852 sock, 853 self.ws.OP_TEXT, 854 'fragment1', 855 fin=False, 856 chopsize=1, 857 ) 858 self.ws.frame_write( 859 sock, 860 self.ws.OP_CONT, 861 'fragment2', 862 fin=True, 863 chopsize=1, 864 ) 865 866 frame = self.ws.frame_read(sock) 867 self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 868 869 # 5_6 870 871 ping_payload = 'ping payload' 872 873 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 874 self.ws.frame_write(sock, self.ws.OP_PING, ping_payload) 875 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 876 877 frame = self.ws.frame_read(sock) 878 self.check_frame(frame, True, self.ws.OP_PONG, ping_payload) 879 880 frame = self.ws.frame_read(sock) 881 self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 882 883 # 5_7 884 885 ping_payload = 'ping payload' 886 887 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 888 self.assertEqual(self.recvall(sock, read_timeout=1), b'', '5_7') 889 890 self.ws.frame_write(sock, self.ws.OP_PING, ping_payload) 891 892 frame = self.ws.frame_read(sock) 893 self.check_frame(frame, True, self.ws.OP_PONG, ping_payload) 894 895 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 896 897 frame = self.ws.frame_read(sock) 898 self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 899 900 # 5_8 901 902 ping_payload = 'ping payload' 903 904 self.ws.frame_write( 905 sock, 906 self.ws.OP_TEXT, 907 'fragment1', 908 fin=False, 909 chopsize=1, 910 ) 911 self.ws.frame_write(sock, self.ws.OP_PING, ping_payload, chopsize=1) 912 self.ws.frame_write( 913 sock, 914 self.ws.OP_CONT, 915 'fragment2', 916 fin=True, 917 chopsize=1, 918 ) 919 920 frame = self.ws.frame_read(sock) 921 self.check_frame(frame, True, self.ws.OP_PONG, ping_payload) 922 923 frame = self.ws.frame_read(sock) 924 self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 925 926 # 5_9 927 928 self.ws.frame_write( 929 sock, 930 self.ws.OP_CONT, 931 'non-continuation payload', 932 fin=True, 933 ) 934 self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 935 self.check_close(sock, 1002) 936 937 # 5_10 938 939 _, sock, _ = self.ws.upgrade() 940 941 self.ws.frame_write( 942 sock, 943 self.ws.OP_CONT, 944 'non-continuation payload', 945 fin=True, 946 ) 947 self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 948 self.check_close(sock, 1002) 949 950 # 5_11 951 952 _, sock, _ = self.ws.upgrade() 953 954 self.ws.frame_write( 955 sock, 956 self.ws.OP_CONT, 957 'non-continuation payload', 958 fin=True, 959 chopsize=1, 960 ) 961 self.ws.frame_write( 962 sock, 963 self.ws.OP_TEXT, 964 'Hello, world!', 965 fin=True, 966 chopsize=1, 967 ) 968 self.check_close(sock, 1002) 969 970 # 5_12 971 972 _, sock, _ = self.ws.upgrade() 973 974 self.ws.frame_write( 975 sock, 976 self.ws.OP_CONT, 977 'non-continuation payload', 978 fin=False, 979 ) 980 self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 981 self.check_close(sock, 1002) 982 983 # 5_13 984 985 _, sock, _ = self.ws.upgrade() 986 987 self.ws.frame_write( 988 sock, 989 self.ws.OP_CONT, 990 'non-continuation payload', 991 fin=False, 992 ) 993 self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 994 self.check_close(sock, 1002) 995 996 # 5_14 997 998 _, sock, _ = self.ws.upgrade() 999 1000 self.ws.frame_write( 1001 sock, 1002 self.ws.OP_CONT, 1003 'non-continuation payload', 1004 fin=False, 1005 chopsize=1, 1006 ) 1007 self.ws.frame_write( 1008 sock, 1009 self.ws.OP_TEXT, 1010 'Hello, world!', 1011 fin=True, 1012 chopsize=1, 1013 ) 1014 self.check_close(sock, 1002) 1015 1016 # 5_15 1017 1018 _, sock, _ = self.ws.upgrade() 1019 1020 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 1021 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 1022 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 1023 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment4', fin=True) 1024 self.check_close(sock, 1002) 1025 1026 # 5_16 1027 1028 _, sock, _ = self.ws.upgrade() 1029 1030 for i in range(0, 2): 1031 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=False) 1032 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False) 1033 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True) 1034 self.check_close(sock, 1002) 1035 1036 # 5_17 1037 1038 _, sock, _ = self.ws.upgrade() 1039 1040 for i in range(0, 2): 1041 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=True) 1042 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False) 1043 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True) 1044 self.check_close(sock, 1002) 1045 1046 # 5_18 1047 1048 _, sock, _ = self.ws.upgrade() 1049 1050 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 1051 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2') 1052 self.check_close(sock, 1002) 1053 1054 # 5_19 1055 1056 _, sock, _ = self.ws.upgrade() 1057 1058 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 1059 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False) 1060 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!') 1061 1062 time.sleep(1) 1063 1064 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 1065 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False) 1066 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!') 1067 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5') 1068 1069 frame = self.ws.frame_read(sock) 1070 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!') 1071 1072 frame = self.ws.frame_read(sock) 1073 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!') 1074 1075 self.check_frame( 1076 self.ws.frame_read(sock), 1077 True, 1078 self.ws.OP_TEXT, 1079 'fragment1fragment2fragment3fragment4fragment5', 1080 ) 1081 1082 # 5_20 1083 1084 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 1085 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False) 1086 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!') 1087 1088 frame = self.ws.frame_read(sock) 1089 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!') 1090 1091 time.sleep(1) 1092 1093 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 1094 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False) 1095 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!') 1096 1097 frame = self.ws.frame_read(sock) 1098 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!') 1099 1100 self.assertEqual(self.recvall(sock, read_timeout=1), b'', '5_20') 1101 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5') 1102 1103 self.check_frame( 1104 self.ws.frame_read(sock), 1105 True, 1106 self.ws.OP_TEXT, 1107 'fragment1fragment2fragment3fragment4fragment5', 1108 ) 1109 1110 self.close_connection(sock) 1111 1112 def test_node_websockets_6_1_1__6_4_4(self): 1113 self.load('websockets/mirror') 1114 1115 # 6_1_1 1116 1117 _, sock, _ = self.ws.upgrade() 1118 1119 self.ws.frame_write(sock, self.ws.OP_TEXT, '') 1120 frame = self.ws.frame_read(sock) 1121 self.check_frame(frame, True, self.ws.OP_TEXT, '') 1122 1123 # 6_1_2 1124 1125 self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False) 1126 self.ws.frame_write(sock, self.ws.OP_CONT, '', fin=False) 1127 self.ws.frame_write(sock, self.ws.OP_CONT, '') 1128 1129 frame = self.ws.frame_read(sock) 1130 self.check_frame(frame, True, self.ws.OP_TEXT, '') 1131 1132 # 6_1_3 1133 1134 payload = 'middle frame payload' 1135 1136 self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False) 1137 self.ws.frame_write(sock, self.ws.OP_CONT, payload, fin=False) 1138 self.ws.frame_write(sock, self.ws.OP_CONT, '') 1139 1140 frame = self.ws.frame_read(sock) 1141 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1142 1143 # 6_2_1 1144 1145 payload = 'Hello-µ@ßöäüàá-UTF-8!!' 1146 1147 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1148 1149 frame = self.ws.frame_read(sock) 1150 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1151 1152 # 6_2_2 1153 1154 self.ws.frame_write(sock, self.ws.OP_TEXT, payload[:12], fin=False) 1155 self.ws.frame_write(sock, self.ws.OP_CONT, payload[12:]) 1156 1157 frame = self.ws.frame_read(sock) 1158 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1159 1160 # 6_2_3 1161 1162 self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 1163 1164 frame = self.ws.frame_read(sock) 1165 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1166 1167 # 6_2_4 1168 1169 payload = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5' 1170 1171 self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 1172 1173 frame = self.ws.frame_read(sock) 1174 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1175 1176 self.close_connection(sock) 1177 1178 # Unit does not support UTF-8 validation 1179 1180# # 6_3_1 FAIL 1181# 1182# payload_1 = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5' 1183# payload_2 = '\xed\xa0\x80' 1184# payload_3 = '\x65\x64\x69\x74\x65\x64' 1185# 1186# payload = payload_1 + payload_2 + payload_3 1187# 1188# self.ws.message(sock, self.ws.OP_TEXT, payload) 1189# self.check_close(sock, 1007) 1190# 1191# # 6_3_2 FAIL 1192# 1193# _, sock, _ = self.ws.upgrade() 1194# 1195# self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 1196# self.check_close(sock, 1007) 1197# 1198# # 6_4_1 ... 6_4_4 FAIL 1199 1200 def test_node_websockets_7_1_1__7_5_1(self): 1201 self.load('websockets/mirror') 1202 1203 # 7_1_1 1204 1205 _, sock, _ = self.ws.upgrade() 1206 1207 payload = "Hello World!" 1208 1209 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1210 1211 frame = self.ws.frame_read(sock) 1212 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1213 1214 self.close_connection(sock) 1215 1216 # 7_1_2 1217 1218 _, sock, _ = self.ws.upgrade() 1219 1220 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1221 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1222 1223 self.check_close(sock) 1224 1225 # 7_1_3 1226 1227 _, sock, _ = self.ws.upgrade() 1228 1229 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1230 self.check_close(sock, no_close = True) 1231 1232 self.ws.frame_write(sock, self.ws.OP_PING, '') 1233 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty sock') 1234 1235 sock.close() 1236 1237 # 7_1_4 1238 1239 _, sock, _ = self.ws.upgrade() 1240 1241 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1242 self.check_close(sock, no_close = True) 1243 1244 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1245 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty sock') 1246 1247 sock.close() 1248 1249 # 7_1_5 1250 1251 _, sock, _ = self.ws.upgrade() 1252 1253 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 1254 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1255 self.check_close(sock, no_close = True) 1256 1257 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2') 1258 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty sock') 1259 1260 sock.close() 1261 1262 # 7_1_6 1263 1264 _, sock, _ = self.ws.upgrade() 1265 1266 self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2**10) 1267 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1268 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1269 1270 self.recvall(sock, read_timeout=1) 1271 1272 self.ws.frame_write(sock, self.ws.OP_PING, '') 1273 self.assertEqual(self.recvall(sock, read_timeout=1), b'', 'empty sock') 1274 1275 sock.close() 1276 1277 # 7_3_1 # FAIL 1278 1279 _, sock, _ = self.ws.upgrade() 1280 1281 self.ws.frame_write(sock, self.ws.OP_CLOSE, '') 1282 self.check_close(sock) 1283 1284 # 7_3_2 1285 1286 _, sock, _ = self.ws.upgrade() 1287 1288 self.ws.frame_write(sock, self.ws.OP_CLOSE, 'a') 1289 self.check_close(sock, 1002) 1290 1291 # 7_3_3 1292 1293 _, sock, _ = self.ws.upgrade() 1294 1295 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1296 self.check_close(sock) 1297 1298 # 7_3_4 1299 1300 _, sock, _ = self.ws.upgrade() 1301 1302 payload = self.ws.serialize_close(reason = 'Hello World!') 1303 1304 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1305 self.check_close(sock) 1306 1307 # 7_3_5 1308 1309 _, sock, _ = self.ws.upgrade() 1310 1311 payload = self.ws.serialize_close(reason = '*' * 123) 1312 1313 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1314 self.check_close(sock) 1315 1316 # 7_3_6 1317 1318 _, sock, _ = self.ws.upgrade() 1319 1320 payload = self.ws.serialize_close(reason = '*' * 124) 1321 1322 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1323 self.check_close(sock, 1002) 1324 1325 # 7_5_1 FAIL Unit does not support UTF-8 validation 1326 1327# _, sock, _ = self.ws.upgrade() 1328# 1329# payload = self.ws.serialize_close(reason = '\xce\xba\xe1\xbd\xb9\xcf' \ 1330# '\x83\xce\xbc\xce\xb5\xed\xa0\x80\x65\x64\x69\x74\x65\x64') 1331# 1332# self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1333# self.check_close(sock, 1007) 1334 1335 def test_node_websockets_7_7_X__7_9_X(self): 1336 self.load('websockets/mirror') 1337 1338 valid_codes = [ 1339 1000, 1340 1001, 1341 1002, 1342 1003, 1343 1007, 1344 1008, 1345 1009, 1346 1010, 1347 1011, 1348 3000, 1349 3999, 1350 4000, 1351 4999, 1352 ] 1353 1354 invalid_codes = [0, 999, 1004, 1005, 1006, 1016, 1100, 2000, 2999] 1355 1356 for code in valid_codes: 1357 _, sock, _ = self.ws.upgrade() 1358 1359 payload = self.ws.serialize_close(code = code) 1360 1361 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1362 self.check_close(sock) 1363 1364 for code in invalid_codes: 1365 _, sock, _ = self.ws.upgrade() 1366 1367 payload = self.ws.serialize_close(code = code) 1368 1369 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1370 self.check_close(sock, 1002) 1371 1372 def test_node_websockets_7_13_1__7_13_2(self): 1373 self.load('websockets/mirror') 1374 1375 # 7_13_1 1376 1377 _, sock, _ = self.ws.upgrade() 1378 1379 payload = self.ws.serialize_close(code = 5000) 1380 1381 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1382 self.check_close(sock, 1002) 1383 1384 # 7_13_2 1385 1386 _, sock, _ = self.ws.upgrade() 1387 1388 payload = struct.pack('!I', 65536) + ''.encode('utf-8') 1389 1390 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1391 self.check_close(sock, 1002) 1392 1393 def test_node_websockets_9_1_1__9_6_6(self): 1394 if not self.unsafe: 1395 self.skipTest("unsafe, long run") 1396 1397 self.load('websockets/mirror') 1398 1399 self.assertIn( 1400 'success', 1401 self.conf( 1402 { 1403 'http': { 1404 'websocket': { 1405 'max_frame_size': 33554432, 1406 'keepalive_interval': 0, 1407 } 1408 } 1409 }, 1410 'settings', 1411 ), 1412 'increase max_frame_size and keepalive_interval', 1413 ) 1414 1415 _, sock, _ = self.ws.upgrade() 1416 1417 op_text = self.ws.OP_TEXT 1418 op_binary = self.ws.OP_BINARY 1419 1420 def check_payload(opcode, length, chopsize=None): 1421 if opcode == self.ws.OP_TEXT: 1422 payload = '*' * length 1423 else: 1424 payload = b'*' * length 1425 1426 self.ws.frame_write(sock, opcode, payload, chopsize=chopsize) 1427 frame = self.ws.frame_read(sock, read_timeout=5) 1428 self.check_frame(frame, True, opcode, payload) 1429 1430 def check_message(opcode, f_size): 1431 if opcode == self.ws.OP_TEXT: 1432 payload = '*' * 4 * 2**20 1433 else: 1434 payload = b'*' * 4 * 2**20 1435 1436 self.ws.message(sock, opcode, payload, fragmention_size=f_size) 1437 frame = self.ws.frame_read(sock, read_timeout=5) 1438 self.check_frame(frame, True, opcode, payload) 1439 1440 check_payload(op_text, 64 * 2**10) # 9_1_1 1441 check_payload(op_text, 256 * 2**10) # 9_1_2 1442 check_payload(op_text, 2**20) # 9_1_3 1443 check_payload(op_text, 4 * 2**20) # 9_1_4 1444 check_payload(op_text, 8 * 2**20) # 9_1_5 1445 check_payload(op_text, 16 * 2**20) # 9_1_6 1446 1447 check_payload(op_binary, 64 * 2**10) # 9_2_1 1448 check_payload(op_binary, 256 * 2**10) # 9_2_2 1449 check_payload(op_binary, 2**20) # 9_2_3 1450 check_payload(op_binary, 4 * 2**20) # 9_2_4 1451 check_payload(op_binary, 8 * 2**20) # 9_2_5 1452 check_payload(op_binary, 16 * 2**20) # 9_2_6 1453 1454 if self.system != 'Darwin' and self.system != 'FreeBSD': 1455 check_message(op_text, 64) # 9_3_1 1456 check_message(op_text, 256) # 9_3_2 1457 check_message(op_text, 2**10) # 9_3_3 1458 check_message(op_text, 4 * 2**10) # 9_3_4 1459 check_message(op_text, 16 * 2**10) # 9_3_5 1460 check_message(op_text, 64 * 2**10) # 9_3_6 1461 check_message(op_text, 256 * 2**10) # 9_3_7 1462 check_message(op_text, 2**20) # 9_3_8 1463 check_message(op_text, 4 * 2**20) # 9_3_9 1464 1465 check_message(op_binary, 64) # 9_4_1 1466 check_message(op_binary, 256) # 9_4_2 1467 check_message(op_binary, 2**10) # 9_4_3 1468 check_message(op_binary, 4 * 2**10) # 9_4_4 1469 check_message(op_binary, 16 * 2**10) # 9_4_5 1470 check_message(op_binary, 64 * 2**10) # 9_4_6 1471 check_message(op_binary, 256 * 2**10) # 9_4_7 1472 check_message(op_binary, 2**20) # 9_4_8 1473 check_message(op_binary, 4 * 2**20) # 9_4_9 1474 1475 check_payload(op_text, 2**20, chopsize=64) # 9_5_1 1476 check_payload(op_text, 2**20, chopsize=128) # 9_5_2 1477 check_payload(op_text, 2**20, chopsize=256) # 9_5_3 1478 check_payload(op_text, 2**20, chopsize=512) # 9_5_4 1479 check_payload(op_text, 2**20, chopsize=1024) # 9_5_5 1480 check_payload(op_text, 2**20, chopsize=2048) # 9_5_6 1481 1482 check_payload(op_binary, 2**20, chopsize=64) # 9_6_1 1483 check_payload(op_binary, 2**20, chopsize=128) # 9_6_2 1484 check_payload(op_binary, 2**20, chopsize=256) # 9_6_3 1485 check_payload(op_binary, 2**20, chopsize=512) # 9_6_4 1486 check_payload(op_binary, 2**20, chopsize=1024) # 9_6_5 1487 check_payload(op_binary, 2**20, chopsize=2048) # 9_6_6 1488 1489 self.close_connection(sock) 1490 1491 def test_node_websockets_10_1_1(self): 1492 self.load('websockets/mirror') 1493 1494 _, sock, _ = self.ws.upgrade() 1495 1496 payload = '*' * 65536 1497 1498 self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1300) 1499 1500 frame = self.ws.frame_read(sock) 1501 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1502 1503 self.close_connection(sock) 1504 1505 # settings 1506 1507 def test_node_websockets_max_frame_size(self): 1508 self.load('websockets/mirror') 1509 1510 self.assertIn( 1511 'success', 1512 self.conf( 1513 {'http': {'websocket': {'max_frame_size': 100}}}, 'settings' 1514 ), 1515 'configure max_frame_size', 1516 ) 1517 1518 _, sock, _ = self.ws.upgrade() 1519 1520 payload = '*' * 94 1521 opcode = self.ws.OP_TEXT 1522 1523 self.ws.frame_write(sock, opcode, payload) # frame length is 100 1524 1525 frame = self.ws.frame_read(sock) 1526 self.check_frame(frame, True, opcode, payload) 1527 1528 payload = '*' * 95 1529 1530 self.ws.frame_write(sock, opcode, payload) # frame length is 101 1531 self.check_close(sock, 1009) # 1009 - CLOSE_TOO_LARGE 1532 1533 @unittest.skip('not yet') 1534 def test_node_websockets_read_timeout(self): 1535 self.load('websockets/mirror') 1536 1537 self.assertIn( 1538 'success', 1539 self.conf( 1540 {'http': {'websocket': {'read_timeout': 1}}}, 'settings' 1541 ), 1542 'configure read_timeout', 1543 ) 1544 1545 _, sock, _ = self.ws.upgrade() 1546 1547 frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah') 1548 sock.sendall(frame[:2]) 1549 1550 time.sleep(2) 1551 1552 self.check_close(sock, 1001) # 1001 - CLOSE_GOING_AWAY 1553 1554 @unittest.skip('not yet') 1555 def test_node_websockets_keepalive_interval(self): 1556 self.load('websockets/mirror') 1557 1558 self.assertIn( 1559 'success', 1560 self.conf( 1561 {'http': {'websocket': {'keepalive_interval': 1}}}, 'settings' 1562 ), 1563 'configure keepalive_interval', 1564 ) 1565 1566 _, sock, _ = self.ws.upgrade() 1567 1568 frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah') 1569 sock.sendall(frame[:2]) 1570 1571 time.sleep(2) 1572 1573 frame = self.ws.frame_read(sock) 1574 self.check_frame(frame, True, self.ws.OP_PING, '') # PING frame 1575 1576 sock.close() 1577 1578if __name__ == '__main__': 1579 TestNodeWebsockets.main() 1580