1import struct 2import time 3 4import pytest 5 6from conftest import option 7from conftest import skip_alert 8from unit.applications.lang.node import TestApplicationNode 9from unit.applications.websockets import TestApplicationWebsocket 10 11 12class TestNodeWebsockets(TestApplicationNode): 13 prerequisites = {'modules': {'node': 'any'}} 14 15 ws = TestApplicationWebsocket() 16 17 def setup_method(self): 18 super().setup_method() 19 20 assert 'success' in self.conf( 21 {'http': {'websocket': {'keepalive_interval': 0}}}, 'settings' 22 ), 'clear keepalive_interval' 23 24 skip_alert(r'socket close\(\d+\) failed') 25 26 def close_connection(self, sock): 27 assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 28 29 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 30 31 self.check_close(sock) 32 33 def check_close(self, sock, code=1000, no_close=False): 34 frame = self.ws.frame_read(sock) 35 36 assert frame['fin'] == True, 'close fin' 37 assert frame['opcode'] == self.ws.OP_CLOSE, 'close opcode' 38 assert frame['code'] == code, 'close code' 39 40 if not no_close: 41 sock.close() 42 43 def check_frame(self, frame, fin, opcode, payload, decode=True): 44 if opcode == self.ws.OP_BINARY or not decode: 45 data = frame['data'] 46 else: 47 data = frame['data'].decode('utf-8') 48 49 assert frame['fin'] == fin, 'fin' 50 assert frame['opcode'] == opcode, 'opcode' 51 assert data == payload, 'payload' 52 53 def test_node_websockets_handshake(self): 54 self.load('websockets/mirror') 55 56 resp, sock, key = self.ws.upgrade() 57 sock.close() 58 59 assert resp['status'] == 101, 'status' 60 assert resp['headers']['Upgrade'] == 'websocket', 'upgrade' 61 assert resp['headers']['Connection'] == 'Upgrade', 'connection' 62 assert resp['headers']['Sec-WebSocket-Accept'] == self.ws.accept( 63 key 64 ), 'key' 65 66 def test_node_websockets_mirror(self): 67 self.load('websockets/mirror') 68 69 message = 'blah' 70 71 _, sock, _ = self.ws.upgrade() 72 73 self.ws.frame_write(sock, self.ws.OP_TEXT, message) 74 frame = self.ws.frame_read(sock) 75 76 assert message == frame['data'].decode('utf-8'), 'mirror' 77 78 self.ws.frame_write(sock, self.ws.OP_TEXT, message) 79 frame = self.ws.frame_read(sock) 80 81 assert message == frame['data'].decode('utf-8'), 'mirror 2' 82 83 sock.close() 84 85 def test_node_websockets_no_mask(self): 86 self.load('websockets/mirror') 87 88 message = 'blah' 89 90 _, sock, _ = self.ws.upgrade() 91 92 self.ws.frame_write(sock, self.ws.OP_TEXT, message, mask=False) 93 94 frame = self.ws.frame_read(sock) 95 96 assert frame['opcode'] == self.ws.OP_CLOSE, 'no mask opcode' 97 assert frame['code'] == 1002, 'no mask close code' 98 99 sock.close() 100 101 def test_node_websockets_fragmentation(self): 102 self.load('websockets/mirror') 103 104 message = 'blah' 105 106 _, sock, _ = self.ws.upgrade() 107 108 self.ws.frame_write(sock, self.ws.OP_TEXT, message, fin=False) 109 self.ws.frame_write(sock, self.ws.OP_CONT, ' ', fin=False) 110 self.ws.frame_write(sock, self.ws.OP_CONT, message) 111 112 frame = self.ws.frame_read(sock) 113 114 assert message + ' ' + message == frame['data'].decode( 115 'utf-8' 116 ), 'mirror framing' 117 118 sock.close() 119 120 def test_node_websockets_frame_fragmentation_invalid(self): 121 self.load('websockets/mirror') 122 123 message = 'blah' 124 125 _, sock, _ = self.ws.upgrade() 126 127 self.ws.frame_write(sock, self.ws.OP_PING, message, fin=False) 128 129 frame = self.ws.frame_read(sock) 130 131 frame.pop('data') 132 assert frame == { 133 'fin': True, 134 'rsv1': False, 135 'rsv2': False, 136 'rsv3': False, 137 'opcode': self.ws.OP_CLOSE, 138 'mask': 0, 139 'code': 1002, 140 'reason': 'Fragmented control frame', 141 }, 'close frame' 142 143 sock.close() 144 145 def test_node_websockets_large(self): 146 self.load('websockets/mirror_fragmentation') 147 148 message = '0123456789' * 3000 149 150 _, sock, _ = self.ws.upgrade() 151 152 self.ws.frame_write(sock, self.ws.OP_TEXT, message) 153 154 frame = self.ws.frame_read(sock) 155 data = frame['data'].decode('utf-8') 156 157 frame = self.ws.frame_read(sock) 158 data += frame['data'].decode('utf-8') 159 160 assert message == data, 'large' 161 162 sock.close() 163 164 def test_node_websockets_two_clients(self): 165 self.load('websockets/mirror') 166 167 message1 = 'blah1' 168 message2 = 'blah2' 169 170 _, sock1, _ = self.ws.upgrade() 171 _, sock2, _ = self.ws.upgrade() 172 173 self.ws.frame_write(sock1, self.ws.OP_TEXT, message1) 174 self.ws.frame_write(sock2, self.ws.OP_TEXT, message2) 175 176 frame1 = self.ws.frame_read(sock1) 177 frame2 = self.ws.frame_read(sock2) 178 179 assert message1 == frame1['data'].decode('utf-8'), 'client 1' 180 assert message2 == frame2['data'].decode('utf-8'), 'client 2' 181 182 sock1.close() 183 sock2.close() 184 185 @pytest.mark.skip('not yet') 186 def test_node_websockets_handshake_upgrade_absent( 187 self 188 ): # FAIL https://tools.ietf.org/html/rfc6455#section-4.2.1 189 self.load('websockets/mirror') 190 191 resp = self.get( 192 headers={ 193 'Host': 'localhost', 194 'Connection': 'Upgrade', 195 'Sec-WebSocket-Key': self.ws.key(), 196 'Sec-WebSocket-Protocol': 'chat', 197 'Sec-WebSocket-Version': 13, 198 }, 199 ) 200 201 assert resp['status'] == 400, 'upgrade absent' 202 203 def test_node_websockets_handshake_case_insensitive(self): 204 self.load('websockets/mirror') 205 206 resp, sock, _ = self.ws.upgrade( 207 headers={ 208 'Host': 'localhost', 209 'Upgrade': 'WEBSOCKET', 210 'Connection': 'UPGRADE', 211 'Sec-WebSocket-Key': self.ws.key(), 212 'Sec-WebSocket-Protocol': 'chat', 213 'Sec-WebSocket-Version': 13, 214 } 215 ) 216 sock.close() 217 218 assert resp['status'] == 101, 'status' 219 220 @pytest.mark.skip('not yet') 221 def test_node_websockets_handshake_connection_absent(self): # FAIL 222 self.load('websockets/mirror') 223 224 resp = self.get( 225 headers={ 226 'Host': 'localhost', 227 'Upgrade': 'websocket', 228 'Sec-WebSocket-Key': self.ws.key(), 229 'Sec-WebSocket-Protocol': 'chat', 230 'Sec-WebSocket-Version': 13, 231 }, 232 ) 233 234 assert resp['status'] == 400, 'status' 235 236 def test_node_websockets_handshake_version_absent(self): 237 self.load('websockets/mirror') 238 239 resp = self.get( 240 headers={ 241 'Host': 'localhost', 242 'Upgrade': 'websocket', 243 'Connection': 'Upgrade', 244 'Sec-WebSocket-Key': self.ws.key(), 245 'Sec-WebSocket-Protocol': 'chat', 246 }, 247 ) 248 249 assert resp['status'] == 426, 'status' 250 251 @pytest.mark.skip('not yet') 252 def test_node_websockets_handshake_key_invalid(self): 253 self.load('websockets/mirror') 254 255 resp = self.get( 256 headers={ 257 'Host': 'localhost', 258 'Upgrade': 'websocket', 259 'Connection': 'Upgrade', 260 'Sec-WebSocket-Key': '!', 261 'Sec-WebSocket-Protocol': 'chat', 262 'Sec-WebSocket-Version': 13, 263 }, 264 ) 265 266 assert resp['status'] == 400, 'key length' 267 268 key = self.ws.key() 269 resp = self.get( 270 headers={ 271 'Host': 'localhost', 272 'Upgrade': 'websocket', 273 'Connection': 'Upgrade', 274 'Sec-WebSocket-Key': [key, key], 275 'Sec-WebSocket-Protocol': 'chat', 276 'Sec-WebSocket-Version': 13, 277 }, 278 ) 279 280 assert resp['status'] == 400, '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 self.check_close(sock, 1002) 888 889 # 5_16 890 891 _, sock, _ = self.ws.upgrade() 892 893 for i in range(0, 2): 894 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=False) 895 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False) 896 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True) 897 self.check_close(sock, 1002) 898 899 # 5_17 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=True) 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_18 910 911 _, sock, _ = self.ws.upgrade() 912 913 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 914 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2') 915 self.check_close(sock, 1002) 916 917 # 5_19 918 919 _, sock, _ = self.ws.upgrade() 920 921 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 922 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False) 923 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!') 924 925 time.sleep(1) 926 927 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 928 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False) 929 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!') 930 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5') 931 932 frame = self.ws.frame_read(sock) 933 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!') 934 935 frame = self.ws.frame_read(sock) 936 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!') 937 938 self.check_frame( 939 self.ws.frame_read(sock), 940 True, 941 self.ws.OP_TEXT, 942 'fragment1fragment2fragment3fragment4fragment5', 943 ) 944 945 # 5_20 946 947 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 948 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False) 949 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!') 950 951 frame = self.ws.frame_read(sock) 952 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!') 953 954 time.sleep(1) 955 956 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 957 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False) 958 self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!') 959 960 frame = self.ws.frame_read(sock) 961 self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!') 962 963 assert self.recvall(sock, read_timeout=0.1) == b'', '5_20' 964 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5') 965 966 self.check_frame( 967 self.ws.frame_read(sock), 968 True, 969 self.ws.OP_TEXT, 970 'fragment1fragment2fragment3fragment4fragment5', 971 ) 972 973 self.close_connection(sock) 974 975 def test_node_websockets_6_1_1__6_4_4(self): 976 self.load('websockets/mirror') 977 978 # 6_1_1 979 980 _, sock, _ = self.ws.upgrade() 981 982 self.ws.frame_write(sock, self.ws.OP_TEXT, '') 983 frame = self.ws.frame_read(sock) 984 self.check_frame(frame, True, self.ws.OP_TEXT, '') 985 986 # 6_1_2 987 988 self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False) 989 self.ws.frame_write(sock, self.ws.OP_CONT, '', fin=False) 990 self.ws.frame_write(sock, self.ws.OP_CONT, '') 991 992 frame = self.ws.frame_read(sock) 993 self.check_frame(frame, True, self.ws.OP_TEXT, '') 994 995 # 6_1_3 996 997 payload = 'middle frame payload' 998 999 self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False) 1000 self.ws.frame_write(sock, self.ws.OP_CONT, payload, fin=False) 1001 self.ws.frame_write(sock, self.ws.OP_CONT, '') 1002 1003 frame = self.ws.frame_read(sock) 1004 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1005 1006 # 6_2_1 1007 1008 payload = 'Hello-µ@ßöäüàá-UTF-8!!' 1009 1010 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1011 1012 frame = self.ws.frame_read(sock) 1013 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1014 1015 # 6_2_2 1016 1017 self.ws.frame_write(sock, self.ws.OP_TEXT, payload[:12], fin=False) 1018 self.ws.frame_write(sock, self.ws.OP_CONT, payload[12:]) 1019 1020 frame = self.ws.frame_read(sock) 1021 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1022 1023 # 6_2_3 1024 1025 self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 1026 1027 frame = self.ws.frame_read(sock) 1028 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1029 1030 # 6_2_4 1031 1032 payload = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5' 1033 1034 self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 1035 1036 frame = self.ws.frame_read(sock) 1037 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1038 1039 self.close_connection(sock) 1040 1041# Unit does not support UTF-8 validation 1042# 1043# # 6_3_1 FAIL 1044# 1045# payload_1 = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5' 1046# payload_2 = '\xed\xa0\x80' 1047# payload_3 = '\x65\x64\x69\x74\x65\x64' 1048# 1049# payload = payload_1 + payload_2 + payload_3 1050# 1051# self.ws.message(sock, self.ws.OP_TEXT, payload) 1052# self.check_close(sock, 1007) 1053# 1054# # 6_3_2 FAIL 1055# 1056# _, sock, _ = self.ws.upgrade() 1057# 1058# self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 1059# self.check_close(sock, 1007) 1060# 1061# # 6_4_1 ... 6_4_4 FAIL 1062 1063 def test_node_websockets_7_1_1__7_5_1(self): 1064 self.load('websockets/mirror') 1065 1066 # 7_1_1 1067 1068 _, sock, _ = self.ws.upgrade() 1069 1070 payload = "Hello World!" 1071 1072 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1073 1074 frame = self.ws.frame_read(sock) 1075 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1076 1077 self.close_connection(sock) 1078 1079 # 7_1_2 1080 1081 _, sock, _ = self.ws.upgrade() 1082 1083 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1084 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1085 1086 self.check_close(sock) 1087 1088 # 7_1_3 1089 1090 _, sock, _ = self.ws.upgrade() 1091 1092 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1093 self.check_close(sock, no_close=True) 1094 1095 self.ws.frame_write(sock, self.ws.OP_PING, '') 1096 assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 1097 1098 sock.close() 1099 1100 # 7_1_4 1101 1102 _, sock, _ = self.ws.upgrade() 1103 1104 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1105 self.check_close(sock, no_close=True) 1106 1107 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1108 assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 1109 1110 sock.close() 1111 1112 # 7_1_5 1113 1114 _, sock, _ = self.ws.upgrade() 1115 1116 self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 1117 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1118 self.check_close(sock, no_close=True) 1119 1120 self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2') 1121 assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 1122 1123 sock.close() 1124 1125 # 7_1_6 1126 1127 _, sock, _ = self.ws.upgrade() 1128 1129 self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10) 1130 self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 1131 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1132 1133 self.recvall(sock, read_timeout=1) 1134 1135 self.ws.frame_write(sock, self.ws.OP_PING, '') 1136 assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 1137 1138 sock.close() 1139 1140 # 7_3_1 1141 1142 _, sock, _ = self.ws.upgrade() 1143 1144 self.ws.frame_write(sock, self.ws.OP_CLOSE, '') 1145 self.check_close(sock) 1146 1147 # 7_3_2 1148 1149 _, sock, _ = self.ws.upgrade() 1150 1151 self.ws.frame_write(sock, self.ws.OP_CLOSE, 'a') 1152 self.check_close(sock, 1002) 1153 1154 # 7_3_3 1155 1156 _, sock, _ = self.ws.upgrade() 1157 1158 self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 1159 self.check_close(sock) 1160 1161 # 7_3_4 1162 1163 _, sock, _ = self.ws.upgrade() 1164 1165 payload = self.ws.serialize_close(reason='Hello World!') 1166 1167 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1168 self.check_close(sock) 1169 1170 # 7_3_5 1171 1172 _, sock, _ = self.ws.upgrade() 1173 1174 payload = self.ws.serialize_close(reason='*' * 123) 1175 1176 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1177 self.check_close(sock) 1178 1179 # 7_3_6 1180 1181 _, sock, _ = self.ws.upgrade() 1182 1183 payload = self.ws.serialize_close(reason='*' * 124) 1184 1185 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1186 self.check_close(sock, 1002) 1187 1188# # 7_5_1 FAIL Unit does not support UTF-8 validation 1189# 1190# _, sock, _ = self.ws.upgrade() 1191# 1192# payload = self.ws.serialize_close(reason = '\xce\xba\xe1\xbd\xb9\xcf' \ 1193# '\x83\xce\xbc\xce\xb5\xed\xa0\x80\x65\x64\x69\x74\x65\x64') 1194# 1195# self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1196# self.check_close(sock, 1007) 1197 1198 def test_node_websockets_7_7_X__7_9_X(self): 1199 self.load('websockets/mirror') 1200 1201 valid_codes = [ 1202 1000, 1203 1001, 1204 1002, 1205 1003, 1206 1007, 1207 1008, 1208 1009, 1209 1010, 1210 1011, 1211 3000, 1212 3999, 1213 4000, 1214 4999, 1215 ] 1216 1217 invalid_codes = [0, 999, 1004, 1005, 1006, 1016, 1100, 2000, 2999] 1218 1219 for code in valid_codes: 1220 _, sock, _ = self.ws.upgrade() 1221 1222 payload = self.ws.serialize_close(code=code) 1223 1224 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1225 self.check_close(sock) 1226 1227 for code in invalid_codes: 1228 _, sock, _ = self.ws.upgrade() 1229 1230 payload = self.ws.serialize_close(code=code) 1231 1232 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1233 self.check_close(sock, 1002) 1234 1235 def test_node_websockets_7_13_1__7_13_2(self): 1236 self.load('websockets/mirror') 1237 1238 # 7_13_1 1239 1240 _, sock, _ = self.ws.upgrade() 1241 1242 payload = self.ws.serialize_close(code=5000) 1243 1244 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1245 self.check_close(sock, 1002) 1246 1247 # 7_13_2 1248 1249 _, sock, _ = self.ws.upgrade() 1250 1251 payload = struct.pack('!I', 65536) + ''.encode('utf-8') 1252 1253 self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 1254 self.check_close(sock, 1002) 1255 1256 def test_node_websockets_9_1_1__9_6_6(self, is_unsafe): 1257 if not is_unsafe: 1258 pytest.skip('unsafe, long run') 1259 1260 self.load('websockets/mirror') 1261 1262 assert 'success' in self.conf( 1263 { 1264 'http': { 1265 'websocket': { 1266 'max_frame_size': 33554432, 1267 'keepalive_interval': 0, 1268 } 1269 } 1270 }, 1271 'settings', 1272 ), 'increase max_frame_size and keepalive_interval' 1273 1274 _, sock, _ = self.ws.upgrade() 1275 1276 op_text = self.ws.OP_TEXT 1277 op_binary = self.ws.OP_BINARY 1278 1279 def check_payload(opcode, length, chopsize=None): 1280 if opcode == self.ws.OP_TEXT: 1281 payload = '*' * length 1282 else: 1283 payload = b'*' * length 1284 1285 self.ws.frame_write(sock, opcode, payload, chopsize=chopsize) 1286 frame = self.ws.frame_read(sock, read_timeout=5) 1287 self.check_frame(frame, True, opcode, payload) 1288 1289 def check_message(opcode, f_size): 1290 if opcode == self.ws.OP_TEXT: 1291 payload = '*' * 4 * 2 ** 20 1292 else: 1293 payload = b'*' * 4 * 2 ** 20 1294 1295 self.ws.message(sock, opcode, payload, fragmention_size=f_size) 1296 frame = self.ws.frame_read(sock, read_timeout=5) 1297 self.check_frame(frame, True, opcode, payload) 1298 1299 check_payload(op_text, 64 * 2 ** 10) # 9_1_1 1300 check_payload(op_text, 256 * 2 ** 10) # 9_1_2 1301 check_payload(op_text, 2 ** 20) # 9_1_3 1302 check_payload(op_text, 4 * 2 ** 20) # 9_1_4 1303 check_payload(op_text, 8 * 2 ** 20) # 9_1_5 1304 check_payload(op_text, 16 * 2 ** 20) # 9_1_6 1305 1306 check_payload(op_binary, 64 * 2 ** 10) # 9_2_1 1307 check_payload(op_binary, 256 * 2 ** 10) # 9_2_2 1308 check_payload(op_binary, 2 ** 20) # 9_2_3 1309 check_payload(op_binary, 4 * 2 ** 20) # 9_2_4 1310 check_payload(op_binary, 8 * 2 ** 20) # 9_2_5 1311 check_payload(op_binary, 16 * 2 ** 20) # 9_2_6 1312 1313 if option.system != 'Darwin' and option.system != 'FreeBSD': 1314 check_message(op_text, 64) # 9_3_1 1315 check_message(op_text, 256) # 9_3_2 1316 check_message(op_text, 2 ** 10) # 9_3_3 1317 check_message(op_text, 4 * 2 ** 10) # 9_3_4 1318 check_message(op_text, 16 * 2 ** 10) # 9_3_5 1319 check_message(op_text, 64 * 2 ** 10) # 9_3_6 1320 check_message(op_text, 256 * 2 ** 10) # 9_3_7 1321 check_message(op_text, 2 ** 20) # 9_3_8 1322 check_message(op_text, 4 * 2 ** 20) # 9_3_9 1323 1324 check_message(op_binary, 64) # 9_4_1 1325 check_message(op_binary, 256) # 9_4_2 1326 check_message(op_binary, 2 ** 10) # 9_4_3 1327 check_message(op_binary, 4 * 2 ** 10) # 9_4_4 1328 check_message(op_binary, 16 * 2 ** 10) # 9_4_5 1329 check_message(op_binary, 64 * 2 ** 10) # 9_4_6 1330 check_message(op_binary, 256 * 2 ** 10) # 9_4_7 1331 check_message(op_binary, 2 ** 20) # 9_4_8 1332 check_message(op_binary, 4 * 2 ** 20) # 9_4_9 1333 1334 check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1 1335 check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2 1336 check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3 1337 check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4 1338 check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5 1339 check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6 1340 1341 check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1 1342 check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2 1343 check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3 1344 check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4 1345 check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5 1346 check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6 1347 1348 self.close_connection(sock) 1349 1350 def test_node_websockets_10_1_1(self): 1351 self.load('websockets/mirror') 1352 1353 _, sock, _ = self.ws.upgrade() 1354 1355 payload = '*' * 65536 1356 1357 self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1300) 1358 1359 frame = self.ws.frame_read(sock) 1360 self.check_frame(frame, True, self.ws.OP_TEXT, payload) 1361 1362 self.close_connection(sock) 1363 1364 # settings 1365 1366 def test_node_websockets_max_frame_size(self): 1367 self.load('websockets/mirror') 1368 1369 assert 'success' in self.conf( 1370 {'http': {'websocket': {'max_frame_size': 100}}}, 'settings' 1371 ), 'configure max_frame_size' 1372 1373 _, sock, _ = self.ws.upgrade() 1374 1375 payload = '*' * 94 1376 opcode = self.ws.OP_TEXT 1377 1378 self.ws.frame_write(sock, opcode, payload) # frame length is 100 1379 1380 frame = self.ws.frame_read(sock) 1381 self.check_frame(frame, True, opcode, payload) 1382 1383 payload = '*' * 95 1384 1385 self.ws.frame_write(sock, opcode, payload) # frame length is 101 1386 self.check_close(sock, 1009) # 1009 - CLOSE_TOO_LARGE 1387 1388 def test_node_websockets_read_timeout(self): 1389 self.load('websockets/mirror') 1390 1391 assert 'success' in self.conf( 1392 {'http': {'websocket': {'read_timeout': 5}}}, 'settings' 1393 ), 'configure read_timeout' 1394 1395 _, sock, _ = self.ws.upgrade() 1396 1397 frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah') 1398 sock.sendall(frame[:2]) 1399 1400 time.sleep(2) 1401 1402 self.check_close(sock, 1001) # 1001 - CLOSE_GOING_AWAY 1403 1404 def test_node_websockets_keepalive_interval(self): 1405 self.load('websockets/mirror') 1406 1407 assert 'success' in self.conf( 1408 {'http': {'websocket': {'keepalive_interval': 5}}}, 'settings' 1409 ), 'configure keepalive_interval' 1410 1411 _, sock, _ = self.ws.upgrade() 1412 1413 frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah') 1414 sock.sendall(frame[:2]) 1415 1416 time.sleep(2) 1417 1418 frame = self.ws.frame_read(sock) 1419 self.check_frame(frame, True, self.ws.OP_PING, '') # PING frame 1420 1421 sock.close() 1422