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