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