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