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