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