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