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