11625Smax.romanov@nginx.comimport struct 21625Smax.romanov@nginx.comimport time 31625Smax.romanov@nginx.comfrom distutils.version import LooseVersion 41625Smax.romanov@nginx.com 51635Szelenkov@nginx.comimport pytest 61625Smax.romanov@nginx.comfrom unit.applications.lang.python import TestApplicationPython 71625Smax.romanov@nginx.comfrom unit.applications.websockets import TestApplicationWebsocket 81730Szelenkov@nginx.comfrom unit.option import option 91625Smax.romanov@nginx.com 101625Smax.romanov@nginx.com 111625Smax.romanov@nginx.comclass TestASGIWebsockets(TestApplicationPython): 121625Smax.romanov@nginx.com prerequisites = {'modules': {'python': 131625Smax.romanov@nginx.com lambda v: LooseVersion(v) >= LooseVersion('3.5')}} 141625Smax.romanov@nginx.com load_module = 'asgi' 151625Smax.romanov@nginx.com 161625Smax.romanov@nginx.com ws = TestApplicationWebsocket() 171625Smax.romanov@nginx.com 181736Szelenkov@nginx.com @pytest.fixture(autouse=True) 191736Szelenkov@nginx.com def setup_method_fixture(self, request, skip_alert): 201625Smax.romanov@nginx.com assert 'success' in self.conf( 211625Smax.romanov@nginx.com {'http': {'websocket': {'keepalive_interval': 0}}}, 'settings' 221625Smax.romanov@nginx.com ), 'clear keepalive_interval' 231625Smax.romanov@nginx.com 241625Smax.romanov@nginx.com skip_alert(r'socket close\(\d+\) failed') 251625Smax.romanov@nginx.com 261625Smax.romanov@nginx.com def close_connection(self, sock): 271625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 281625Smax.romanov@nginx.com 291625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 301625Smax.romanov@nginx.com 311625Smax.romanov@nginx.com self.check_close(sock) 321625Smax.romanov@nginx.com 331625Smax.romanov@nginx.com def check_close(self, sock, code=1000, no_close=False): 341625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 351625Smax.romanov@nginx.com 361625Smax.romanov@nginx.com assert frame['fin'] == True, 'close fin' 371625Smax.romanov@nginx.com assert frame['opcode'] == self.ws.OP_CLOSE, 'close opcode' 381625Smax.romanov@nginx.com assert frame['code'] == code, 'close code' 391625Smax.romanov@nginx.com 401625Smax.romanov@nginx.com if not no_close: 411625Smax.romanov@nginx.com sock.close() 421625Smax.romanov@nginx.com 431625Smax.romanov@nginx.com def check_frame(self, frame, fin, opcode, payload, decode=True): 441625Smax.romanov@nginx.com if opcode == self.ws.OP_BINARY or not decode: 451625Smax.romanov@nginx.com data = frame['data'] 461625Smax.romanov@nginx.com else: 471625Smax.romanov@nginx.com data = frame['data'].decode('utf-8') 481625Smax.romanov@nginx.com 491625Smax.romanov@nginx.com assert frame['fin'] == fin, 'fin' 501625Smax.romanov@nginx.com assert frame['opcode'] == opcode, 'opcode' 511625Smax.romanov@nginx.com assert data == payload, 'payload' 521625Smax.romanov@nginx.com 531625Smax.romanov@nginx.com def test_asgi_websockets_handshake(self): 541625Smax.romanov@nginx.com self.load('websockets/mirror') 551625Smax.romanov@nginx.com 561625Smax.romanov@nginx.com resp, sock, key = self.ws.upgrade() 571625Smax.romanov@nginx.com sock.close() 581625Smax.romanov@nginx.com 591625Smax.romanov@nginx.com assert resp['status'] == 101, 'status' 601625Smax.romanov@nginx.com assert resp['headers']['Upgrade'] == 'websocket', 'upgrade' 611625Smax.romanov@nginx.com assert resp['headers']['Connection'] == 'Upgrade', 'connection' 621625Smax.romanov@nginx.com assert resp['headers']['Sec-WebSocket-Accept'] == self.ws.accept( 631625Smax.romanov@nginx.com key 641625Smax.romanov@nginx.com ), 'key' 651625Smax.romanov@nginx.com 66*1780Smax.romanov@nginx.com # remove "mirror" application 67*1780Smax.romanov@nginx.com self.load('websockets/subprotocol') 68*1780Smax.romanov@nginx.com 691625Smax.romanov@nginx.com def test_asgi_websockets_subprotocol(self): 701625Smax.romanov@nginx.com self.load('websockets/subprotocol') 711625Smax.romanov@nginx.com 721625Smax.romanov@nginx.com resp, sock, key = self.ws.upgrade() 731625Smax.romanov@nginx.com sock.close() 741625Smax.romanov@nginx.com 751625Smax.romanov@nginx.com assert resp['status'] == 101, 'status' 761625Smax.romanov@nginx.com assert resp['headers']['x-subprotocols'] == "('chat', 'phone', 'video')", 'subprotocols' 771625Smax.romanov@nginx.com assert resp['headers']['sec-websocket-protocol'] == 'chat', 'key' 781625Smax.romanov@nginx.com 791625Smax.romanov@nginx.com def test_asgi_websockets_mirror(self): 801625Smax.romanov@nginx.com self.load('websockets/mirror') 811625Smax.romanov@nginx.com 821625Smax.romanov@nginx.com message = 'blah' 831625Smax.romanov@nginx.com 841625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 851625Smax.romanov@nginx.com 861625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, message) 871625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 881625Smax.romanov@nginx.com 891625Smax.romanov@nginx.com assert message == frame['data'].decode('utf-8'), 'mirror' 901625Smax.romanov@nginx.com 911625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, message) 921625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 931625Smax.romanov@nginx.com 941625Smax.romanov@nginx.com assert message == frame['data'].decode('utf-8'), 'mirror 2' 951625Smax.romanov@nginx.com 961625Smax.romanov@nginx.com sock.close() 971625Smax.romanov@nginx.com 98*1780Smax.romanov@nginx.com def test_asgi_websockets_mirror_app_change(self): 99*1780Smax.romanov@nginx.com self.load('websockets/mirror') 100*1780Smax.romanov@nginx.com 101*1780Smax.romanov@nginx.com message = 'blah' 102*1780Smax.romanov@nginx.com 103*1780Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 104*1780Smax.romanov@nginx.com 105*1780Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, message) 106*1780Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 107*1780Smax.romanov@nginx.com 108*1780Smax.romanov@nginx.com assert message == frame['data'].decode('utf-8'), 'mirror' 109*1780Smax.romanov@nginx.com 110*1780Smax.romanov@nginx.com self.load('websockets/subprotocol') 111*1780Smax.romanov@nginx.com 112*1780Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, message) 113*1780Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 114*1780Smax.romanov@nginx.com 115*1780Smax.romanov@nginx.com assert message == frame['data'].decode('utf-8'), 'mirror 2' 116*1780Smax.romanov@nginx.com 117*1780Smax.romanov@nginx.com sock.close() 118*1780Smax.romanov@nginx.com 1191625Smax.romanov@nginx.com def test_asgi_websockets_no_mask(self): 1201625Smax.romanov@nginx.com self.load('websockets/mirror') 1211625Smax.romanov@nginx.com 1221625Smax.romanov@nginx.com message = 'blah' 1231625Smax.romanov@nginx.com 1241625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 1251625Smax.romanov@nginx.com 1261625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, message, mask=False) 1271625Smax.romanov@nginx.com 1281625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 1291625Smax.romanov@nginx.com 1301625Smax.romanov@nginx.com assert frame['opcode'] == self.ws.OP_CLOSE, 'no mask opcode' 1311625Smax.romanov@nginx.com assert frame['code'] == 1002, 'no mask close code' 1321625Smax.romanov@nginx.com 1331625Smax.romanov@nginx.com sock.close() 1341625Smax.romanov@nginx.com 1351625Smax.romanov@nginx.com def test_asgi_websockets_fragmentation(self): 1361625Smax.romanov@nginx.com self.load('websockets/mirror') 1371625Smax.romanov@nginx.com 1381625Smax.romanov@nginx.com message = 'blah' 1391625Smax.romanov@nginx.com 1401625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 1411625Smax.romanov@nginx.com 1421625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, message, fin=False) 1431625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, ' ', fin=False) 1441625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, message) 1451625Smax.romanov@nginx.com 1461625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 1471625Smax.romanov@nginx.com 1481625Smax.romanov@nginx.com assert message + ' ' + message == frame['data'].decode( 1491625Smax.romanov@nginx.com 'utf-8' 1501625Smax.romanov@nginx.com ), 'mirror framing' 1511625Smax.romanov@nginx.com 1521625Smax.romanov@nginx.com sock.close() 1531625Smax.romanov@nginx.com 1541629Szelenkov@nginx.com def test_asgi_websockets_length_long(self): 1551629Szelenkov@nginx.com self.load('websockets/mirror') 1561629Szelenkov@nginx.com 1571629Szelenkov@nginx.com _, sock, _ = self.ws.upgrade() 1581629Szelenkov@nginx.com 1591629Szelenkov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 1601629Szelenkov@nginx.com self.ws.frame_write( 1611629Szelenkov@nginx.com sock, self.ws.OP_CONT, 'fragment2', length=2**64 - 1 1621629Szelenkov@nginx.com ) 1631629Szelenkov@nginx.com 1641629Szelenkov@nginx.com self.check_close(sock, 1009) # 1009 - CLOSE_TOO_LARGE 1651629Szelenkov@nginx.com 1661625Smax.romanov@nginx.com def test_asgi_websockets_frame_fragmentation_invalid(self): 1671625Smax.romanov@nginx.com self.load('websockets/mirror') 1681625Smax.romanov@nginx.com 1691625Smax.romanov@nginx.com message = 'blah' 1701625Smax.romanov@nginx.com 1711625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 1721625Smax.romanov@nginx.com 1731625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, message, fin=False) 1741625Smax.romanov@nginx.com 1751625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 1761625Smax.romanov@nginx.com 1771625Smax.romanov@nginx.com frame.pop('data') 1781625Smax.romanov@nginx.com assert frame == { 1791625Smax.romanov@nginx.com 'fin': True, 1801625Smax.romanov@nginx.com 'rsv1': False, 1811625Smax.romanov@nginx.com 'rsv2': False, 1821625Smax.romanov@nginx.com 'rsv3': False, 1831625Smax.romanov@nginx.com 'opcode': self.ws.OP_CLOSE, 1841625Smax.romanov@nginx.com 'mask': 0, 1851625Smax.romanov@nginx.com 'code': 1002, 1861625Smax.romanov@nginx.com 'reason': 'Fragmented control frame', 1871625Smax.romanov@nginx.com }, 'close frame' 1881625Smax.romanov@nginx.com 1891625Smax.romanov@nginx.com sock.close() 1901625Smax.romanov@nginx.com 1911625Smax.romanov@nginx.com def test_asgi_websockets_large(self): 1921625Smax.romanov@nginx.com self.load('websockets/mirror') 1931625Smax.romanov@nginx.com 1941625Smax.romanov@nginx.com message = '0123456789' * 300 1951625Smax.romanov@nginx.com 1961625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 1971625Smax.romanov@nginx.com 1981625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, message) 1991625Smax.romanov@nginx.com 2001625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 2011625Smax.romanov@nginx.com data = frame['data'].decode('utf-8') 2021625Smax.romanov@nginx.com 2031625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 2041625Smax.romanov@nginx.com data += frame['data'].decode('utf-8') 2051625Smax.romanov@nginx.com 2061625Smax.romanov@nginx.com assert message == data, 'large' 2071625Smax.romanov@nginx.com 2081625Smax.romanov@nginx.com sock.close() 2091625Smax.romanov@nginx.com 2101625Smax.romanov@nginx.com def test_asgi_websockets_two_clients(self): 2111625Smax.romanov@nginx.com self.load('websockets/mirror') 2121625Smax.romanov@nginx.com 2131625Smax.romanov@nginx.com message1 = 'blah1' 2141625Smax.romanov@nginx.com message2 = 'blah2' 2151625Smax.romanov@nginx.com 2161625Smax.romanov@nginx.com _, sock1, _ = self.ws.upgrade() 2171625Smax.romanov@nginx.com _, sock2, _ = self.ws.upgrade() 2181625Smax.romanov@nginx.com 2191625Smax.romanov@nginx.com self.ws.frame_write(sock1, self.ws.OP_TEXT, message1) 2201625Smax.romanov@nginx.com self.ws.frame_write(sock2, self.ws.OP_TEXT, message2) 2211625Smax.romanov@nginx.com 2221625Smax.romanov@nginx.com frame1 = self.ws.frame_read(sock1) 2231625Smax.romanov@nginx.com frame2 = self.ws.frame_read(sock2) 2241625Smax.romanov@nginx.com 2251625Smax.romanov@nginx.com assert message1 == frame1['data'].decode('utf-8'), 'client 1' 2261625Smax.romanov@nginx.com assert message2 == frame2['data'].decode('utf-8'), 'client 2' 2271625Smax.romanov@nginx.com 2281625Smax.romanov@nginx.com sock1.close() 2291625Smax.romanov@nginx.com sock2.close() 2301625Smax.romanov@nginx.com 2311625Smax.romanov@nginx.com @pytest.mark.skip('not yet') 2321625Smax.romanov@nginx.com def test_asgi_websockets_handshake_upgrade_absent( 2331625Smax.romanov@nginx.com self 2341625Smax.romanov@nginx.com ): # FAIL https://tools.ietf.org/html/rfc6455#section-4.2.1 2351625Smax.romanov@nginx.com self.load('websockets/mirror') 2361625Smax.romanov@nginx.com 2371625Smax.romanov@nginx.com resp = self.get( 2381625Smax.romanov@nginx.com headers={ 2391625Smax.romanov@nginx.com 'Host': 'localhost', 2401625Smax.romanov@nginx.com 'Connection': 'Upgrade', 2411625Smax.romanov@nginx.com 'Sec-WebSocket-Key': self.ws.key(), 2421625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 2431625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 2441625Smax.romanov@nginx.com }, 2451625Smax.romanov@nginx.com ) 2461625Smax.romanov@nginx.com 2471625Smax.romanov@nginx.com assert resp['status'] == 400, 'upgrade absent' 2481625Smax.romanov@nginx.com 2491625Smax.romanov@nginx.com def test_asgi_websockets_handshake_case_insensitive(self): 2501625Smax.romanov@nginx.com self.load('websockets/mirror') 2511625Smax.romanov@nginx.com 2521625Smax.romanov@nginx.com resp, sock, _ = self.ws.upgrade( 2531625Smax.romanov@nginx.com headers={ 2541625Smax.romanov@nginx.com 'Host': 'localhost', 2551625Smax.romanov@nginx.com 'Upgrade': 'WEBSOCKET', 2561625Smax.romanov@nginx.com 'Connection': 'UPGRADE', 2571625Smax.romanov@nginx.com 'Sec-WebSocket-Key': self.ws.key(), 2581625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 2591625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 2601625Smax.romanov@nginx.com } 2611625Smax.romanov@nginx.com ) 2621625Smax.romanov@nginx.com sock.close() 2631625Smax.romanov@nginx.com 2641625Smax.romanov@nginx.com assert resp['status'] == 101, 'status' 2651625Smax.romanov@nginx.com 2661625Smax.romanov@nginx.com @pytest.mark.skip('not yet') 2671625Smax.romanov@nginx.com def test_asgi_websockets_handshake_connection_absent(self): # FAIL 2681625Smax.romanov@nginx.com self.load('websockets/mirror') 2691625Smax.romanov@nginx.com 2701625Smax.romanov@nginx.com resp = self.get( 2711625Smax.romanov@nginx.com headers={ 2721625Smax.romanov@nginx.com 'Host': 'localhost', 2731625Smax.romanov@nginx.com 'Upgrade': 'websocket', 2741625Smax.romanov@nginx.com 'Sec-WebSocket-Key': self.ws.key(), 2751625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 2761625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 2771625Smax.romanov@nginx.com }, 2781625Smax.romanov@nginx.com ) 2791625Smax.romanov@nginx.com 2801625Smax.romanov@nginx.com assert resp['status'] == 400, 'status' 2811625Smax.romanov@nginx.com 2821625Smax.romanov@nginx.com def test_asgi_websockets_handshake_version_absent(self): 2831625Smax.romanov@nginx.com self.load('websockets/mirror') 2841625Smax.romanov@nginx.com 2851625Smax.romanov@nginx.com resp = self.get( 2861625Smax.romanov@nginx.com headers={ 2871625Smax.romanov@nginx.com 'Host': 'localhost', 2881625Smax.romanov@nginx.com 'Upgrade': 'websocket', 2891625Smax.romanov@nginx.com 'Connection': 'Upgrade', 2901625Smax.romanov@nginx.com 'Sec-WebSocket-Key': self.ws.key(), 2911625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 2921625Smax.romanov@nginx.com }, 2931625Smax.romanov@nginx.com ) 2941625Smax.romanov@nginx.com 2951625Smax.romanov@nginx.com assert resp['status'] == 426, 'status' 2961625Smax.romanov@nginx.com 2971625Smax.romanov@nginx.com @pytest.mark.skip('not yet') 2981625Smax.romanov@nginx.com def test_asgi_websockets_handshake_key_invalid(self): 2991625Smax.romanov@nginx.com self.load('websockets/mirror') 3001625Smax.romanov@nginx.com 3011625Smax.romanov@nginx.com resp = self.get( 3021625Smax.romanov@nginx.com headers={ 3031625Smax.romanov@nginx.com 'Host': 'localhost', 3041625Smax.romanov@nginx.com 'Upgrade': 'websocket', 3051625Smax.romanov@nginx.com 'Connection': 'Upgrade', 3061625Smax.romanov@nginx.com 'Sec-WebSocket-Key': '!', 3071625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 3081625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 3091625Smax.romanov@nginx.com }, 3101625Smax.romanov@nginx.com ) 3111625Smax.romanov@nginx.com 3121625Smax.romanov@nginx.com assert resp['status'] == 400, 'key length' 3131625Smax.romanov@nginx.com 3141625Smax.romanov@nginx.com key = self.ws.key() 3151625Smax.romanov@nginx.com resp = self.get( 3161625Smax.romanov@nginx.com headers={ 3171625Smax.romanov@nginx.com 'Host': 'localhost', 3181625Smax.romanov@nginx.com 'Upgrade': 'websocket', 3191625Smax.romanov@nginx.com 'Connection': 'Upgrade', 3201625Smax.romanov@nginx.com 'Sec-WebSocket-Key': [key, key], 3211625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 3221625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 3231625Smax.romanov@nginx.com }, 3241625Smax.romanov@nginx.com ) 3251625Smax.romanov@nginx.com 3261625Smax.romanov@nginx.com assert resp['status'] == 400, 'key double' # FAIL https://tools.ietf.org/html/rfc6455#section-11.3.1 3271625Smax.romanov@nginx.com 3281625Smax.romanov@nginx.com def test_asgi_websockets_handshake_method_invalid(self): 3291625Smax.romanov@nginx.com self.load('websockets/mirror') 3301625Smax.romanov@nginx.com 3311625Smax.romanov@nginx.com resp = self.post( 3321625Smax.romanov@nginx.com headers={ 3331625Smax.romanov@nginx.com 'Host': 'localhost', 3341625Smax.romanov@nginx.com 'Upgrade': 'websocket', 3351625Smax.romanov@nginx.com 'Connection': 'Upgrade', 3361625Smax.romanov@nginx.com 'Sec-WebSocket-Key': self.ws.key(), 3371625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 3381625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 3391625Smax.romanov@nginx.com }, 3401625Smax.romanov@nginx.com ) 3411625Smax.romanov@nginx.com 3421625Smax.romanov@nginx.com assert resp['status'] == 400, 'status' 3431625Smax.romanov@nginx.com 3441625Smax.romanov@nginx.com def test_asgi_websockets_handshake_http_10(self): 3451625Smax.romanov@nginx.com self.load('websockets/mirror') 3461625Smax.romanov@nginx.com 3471625Smax.romanov@nginx.com resp = self.get( 3481625Smax.romanov@nginx.com headers={ 3491625Smax.romanov@nginx.com 'Host': 'localhost', 3501625Smax.romanov@nginx.com 'Upgrade': 'websocket', 3511625Smax.romanov@nginx.com 'Connection': 'Upgrade', 3521625Smax.romanov@nginx.com 'Sec-WebSocket-Key': self.ws.key(), 3531625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 3541625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 3551625Smax.romanov@nginx.com }, 3561625Smax.romanov@nginx.com http_10=True, 3571625Smax.romanov@nginx.com ) 3581625Smax.romanov@nginx.com 3591625Smax.romanov@nginx.com assert resp['status'] == 400, 'status' 3601625Smax.romanov@nginx.com 3611625Smax.romanov@nginx.com def test_asgi_websockets_handshake_uri_invalid(self): 3621625Smax.romanov@nginx.com self.load('websockets/mirror') 3631625Smax.romanov@nginx.com 3641625Smax.romanov@nginx.com resp = self.get( 3651625Smax.romanov@nginx.com headers={ 3661625Smax.romanov@nginx.com 'Host': 'localhost', 3671625Smax.romanov@nginx.com 'Upgrade': 'websocket', 3681625Smax.romanov@nginx.com 'Connection': 'Upgrade', 3691625Smax.romanov@nginx.com 'Sec-WebSocket-Key': self.ws.key(), 3701625Smax.romanov@nginx.com 'Sec-WebSocket-Protocol': 'chat', 3711625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 3721625Smax.romanov@nginx.com }, 3731625Smax.romanov@nginx.com url='!', 3741625Smax.romanov@nginx.com ) 3751625Smax.romanov@nginx.com 3761625Smax.romanov@nginx.com assert resp['status'] == 400, 'status' 3771625Smax.romanov@nginx.com 3781625Smax.romanov@nginx.com def test_asgi_websockets_protocol_absent(self): 3791625Smax.romanov@nginx.com self.load('websockets/mirror') 3801625Smax.romanov@nginx.com 3811625Smax.romanov@nginx.com key = self.ws.key() 3821625Smax.romanov@nginx.com resp, sock, _ = self.ws.upgrade( 3831625Smax.romanov@nginx.com headers={ 3841625Smax.romanov@nginx.com 'Host': 'localhost', 3851625Smax.romanov@nginx.com 'Upgrade': 'websocket', 3861625Smax.romanov@nginx.com 'Connection': 'Upgrade', 3871625Smax.romanov@nginx.com 'Sec-WebSocket-Key': key, 3881625Smax.romanov@nginx.com 'Sec-WebSocket-Version': 13, 3891625Smax.romanov@nginx.com } 3901625Smax.romanov@nginx.com ) 3911625Smax.romanov@nginx.com sock.close() 3921625Smax.romanov@nginx.com 3931625Smax.romanov@nginx.com assert resp['status'] == 101, 'status' 3941625Smax.romanov@nginx.com assert resp['headers']['Upgrade'] == 'websocket', 'upgrade' 3951625Smax.romanov@nginx.com assert resp['headers']['Connection'] == 'Upgrade', 'connection' 3961625Smax.romanov@nginx.com assert resp['headers']['Sec-WebSocket-Accept'] == self.ws.accept( 3971625Smax.romanov@nginx.com key 3981625Smax.romanov@nginx.com ), 'key' 3991625Smax.romanov@nginx.com 4001625Smax.romanov@nginx.com # autobahn-testsuite 4011625Smax.romanov@nginx.com # 4021625Smax.romanov@nginx.com # Some following tests fail because of Unit does not support UTF-8 4031625Smax.romanov@nginx.com # validation for websocket frames. It should be implemented 4041625Smax.romanov@nginx.com # by application, if necessary. 4051625Smax.romanov@nginx.com 4061625Smax.romanov@nginx.com def test_asgi_websockets_1_1_1__1_1_8(self): 4071625Smax.romanov@nginx.com self.load('websockets/mirror') 4081625Smax.romanov@nginx.com 4091625Smax.romanov@nginx.com opcode = self.ws.OP_TEXT 4101625Smax.romanov@nginx.com 4111625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 4121625Smax.romanov@nginx.com 4131625Smax.romanov@nginx.com def check_length(length, chopsize=None): 4141625Smax.romanov@nginx.com payload = '*' * length 4151625Smax.romanov@nginx.com 4161625Smax.romanov@nginx.com self.ws.frame_write(sock, opcode, payload, chopsize=chopsize) 4171625Smax.romanov@nginx.com 4181625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 4191625Smax.romanov@nginx.com self.check_frame(frame, True, opcode, payload) 4201625Smax.romanov@nginx.com 4211625Smax.romanov@nginx.com check_length(0) # 1_1_1 4221625Smax.romanov@nginx.com check_length(125) # 1_1_2 4231625Smax.romanov@nginx.com check_length(126) # 1_1_3 4241625Smax.romanov@nginx.com check_length(127) # 1_1_4 4251625Smax.romanov@nginx.com check_length(128) # 1_1_5 4261625Smax.romanov@nginx.com check_length(65535) # 1_1_6 4271625Smax.romanov@nginx.com check_length(65536) # 1_1_7 4281625Smax.romanov@nginx.com check_length(65536, chopsize = 997) # 1_1_8 4291625Smax.romanov@nginx.com 4301625Smax.romanov@nginx.com self.close_connection(sock) 4311625Smax.romanov@nginx.com 4321625Smax.romanov@nginx.com def test_asgi_websockets_1_2_1__1_2_8(self): 4331625Smax.romanov@nginx.com self.load('websockets/mirror') 4341625Smax.romanov@nginx.com 4351625Smax.romanov@nginx.com opcode = self.ws.OP_BINARY 4361625Smax.romanov@nginx.com 4371625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 4381625Smax.romanov@nginx.com 4391625Smax.romanov@nginx.com def check_length(length, chopsize=None): 4401625Smax.romanov@nginx.com payload = b'\xfe' * length 4411625Smax.romanov@nginx.com 4421625Smax.romanov@nginx.com self.ws.frame_write(sock, opcode, payload, chopsize=chopsize) 4431625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 4441625Smax.romanov@nginx.com 4451625Smax.romanov@nginx.com self.check_frame(frame, True, opcode, payload) 4461625Smax.romanov@nginx.com 4471625Smax.romanov@nginx.com check_length(0) # 1_2_1 4481625Smax.romanov@nginx.com check_length(125) # 1_2_2 4491625Smax.romanov@nginx.com check_length(126) # 1_2_3 4501625Smax.romanov@nginx.com check_length(127) # 1_2_4 4511625Smax.romanov@nginx.com check_length(128) # 1_2_5 4521625Smax.romanov@nginx.com check_length(65535) # 1_2_6 4531625Smax.romanov@nginx.com check_length(65536) # 1_2_7 4541625Smax.romanov@nginx.com check_length(65536, chopsize = 997) # 1_2_8 4551625Smax.romanov@nginx.com 4561625Smax.romanov@nginx.com self.close_connection(sock) 4571625Smax.romanov@nginx.com 4581625Smax.romanov@nginx.com def test_asgi_websockets_2_1__2_6(self): 4591625Smax.romanov@nginx.com self.load('websockets/mirror') 4601625Smax.romanov@nginx.com 4611625Smax.romanov@nginx.com op_ping = self.ws.OP_PING 4621625Smax.romanov@nginx.com op_pong = self.ws.OP_PONG 4631625Smax.romanov@nginx.com 4641625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 4651625Smax.romanov@nginx.com 4661625Smax.romanov@nginx.com def check_ping(payload, chopsize=None, decode=True): 4671625Smax.romanov@nginx.com self.ws.frame_write(sock, op_ping, payload, chopsize=chopsize) 4681625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 4691625Smax.romanov@nginx.com 4701625Smax.romanov@nginx.com self.check_frame(frame, True, op_pong, payload, decode=decode) 4711625Smax.romanov@nginx.com 4721625Smax.romanov@nginx.com check_ping('') # 2_1 4731625Smax.romanov@nginx.com check_ping('Hello, world!') # 2_2 4741625Smax.romanov@nginx.com check_ping(b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff', decode=False) # 2_3 4751625Smax.romanov@nginx.com check_ping(b'\xfe' * 125, decode=False) # 2_4 4761625Smax.romanov@nginx.com check_ping(b'\xfe' * 125, chopsize=1, decode=False) # 2_6 4771625Smax.romanov@nginx.com 4781625Smax.romanov@nginx.com self.close_connection(sock) 4791625Smax.romanov@nginx.com 4801625Smax.romanov@nginx.com # 2_5 4811625Smax.romanov@nginx.com 4821625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 4831625Smax.romanov@nginx.com 4841625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, b'\xfe' * 126) 4851625Smax.romanov@nginx.com self.check_close(sock, 1002) 4861625Smax.romanov@nginx.com 4871625Smax.romanov@nginx.com def test_asgi_websockets_2_7__2_9(self): 4881625Smax.romanov@nginx.com self.load('websockets/mirror') 4891625Smax.romanov@nginx.com 4901625Smax.romanov@nginx.com # 2_7 4911625Smax.romanov@nginx.com 4921625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 4931625Smax.romanov@nginx.com 4941625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PONG, '') 4951625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', '2_7' 4961625Smax.romanov@nginx.com 4971625Smax.romanov@nginx.com # 2_8 4981625Smax.romanov@nginx.com 4991625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload') 5001625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', '2_8' 5011625Smax.romanov@nginx.com 5021625Smax.romanov@nginx.com # 2_9 5031625Smax.romanov@nginx.com 5041625Smax.romanov@nginx.com payload = 'ping payload' 5051625Smax.romanov@nginx.com 5061625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload') 5071625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, payload) 5081625Smax.romanov@nginx.com 5091625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 5101625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, payload) 5111625Smax.romanov@nginx.com 5121625Smax.romanov@nginx.com self.close_connection(sock) 5131625Smax.romanov@nginx.com 5141625Smax.romanov@nginx.com def test_asgi_websockets_2_10__2_11(self): 5151625Smax.romanov@nginx.com self.load('websockets/mirror') 5161625Smax.romanov@nginx.com 5171625Smax.romanov@nginx.com # 2_10 5181625Smax.romanov@nginx.com 5191625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 5201625Smax.romanov@nginx.com 5211625Smax.romanov@nginx.com for i in range(0, 10): 5221625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, 'payload-%d' % i) 5231625Smax.romanov@nginx.com 5241625Smax.romanov@nginx.com for i in range(0, 10): 5251625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 5261625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) 5271625Smax.romanov@nginx.com 5281625Smax.romanov@nginx.com # 2_11 5291625Smax.romanov@nginx.com 5301625Smax.romanov@nginx.com for i in range(0, 10): 5311625Smax.romanov@nginx.com opcode = self.ws.OP_PING 5321625Smax.romanov@nginx.com self.ws.frame_write(sock, opcode, 'payload-%d' % i, chopsize=1) 5331625Smax.romanov@nginx.com 5341625Smax.romanov@nginx.com for i in range(0, 10): 5351625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 5361625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) 5371625Smax.romanov@nginx.com 5381625Smax.romanov@nginx.com self.close_connection(sock) 5391625Smax.romanov@nginx.com 5401625Smax.romanov@nginx.com @pytest.mark.skip('not yet') 5411625Smax.romanov@nginx.com def test_asgi_websockets_3_1__3_7(self): 5421625Smax.romanov@nginx.com self.load('websockets/mirror') 5431625Smax.romanov@nginx.com 5441625Smax.romanov@nginx.com payload = 'Hello, world!' 5451625Smax.romanov@nginx.com 5461625Smax.romanov@nginx.com # 3_1 5471625Smax.romanov@nginx.com 5481625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 5491625Smax.romanov@nginx.com 5501625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv1=True) 5511625Smax.romanov@nginx.com self.check_close(sock, 1002) 5521625Smax.romanov@nginx.com 5531625Smax.romanov@nginx.com # 3_2 5541625Smax.romanov@nginx.com 5551625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 5561625Smax.romanov@nginx.com 5571625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 5581625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv2=True) 5591625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 5601625Smax.romanov@nginx.com 5611625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 5621625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 5631625Smax.romanov@nginx.com 5641625Smax.romanov@nginx.com self.check_close(sock, 1002, no_close=True) 5651625Smax.romanov@nginx.com 5661625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_2' 5671625Smax.romanov@nginx.com sock.close() 5681625Smax.romanov@nginx.com 5691625Smax.romanov@nginx.com # 3_3 5701625Smax.romanov@nginx.com 5711625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 5721625Smax.romanov@nginx.com 5731625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 5741625Smax.romanov@nginx.com 5751625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 5761625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 5771625Smax.romanov@nginx.com 5781625Smax.romanov@nginx.com self.ws.frame_write( 5791625Smax.romanov@nginx.com sock, self.ws.OP_TEXT, payload, rsv1=True, rsv2=True 5801625Smax.romanov@nginx.com ) 5811625Smax.romanov@nginx.com 5821625Smax.romanov@nginx.com self.check_close(sock, 1002, no_close=True) 5831625Smax.romanov@nginx.com 5841625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_3' 5851625Smax.romanov@nginx.com sock.close() 5861625Smax.romanov@nginx.com 5871625Smax.romanov@nginx.com # 3_4 5881625Smax.romanov@nginx.com 5891625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 5901625Smax.romanov@nginx.com 5911625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1) 5921625Smax.romanov@nginx.com self.ws.frame_write( 5931625Smax.romanov@nginx.com sock, self.ws.OP_TEXT, payload, rsv3=True, chopsize=1 5941625Smax.romanov@nginx.com ) 5951625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 5961625Smax.romanov@nginx.com 5971625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 5981625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 5991625Smax.romanov@nginx.com 6001625Smax.romanov@nginx.com self.check_close(sock, 1002, no_close=True) 6011625Smax.romanov@nginx.com 6021625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_4' 6031625Smax.romanov@nginx.com sock.close() 6041625Smax.romanov@nginx.com 6051625Smax.romanov@nginx.com # 3_5 6061625Smax.romanov@nginx.com 6071625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6081625Smax.romanov@nginx.com 6091625Smax.romanov@nginx.com self.ws.frame_write( 6101625Smax.romanov@nginx.com sock, 6111625Smax.romanov@nginx.com self.ws.OP_BINARY, 6121625Smax.romanov@nginx.com b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff', 6131625Smax.romanov@nginx.com rsv1=True, 6141625Smax.romanov@nginx.com rsv3=True, 6151625Smax.romanov@nginx.com ) 6161625Smax.romanov@nginx.com 6171625Smax.romanov@nginx.com self.check_close(sock, 1002) 6181625Smax.romanov@nginx.com 6191625Smax.romanov@nginx.com # 3_6 6201625Smax.romanov@nginx.com 6211625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6221625Smax.romanov@nginx.com 6231625Smax.romanov@nginx.com self.ws.frame_write( 6241625Smax.romanov@nginx.com sock, self.ws.OP_PING, payload, rsv2=True, rsv3=True 6251625Smax.romanov@nginx.com ) 6261625Smax.romanov@nginx.com 6271625Smax.romanov@nginx.com self.check_close(sock, 1002) 6281625Smax.romanov@nginx.com 6291625Smax.romanov@nginx.com # 3_7 6301625Smax.romanov@nginx.com 6311625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6321625Smax.romanov@nginx.com 6331625Smax.romanov@nginx.com self.ws.frame_write( 6341625Smax.romanov@nginx.com sock, self.ws.OP_CLOSE, payload, rsv1=True, rsv2=True, rsv3=True 6351625Smax.romanov@nginx.com ) 6361625Smax.romanov@nginx.com 6371625Smax.romanov@nginx.com self.check_close(sock, 1002) 6381625Smax.romanov@nginx.com 6391625Smax.romanov@nginx.com def test_asgi_websockets_4_1_1__4_2_5(self): 6401625Smax.romanov@nginx.com self.load('websockets/mirror') 6411625Smax.romanov@nginx.com 6421625Smax.romanov@nginx.com payload = 'Hello, world!' 6431625Smax.romanov@nginx.com 6441625Smax.romanov@nginx.com # 4_1_1 6451625Smax.romanov@nginx.com 6461625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6471625Smax.romanov@nginx.com 6481625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x03, '') 6491625Smax.romanov@nginx.com self.check_close(sock, 1002) 6501625Smax.romanov@nginx.com 6511625Smax.romanov@nginx.com # 4_1_2 6521625Smax.romanov@nginx.com 6531625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6541625Smax.romanov@nginx.com 6551625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x04, 'reserved opcode payload') 6561625Smax.romanov@nginx.com self.check_close(sock, 1002) 6571625Smax.romanov@nginx.com 6581625Smax.romanov@nginx.com # 4_1_3 6591625Smax.romanov@nginx.com 6601625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6611625Smax.romanov@nginx.com 6621625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 6631625Smax.romanov@nginx.com 6641625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 6651625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 6661625Smax.romanov@nginx.com 6671625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x05, '') 6681625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 6691625Smax.romanov@nginx.com 6701625Smax.romanov@nginx.com self.check_close(sock, 1002) 6711625Smax.romanov@nginx.com 6721625Smax.romanov@nginx.com # 4_1_4 6731625Smax.romanov@nginx.com 6741625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6751625Smax.romanov@nginx.com 6761625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 6771625Smax.romanov@nginx.com 6781625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 6791625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 6801625Smax.romanov@nginx.com 6811625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x06, payload) 6821625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 6831625Smax.romanov@nginx.com 6841625Smax.romanov@nginx.com self.check_close(sock, 1002) 6851625Smax.romanov@nginx.com 6861625Smax.romanov@nginx.com # 4_1_5 6871625Smax.romanov@nginx.com 6881625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 6891625Smax.romanov@nginx.com 6901625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1) 6911625Smax.romanov@nginx.com 6921625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 6931625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 6941625Smax.romanov@nginx.com 6951625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x07, payload, chopsize=1) 6961625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 6971625Smax.romanov@nginx.com 6981625Smax.romanov@nginx.com self.check_close(sock, 1002) 6991625Smax.romanov@nginx.com 7001625Smax.romanov@nginx.com # 4_2_1 7011625Smax.romanov@nginx.com 7021625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7031625Smax.romanov@nginx.com 7041625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x0B, '') 7051625Smax.romanov@nginx.com self.check_close(sock, 1002) 7061625Smax.romanov@nginx.com 7071625Smax.romanov@nginx.com # 4_2_2 7081625Smax.romanov@nginx.com 7091625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7101625Smax.romanov@nginx.com 7111625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x0C, 'reserved opcode payload') 7121625Smax.romanov@nginx.com self.check_close(sock, 1002) 7131625Smax.romanov@nginx.com 7141625Smax.romanov@nginx.com # 4_2_3 7151625Smax.romanov@nginx.com 7161625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7171625Smax.romanov@nginx.com 7181625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 7191625Smax.romanov@nginx.com 7201625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 7211625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 7221625Smax.romanov@nginx.com 7231625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x0D, '') 7241625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 7251625Smax.romanov@nginx.com 7261625Smax.romanov@nginx.com self.check_close(sock, 1002) 7271625Smax.romanov@nginx.com 7281625Smax.romanov@nginx.com # 4_2_4 7291625Smax.romanov@nginx.com 7301625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7311625Smax.romanov@nginx.com 7321625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 7331625Smax.romanov@nginx.com 7341625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 7351625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 7361625Smax.romanov@nginx.com 7371625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x0E, payload) 7381625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 7391625Smax.romanov@nginx.com 7401625Smax.romanov@nginx.com self.check_close(sock, 1002) 7411625Smax.romanov@nginx.com 7421625Smax.romanov@nginx.com # 4_2_5 7431625Smax.romanov@nginx.com 7441625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7451625Smax.romanov@nginx.com 7461625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1) 7471625Smax.romanov@nginx.com 7481625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 7491625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 7501625Smax.romanov@nginx.com 7511625Smax.romanov@nginx.com self.ws.frame_write(sock, 0x0F, payload, chopsize=1) 7521625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 7531625Smax.romanov@nginx.com 7541625Smax.romanov@nginx.com self.check_close(sock, 1002) 7551625Smax.romanov@nginx.com 7561625Smax.romanov@nginx.com def test_asgi_websockets_5_1__5_20(self): 7571625Smax.romanov@nginx.com self.load('websockets/mirror') 7581625Smax.romanov@nginx.com 7591625Smax.romanov@nginx.com # 5_1 7601625Smax.romanov@nginx.com 7611625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7621625Smax.romanov@nginx.com 7631625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, 'fragment1', fin=False) 7641625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 7651625Smax.romanov@nginx.com self.check_close(sock, 1002) 7661625Smax.romanov@nginx.com 7671625Smax.romanov@nginx.com # 5_2 7681625Smax.romanov@nginx.com 7691625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7701625Smax.romanov@nginx.com 7711625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PONG, 'fragment1', fin=False) 7721625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 7731625Smax.romanov@nginx.com self.check_close(sock, 1002) 7741625Smax.romanov@nginx.com 7751625Smax.romanov@nginx.com # 5_3 7761625Smax.romanov@nginx.com 7771625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 7781625Smax.romanov@nginx.com 7791625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 7801625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 7811625Smax.romanov@nginx.com 7821625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 7831625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 7841625Smax.romanov@nginx.com 7851625Smax.romanov@nginx.com # 5_4 7861625Smax.romanov@nginx.com 7871625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 7881625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', '5_4' 7891625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 7901625Smax.romanov@nginx.com 7911625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 7921625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 7931625Smax.romanov@nginx.com 7941625Smax.romanov@nginx.com # 5_5 7951625Smax.romanov@nginx.com 7961625Smax.romanov@nginx.com self.ws.frame_write( 7971625Smax.romanov@nginx.com sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1 7981625Smax.romanov@nginx.com ) 7991625Smax.romanov@nginx.com self.ws.frame_write( 8001625Smax.romanov@nginx.com sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1 8011625Smax.romanov@nginx.com ) 8021625Smax.romanov@nginx.com 8031625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 8041625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 8051625Smax.romanov@nginx.com 8061625Smax.romanov@nginx.com # 5_6 8071625Smax.romanov@nginx.com 8081625Smax.romanov@nginx.com ping_payload = 'ping payload' 8091625Smax.romanov@nginx.com 8101625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 8111625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, ping_payload) 8121625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 8131625Smax.romanov@nginx.com 8141625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 8151625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, ping_payload) 8161625Smax.romanov@nginx.com 8171625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 8181625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 8191625Smax.romanov@nginx.com 8201625Smax.romanov@nginx.com # 5_7 8211625Smax.romanov@nginx.com 8221625Smax.romanov@nginx.com ping_payload = 'ping payload' 8231625Smax.romanov@nginx.com 8241625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 8251625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', '5_7' 8261625Smax.romanov@nginx.com 8271625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, ping_payload) 8281625Smax.romanov@nginx.com 8291625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 8301625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, ping_payload) 8311625Smax.romanov@nginx.com 8321625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 8331625Smax.romanov@nginx.com 8341625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 8351625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 8361625Smax.romanov@nginx.com 8371625Smax.romanov@nginx.com # 5_8 8381625Smax.romanov@nginx.com 8391625Smax.romanov@nginx.com ping_payload = 'ping payload' 8401625Smax.romanov@nginx.com 8411625Smax.romanov@nginx.com self.ws.frame_write( 8421625Smax.romanov@nginx.com sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1 8431625Smax.romanov@nginx.com ) 8441625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, ping_payload, chopsize=1) 8451625Smax.romanov@nginx.com self.ws.frame_write( 8461625Smax.romanov@nginx.com sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1 8471625Smax.romanov@nginx.com ) 8481625Smax.romanov@nginx.com 8491625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 8501625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, ping_payload) 8511625Smax.romanov@nginx.com 8521625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 8531625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') 8541625Smax.romanov@nginx.com 8551625Smax.romanov@nginx.com # 5_9 8561625Smax.romanov@nginx.com 8571625Smax.romanov@nginx.com self.ws.frame_write( 8581625Smax.romanov@nginx.com sock, self.ws.OP_CONT, 'non-continuation payload', fin=True 8591625Smax.romanov@nginx.com ) 8601625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 8611625Smax.romanov@nginx.com self.check_close(sock, 1002) 8621625Smax.romanov@nginx.com 8631625Smax.romanov@nginx.com # 5_10 8641625Smax.romanov@nginx.com 8651625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 8661625Smax.romanov@nginx.com 8671625Smax.romanov@nginx.com self.ws.frame_write( 8681625Smax.romanov@nginx.com sock, self.ws.OP_CONT, 'non-continuation payload', fin=True 8691625Smax.romanov@nginx.com ) 8701625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 8711625Smax.romanov@nginx.com self.check_close(sock, 1002) 8721625Smax.romanov@nginx.com 8731625Smax.romanov@nginx.com # 5_11 8741625Smax.romanov@nginx.com 8751625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 8761625Smax.romanov@nginx.com 8771625Smax.romanov@nginx.com self.ws.frame_write( 8781625Smax.romanov@nginx.com sock, 8791625Smax.romanov@nginx.com self.ws.OP_CONT, 8801625Smax.romanov@nginx.com 'non-continuation payload', 8811625Smax.romanov@nginx.com fin=True, 8821625Smax.romanov@nginx.com chopsize=1, 8831625Smax.romanov@nginx.com ) 8841625Smax.romanov@nginx.com self.ws.frame_write( 8851625Smax.romanov@nginx.com sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1 8861625Smax.romanov@nginx.com ) 8871625Smax.romanov@nginx.com self.check_close(sock, 1002) 8881625Smax.romanov@nginx.com 8891625Smax.romanov@nginx.com # 5_12 8901625Smax.romanov@nginx.com 8911625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 8921625Smax.romanov@nginx.com 8931625Smax.romanov@nginx.com self.ws.frame_write( 8941625Smax.romanov@nginx.com sock, self.ws.OP_CONT, 'non-continuation payload', fin=False 8951625Smax.romanov@nginx.com ) 8961625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 8971625Smax.romanov@nginx.com self.check_close(sock, 1002) 8981625Smax.romanov@nginx.com 8991625Smax.romanov@nginx.com # 5_13 9001625Smax.romanov@nginx.com 9011625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 9021625Smax.romanov@nginx.com 9031625Smax.romanov@nginx.com self.ws.frame_write( 9041625Smax.romanov@nginx.com sock, self.ws.OP_CONT, 'non-continuation payload', fin=False 9051625Smax.romanov@nginx.com ) 9061625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True) 9071625Smax.romanov@nginx.com self.check_close(sock, 1002) 9081625Smax.romanov@nginx.com 9091625Smax.romanov@nginx.com # 5_14 9101625Smax.romanov@nginx.com 9111625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 9121625Smax.romanov@nginx.com 9131625Smax.romanov@nginx.com self.ws.frame_write( 9141625Smax.romanov@nginx.com sock, 9151625Smax.romanov@nginx.com self.ws.OP_CONT, 9161625Smax.romanov@nginx.com 'non-continuation payload', 9171625Smax.romanov@nginx.com fin=False, 9181625Smax.romanov@nginx.com chopsize=1, 9191625Smax.romanov@nginx.com ) 9201625Smax.romanov@nginx.com self.ws.frame_write( 9211625Smax.romanov@nginx.com sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1 9221625Smax.romanov@nginx.com ) 9231625Smax.romanov@nginx.com self.check_close(sock, 1002) 9241625Smax.romanov@nginx.com 9251625Smax.romanov@nginx.com # 5_15 9261625Smax.romanov@nginx.com 9271625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 9281625Smax.romanov@nginx.com 9291625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 9301625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True) 9311625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 9321625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment4', fin=True) 9331625Smax.romanov@nginx.com self.check_close(sock, 1002) 9341625Smax.romanov@nginx.com 9351625Smax.romanov@nginx.com # 5_16 9361625Smax.romanov@nginx.com 9371625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 9381625Smax.romanov@nginx.com 9391625Smax.romanov@nginx.com for i in range(0, 2): 9401625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=False) 9411625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False) 9421625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True) 9431625Smax.romanov@nginx.com self.check_close(sock, 1002) 9441625Smax.romanov@nginx.com 9451625Smax.romanov@nginx.com # 5_17 9461625Smax.romanov@nginx.com 9471625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 9481625Smax.romanov@nginx.com 9491625Smax.romanov@nginx.com for i in range(0, 2): 9501625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=True) 9511625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False) 9521625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True) 9531625Smax.romanov@nginx.com self.check_close(sock, 1002) 9541625Smax.romanov@nginx.com 9551625Smax.romanov@nginx.com # 5_18 9561625Smax.romanov@nginx.com 9571625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 9581625Smax.romanov@nginx.com 9591625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 9601625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2') 9611625Smax.romanov@nginx.com self.check_close(sock, 1002) 9621625Smax.romanov@nginx.com 9631625Smax.romanov@nginx.com # 5_19 9641625Smax.romanov@nginx.com 9651625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 9661625Smax.romanov@nginx.com 9671625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 9681625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False) 9691625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!') 9701625Smax.romanov@nginx.com 9711625Smax.romanov@nginx.com time.sleep(1) 9721625Smax.romanov@nginx.com 9731625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 9741625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False) 9751625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!') 9761625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5') 9771625Smax.romanov@nginx.com 9781625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 9791625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!') 9801625Smax.romanov@nginx.com 9811625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 9821625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!') 9831625Smax.romanov@nginx.com 9841625Smax.romanov@nginx.com self.check_frame( 9851625Smax.romanov@nginx.com self.ws.frame_read(sock), 9861625Smax.romanov@nginx.com True, 9871625Smax.romanov@nginx.com self.ws.OP_TEXT, 9881625Smax.romanov@nginx.com 'fragment1fragment2fragment3fragment4fragment5', 9891625Smax.romanov@nginx.com ) 9901625Smax.romanov@nginx.com 9911625Smax.romanov@nginx.com # 5_20 9921625Smax.romanov@nginx.com 9931625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 9941625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False) 9951625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!') 9961625Smax.romanov@nginx.com 9971625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 9981625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!') 9991625Smax.romanov@nginx.com 10001625Smax.romanov@nginx.com time.sleep(1) 10011625Smax.romanov@nginx.com 10021625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False) 10031625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False) 10041625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!') 10051625Smax.romanov@nginx.com 10061625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10071625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!') 10081625Smax.romanov@nginx.com 10091625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', '5_20' 10101625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5') 10111625Smax.romanov@nginx.com 10121625Smax.romanov@nginx.com self.check_frame( 10131625Smax.romanov@nginx.com self.ws.frame_read(sock), 10141625Smax.romanov@nginx.com True, 10151625Smax.romanov@nginx.com self.ws.OP_TEXT, 10161625Smax.romanov@nginx.com 'fragment1fragment2fragment3fragment4fragment5', 10171625Smax.romanov@nginx.com ) 10181625Smax.romanov@nginx.com 10191625Smax.romanov@nginx.com self.close_connection(sock) 10201625Smax.romanov@nginx.com 10211625Smax.romanov@nginx.com def test_asgi_websockets_6_1_1__6_4_4(self): 10221625Smax.romanov@nginx.com self.load('websockets/mirror') 10231625Smax.romanov@nginx.com 10241625Smax.romanov@nginx.com # 6_1_1 10251625Smax.romanov@nginx.com 10261625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 10271625Smax.romanov@nginx.com 10281625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, '') 10291625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10301625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, '') 10311625Smax.romanov@nginx.com 10321625Smax.romanov@nginx.com # 6_1_2 10331625Smax.romanov@nginx.com 10341625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False) 10351625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, '', fin=False) 10361625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, '') 10371625Smax.romanov@nginx.com 10381625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10391625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, '') 10401625Smax.romanov@nginx.com 10411625Smax.romanov@nginx.com # 6_1_3 10421625Smax.romanov@nginx.com 10431625Smax.romanov@nginx.com payload = 'middle frame payload' 10441625Smax.romanov@nginx.com 10451625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False) 10461625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, payload, fin=False) 10471625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, '') 10481625Smax.romanov@nginx.com 10491625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10501625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 10511625Smax.romanov@nginx.com 10521625Smax.romanov@nginx.com # 6_2_1 10531625Smax.romanov@nginx.com 10541625Smax.romanov@nginx.com payload = 'Hello-µ@ßöäüàá-UTF-8!!' 10551625Smax.romanov@nginx.com 10561625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 10571625Smax.romanov@nginx.com 10581625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10591625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 10601625Smax.romanov@nginx.com 10611625Smax.romanov@nginx.com # 6_2_2 10621625Smax.romanov@nginx.com 10631625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload[:12], fin=False) 10641625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, payload[12:]) 10651625Smax.romanov@nginx.com 10661625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10671625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 10681625Smax.romanov@nginx.com 10691625Smax.romanov@nginx.com # 6_2_3 10701625Smax.romanov@nginx.com 10711625Smax.romanov@nginx.com self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 10721625Smax.romanov@nginx.com 10731625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10741625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 10751625Smax.romanov@nginx.com 10761625Smax.romanov@nginx.com # 6_2_4 10771625Smax.romanov@nginx.com 10781625Smax.romanov@nginx.com payload = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5' 10791625Smax.romanov@nginx.com 10801625Smax.romanov@nginx.com self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 10811625Smax.romanov@nginx.com 10821625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 10831625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 10841625Smax.romanov@nginx.com 10851625Smax.romanov@nginx.com self.close_connection(sock) 10861625Smax.romanov@nginx.com 10871625Smax.romanov@nginx.com# Unit does not support UTF-8 validation 10881625Smax.romanov@nginx.com# 10891625Smax.romanov@nginx.com# # 6_3_1 FAIL 10901625Smax.romanov@nginx.com# 10911625Smax.romanov@nginx.com# payload_1 = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5' 10921625Smax.romanov@nginx.com# payload_2 = '\xed\xa0\x80' 10931625Smax.romanov@nginx.com# payload_3 = '\x65\x64\x69\x74\x65\x64' 10941625Smax.romanov@nginx.com# 10951625Smax.romanov@nginx.com# payload = payload_1 + payload_2 + payload_3 10961625Smax.romanov@nginx.com# 10971625Smax.romanov@nginx.com# self.ws.message(sock, self.ws.OP_TEXT, payload) 10981625Smax.romanov@nginx.com# self.check_close(sock, 1007) 10991625Smax.romanov@nginx.com# 11001625Smax.romanov@nginx.com# # 6_3_2 FAIL 11011625Smax.romanov@nginx.com# 11021625Smax.romanov@nginx.com# _, sock, _ = self.ws.upgrade() 11031625Smax.romanov@nginx.com# 11041625Smax.romanov@nginx.com# self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1) 11051625Smax.romanov@nginx.com# self.check_close(sock, 1007) 11061625Smax.romanov@nginx.com# 11071625Smax.romanov@nginx.com# # 6_4_1 ... 6_4_4 FAIL 11081625Smax.romanov@nginx.com 11091625Smax.romanov@nginx.com def test_asgi_websockets_7_1_1__7_5_1(self): 11101625Smax.romanov@nginx.com self.load('websockets/mirror') 11111625Smax.romanov@nginx.com 11121625Smax.romanov@nginx.com # 7_1_1 11131625Smax.romanov@nginx.com 11141625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11151625Smax.romanov@nginx.com 11161625Smax.romanov@nginx.com payload = "Hello World!" 11171625Smax.romanov@nginx.com 11181625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 11191625Smax.romanov@nginx.com 11201625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 11211625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 11221625Smax.romanov@nginx.com 11231625Smax.romanov@nginx.com self.close_connection(sock) 11241625Smax.romanov@nginx.com 11251625Smax.romanov@nginx.com # 7_1_2 11261625Smax.romanov@nginx.com 11271625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11281625Smax.romanov@nginx.com 11291625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 11301625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 11311625Smax.romanov@nginx.com 11321625Smax.romanov@nginx.com self.check_close(sock) 11331625Smax.romanov@nginx.com 11341625Smax.romanov@nginx.com # 7_1_3 11351625Smax.romanov@nginx.com 11361625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11371625Smax.romanov@nginx.com 11381625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 11391625Smax.romanov@nginx.com self.check_close(sock, no_close=True) 11401625Smax.romanov@nginx.com 11411625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 11421625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 11431625Smax.romanov@nginx.com 11441625Smax.romanov@nginx.com sock.close() 11451625Smax.romanov@nginx.com 11461625Smax.romanov@nginx.com # 7_1_4 11471625Smax.romanov@nginx.com 11481625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11491625Smax.romanov@nginx.com 11501625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 11511625Smax.romanov@nginx.com self.check_close(sock, no_close=True) 11521625Smax.romanov@nginx.com 11531625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 11541625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 11551625Smax.romanov@nginx.com 11561625Smax.romanov@nginx.com sock.close() 11571625Smax.romanov@nginx.com 11581625Smax.romanov@nginx.com # 7_1_5 11591625Smax.romanov@nginx.com 11601625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11611625Smax.romanov@nginx.com 11621625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) 11631625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 11641625Smax.romanov@nginx.com self.check_close(sock, no_close=True) 11651625Smax.romanov@nginx.com 11661625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2') 11671625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 11681625Smax.romanov@nginx.com 11691625Smax.romanov@nginx.com sock.close() 11701625Smax.romanov@nginx.com 11711625Smax.romanov@nginx.com # 7_1_6 11721625Smax.romanov@nginx.com 11731625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11741625Smax.romanov@nginx.com 11751625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10) 11761625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_TEXT, payload) 11771625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 11781625Smax.romanov@nginx.com 11791625Smax.romanov@nginx.com self.recvall(sock, read_timeout=1) 11801625Smax.romanov@nginx.com 11811625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_PING, '') 11821625Smax.romanov@nginx.com assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc' 11831625Smax.romanov@nginx.com 11841625Smax.romanov@nginx.com sock.close() 11851625Smax.romanov@nginx.com 11861625Smax.romanov@nginx.com # 7_3_1 11871625Smax.romanov@nginx.com 11881625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11891625Smax.romanov@nginx.com 11901625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, '') 11911625Smax.romanov@nginx.com self.check_close(sock) 11921625Smax.romanov@nginx.com 11931625Smax.romanov@nginx.com # 7_3_2 11941625Smax.romanov@nginx.com 11951625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 11961625Smax.romanov@nginx.com 11971625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, 'a') 11981625Smax.romanov@nginx.com self.check_close(sock, 1002) 11991625Smax.romanov@nginx.com 12001625Smax.romanov@nginx.com # 7_3_3 12011625Smax.romanov@nginx.com 12021625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12031625Smax.romanov@nginx.com 12041625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) 12051625Smax.romanov@nginx.com self.check_close(sock) 12061625Smax.romanov@nginx.com 12071625Smax.romanov@nginx.com # 7_3_4 12081625Smax.romanov@nginx.com 12091625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12101625Smax.romanov@nginx.com 12111625Smax.romanov@nginx.com payload = self.ws.serialize_close(reason='Hello World!') 12121625Smax.romanov@nginx.com 12131625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 12141625Smax.romanov@nginx.com self.check_close(sock) 12151625Smax.romanov@nginx.com 12161625Smax.romanov@nginx.com # 7_3_5 12171625Smax.romanov@nginx.com 12181625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12191625Smax.romanov@nginx.com 12201625Smax.romanov@nginx.com payload = self.ws.serialize_close(reason='*' * 123) 12211625Smax.romanov@nginx.com 12221625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 12231625Smax.romanov@nginx.com self.check_close(sock) 12241625Smax.romanov@nginx.com 12251625Smax.romanov@nginx.com # 7_3_6 12261625Smax.romanov@nginx.com 12271625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12281625Smax.romanov@nginx.com 12291625Smax.romanov@nginx.com payload = self.ws.serialize_close(reason='*' * 124) 12301625Smax.romanov@nginx.com 12311625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 12321625Smax.romanov@nginx.com self.check_close(sock, 1002) 12331625Smax.romanov@nginx.com 12341625Smax.romanov@nginx.com# # 7_5_1 FAIL Unit does not support UTF-8 validation 12351625Smax.romanov@nginx.com# 12361625Smax.romanov@nginx.com# _, sock, _ = self.ws.upgrade() 12371625Smax.romanov@nginx.com# 12381625Smax.romanov@nginx.com# payload = self.ws.serialize_close(reason = '\xce\xba\xe1\xbd\xb9\xcf' \ 12391625Smax.romanov@nginx.com# '\x83\xce\xbc\xce\xb5\xed\xa0\x80\x65\x64\x69\x74\x65\x64') 12401625Smax.romanov@nginx.com# 12411625Smax.romanov@nginx.com# self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 12421625Smax.romanov@nginx.com# self.check_close(sock, 1007) 12431625Smax.romanov@nginx.com 12441625Smax.romanov@nginx.com def test_asgi_websockets_7_7_X__7_9_X(self): 12451625Smax.romanov@nginx.com self.load('websockets/mirror') 12461625Smax.romanov@nginx.com 12471625Smax.romanov@nginx.com valid_codes = [ 12481625Smax.romanov@nginx.com 1000, 12491625Smax.romanov@nginx.com 1001, 12501625Smax.romanov@nginx.com 1002, 12511625Smax.romanov@nginx.com 1003, 12521625Smax.romanov@nginx.com 1007, 12531625Smax.romanov@nginx.com 1008, 12541625Smax.romanov@nginx.com 1009, 12551625Smax.romanov@nginx.com 1010, 12561625Smax.romanov@nginx.com 1011, 12571625Smax.romanov@nginx.com 3000, 12581625Smax.romanov@nginx.com 3999, 12591625Smax.romanov@nginx.com 4000, 12601625Smax.romanov@nginx.com 4999, 12611625Smax.romanov@nginx.com ] 12621625Smax.romanov@nginx.com 12631625Smax.romanov@nginx.com invalid_codes = [0, 999, 1004, 1005, 1006, 1016, 1100, 2000, 2999] 12641625Smax.romanov@nginx.com 12651625Smax.romanov@nginx.com for code in valid_codes: 12661625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12671625Smax.romanov@nginx.com 12681625Smax.romanov@nginx.com payload = self.ws.serialize_close(code=code) 12691625Smax.romanov@nginx.com 12701625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 12711625Smax.romanov@nginx.com self.check_close(sock) 12721625Smax.romanov@nginx.com 12731625Smax.romanov@nginx.com for code in invalid_codes: 12741625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12751625Smax.romanov@nginx.com 12761625Smax.romanov@nginx.com payload = self.ws.serialize_close(code=code) 12771625Smax.romanov@nginx.com 12781625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 12791625Smax.romanov@nginx.com self.check_close(sock, 1002) 12801625Smax.romanov@nginx.com 12811625Smax.romanov@nginx.com def test_asgi_websockets_7_13_1__7_13_2(self): 12821625Smax.romanov@nginx.com self.load('websockets/mirror') 12831625Smax.romanov@nginx.com 12841625Smax.romanov@nginx.com # 7_13_1 12851625Smax.romanov@nginx.com 12861625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12871625Smax.romanov@nginx.com 12881625Smax.romanov@nginx.com payload = self.ws.serialize_close(code=5000) 12891625Smax.romanov@nginx.com 12901625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 12911625Smax.romanov@nginx.com self.check_close(sock, 1002) 12921625Smax.romanov@nginx.com 12931625Smax.romanov@nginx.com # 7_13_2 12941625Smax.romanov@nginx.com 12951625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 12961625Smax.romanov@nginx.com 12971625Smax.romanov@nginx.com payload = struct.pack('!I', 65536) + ''.encode('utf-8') 12981625Smax.romanov@nginx.com 12991625Smax.romanov@nginx.com self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) 13001625Smax.romanov@nginx.com self.check_close(sock, 1002) 13011625Smax.romanov@nginx.com 13021625Smax.romanov@nginx.com def test_asgi_websockets_9_1_1__9_6_6(self, is_unsafe): 13031625Smax.romanov@nginx.com if not is_unsafe: 13041625Smax.romanov@nginx.com pytest.skip('unsafe, long run') 13051625Smax.romanov@nginx.com 13061625Smax.romanov@nginx.com self.load('websockets/mirror') 13071625Smax.romanov@nginx.com 13081625Smax.romanov@nginx.com assert 'success' in self.conf( 13091625Smax.romanov@nginx.com { 13101625Smax.romanov@nginx.com 'http': { 13111625Smax.romanov@nginx.com 'websocket': { 13121625Smax.romanov@nginx.com 'max_frame_size': 33554432, 13131625Smax.romanov@nginx.com 'keepalive_interval': 0, 13141625Smax.romanov@nginx.com } 13151625Smax.romanov@nginx.com } 13161625Smax.romanov@nginx.com }, 13171625Smax.romanov@nginx.com 'settings', 13181625Smax.romanov@nginx.com ), 'increase max_frame_size and keepalive_interval' 13191625Smax.romanov@nginx.com 13201625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 13211625Smax.romanov@nginx.com 13221625Smax.romanov@nginx.com op_text = self.ws.OP_TEXT 13231625Smax.romanov@nginx.com op_binary = self.ws.OP_BINARY 13241625Smax.romanov@nginx.com 13251625Smax.romanov@nginx.com def check_payload(opcode, length, chopsize=None): 13261625Smax.romanov@nginx.com if opcode == self.ws.OP_TEXT: 13271625Smax.romanov@nginx.com payload = '*' * length 13281625Smax.romanov@nginx.com else: 13291625Smax.romanov@nginx.com payload = b'*' * length 13301625Smax.romanov@nginx.com 13311625Smax.romanov@nginx.com self.ws.frame_write(sock, opcode, payload, chopsize=chopsize) 13321625Smax.romanov@nginx.com frame = self.ws.frame_read(sock, read_timeout=5) 13331625Smax.romanov@nginx.com self.check_frame(frame, True, opcode, payload) 13341625Smax.romanov@nginx.com 13351625Smax.romanov@nginx.com def check_message(opcode, f_size): 13361625Smax.romanov@nginx.com if opcode == self.ws.OP_TEXT: 13371625Smax.romanov@nginx.com payload = '*' * 4 * 2 ** 20 13381625Smax.romanov@nginx.com else: 13391625Smax.romanov@nginx.com payload = b'*' * 4 * 2 ** 20 13401625Smax.romanov@nginx.com 13411625Smax.romanov@nginx.com self.ws.message(sock, opcode, payload, fragmention_size=f_size) 13421625Smax.romanov@nginx.com frame = self.ws.frame_read(sock, read_timeout=5) 13431625Smax.romanov@nginx.com self.check_frame(frame, True, opcode, payload) 13441625Smax.romanov@nginx.com 13451625Smax.romanov@nginx.com check_payload(op_text, 64 * 2 ** 10) # 9_1_1 13461625Smax.romanov@nginx.com check_payload(op_text, 256 * 2 ** 10) # 9_1_2 13471625Smax.romanov@nginx.com check_payload(op_text, 2 ** 20) # 9_1_3 13481625Smax.romanov@nginx.com check_payload(op_text, 4 * 2 ** 20) # 9_1_4 13491625Smax.romanov@nginx.com check_payload(op_text, 8 * 2 ** 20) # 9_1_5 13501625Smax.romanov@nginx.com check_payload(op_text, 16 * 2 ** 20) # 9_1_6 13511625Smax.romanov@nginx.com 13521625Smax.romanov@nginx.com check_payload(op_binary, 64 * 2 ** 10) # 9_2_1 13531625Smax.romanov@nginx.com check_payload(op_binary, 256 * 2 ** 10) # 9_2_2 13541625Smax.romanov@nginx.com check_payload(op_binary, 2 ** 20) # 9_2_3 13551625Smax.romanov@nginx.com check_payload(op_binary, 4 * 2 ** 20) # 9_2_4 13561625Smax.romanov@nginx.com check_payload(op_binary, 8 * 2 ** 20) # 9_2_5 13571625Smax.romanov@nginx.com check_payload(op_binary, 16 * 2 ** 20) # 9_2_6 13581625Smax.romanov@nginx.com 13591625Smax.romanov@nginx.com if option.system != 'Darwin' and option.system != 'FreeBSD': 13601625Smax.romanov@nginx.com check_message(op_text, 64) # 9_3_1 13611625Smax.romanov@nginx.com check_message(op_text, 256) # 9_3_2 13621625Smax.romanov@nginx.com check_message(op_text, 2 ** 10) # 9_3_3 13631625Smax.romanov@nginx.com check_message(op_text, 4 * 2 ** 10) # 9_3_4 13641625Smax.romanov@nginx.com check_message(op_text, 16 * 2 ** 10) # 9_3_5 13651625Smax.romanov@nginx.com check_message(op_text, 64 * 2 ** 10) # 9_3_6 13661625Smax.romanov@nginx.com check_message(op_text, 256 * 2 ** 10) # 9_3_7 13671625Smax.romanov@nginx.com check_message(op_text, 2 ** 20) # 9_3_8 13681625Smax.romanov@nginx.com check_message(op_text, 4 * 2 ** 20) # 9_3_9 13691625Smax.romanov@nginx.com 13701625Smax.romanov@nginx.com check_message(op_binary, 64) # 9_4_1 13711625Smax.romanov@nginx.com check_message(op_binary, 256) # 9_4_2 13721625Smax.romanov@nginx.com check_message(op_binary, 2 ** 10) # 9_4_3 13731625Smax.romanov@nginx.com check_message(op_binary, 4 * 2 ** 10) # 9_4_4 13741625Smax.romanov@nginx.com check_message(op_binary, 16 * 2 ** 10) # 9_4_5 13751625Smax.romanov@nginx.com check_message(op_binary, 64 * 2 ** 10) # 9_4_6 13761625Smax.romanov@nginx.com check_message(op_binary, 256 * 2 ** 10) # 9_4_7 13771625Smax.romanov@nginx.com check_message(op_binary, 2 ** 20) # 9_4_8 13781625Smax.romanov@nginx.com check_message(op_binary, 4 * 2 ** 20) # 9_4_9 13791625Smax.romanov@nginx.com 13801625Smax.romanov@nginx.com check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1 13811625Smax.romanov@nginx.com check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2 13821625Smax.romanov@nginx.com check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3 13831625Smax.romanov@nginx.com check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4 13841625Smax.romanov@nginx.com check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5 13851625Smax.romanov@nginx.com check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6 13861625Smax.romanov@nginx.com 13871625Smax.romanov@nginx.com check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1 13881625Smax.romanov@nginx.com check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2 13891625Smax.romanov@nginx.com check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3 13901625Smax.romanov@nginx.com check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4 13911625Smax.romanov@nginx.com check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5 13921625Smax.romanov@nginx.com check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6 13931625Smax.romanov@nginx.com 13941625Smax.romanov@nginx.com self.close_connection(sock) 13951625Smax.romanov@nginx.com 13961625Smax.romanov@nginx.com def test_asgi_websockets_10_1_1(self): 13971625Smax.romanov@nginx.com self.load('websockets/mirror') 13981625Smax.romanov@nginx.com 13991625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 14001625Smax.romanov@nginx.com 14011625Smax.romanov@nginx.com payload = '*' * 65536 14021625Smax.romanov@nginx.com 14031625Smax.romanov@nginx.com self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1300) 14041625Smax.romanov@nginx.com 14051625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 14061625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_TEXT, payload) 14071625Smax.romanov@nginx.com 14081625Smax.romanov@nginx.com self.close_connection(sock) 14091625Smax.romanov@nginx.com 14101625Smax.romanov@nginx.com # settings 14111625Smax.romanov@nginx.com 14121625Smax.romanov@nginx.com def test_asgi_websockets_max_frame_size(self): 14131625Smax.romanov@nginx.com self.load('websockets/mirror') 14141625Smax.romanov@nginx.com 14151625Smax.romanov@nginx.com assert 'success' in self.conf( 14161625Smax.romanov@nginx.com {'http': {'websocket': {'max_frame_size': 100}}}, 'settings' 14171625Smax.romanov@nginx.com ), 'configure max_frame_size' 14181625Smax.romanov@nginx.com 14191625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 14201625Smax.romanov@nginx.com 14211625Smax.romanov@nginx.com payload = '*' * 94 14221625Smax.romanov@nginx.com opcode = self.ws.OP_TEXT 14231625Smax.romanov@nginx.com 14241625Smax.romanov@nginx.com self.ws.frame_write(sock, opcode, payload) # frame length is 100 14251625Smax.romanov@nginx.com 14261625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 14271625Smax.romanov@nginx.com self.check_frame(frame, True, opcode, payload) 14281625Smax.romanov@nginx.com 14291625Smax.romanov@nginx.com payload = '*' * 95 14301625Smax.romanov@nginx.com 14311625Smax.romanov@nginx.com self.ws.frame_write(sock, opcode, payload) # frame length is 101 14321625Smax.romanov@nginx.com self.check_close(sock, 1009) # 1009 - CLOSE_TOO_LARGE 14331625Smax.romanov@nginx.com 14341625Smax.romanov@nginx.com def test_asgi_websockets_read_timeout(self): 14351625Smax.romanov@nginx.com self.load('websockets/mirror') 14361625Smax.romanov@nginx.com 14371625Smax.romanov@nginx.com assert 'success' in self.conf( 14381625Smax.romanov@nginx.com {'http': {'websocket': {'read_timeout': 5}}}, 'settings' 14391625Smax.romanov@nginx.com ), 'configure read_timeout' 14401625Smax.romanov@nginx.com 14411625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 14421625Smax.romanov@nginx.com 14431625Smax.romanov@nginx.com frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah') 14441625Smax.romanov@nginx.com sock.sendall(frame[:2]) 14451625Smax.romanov@nginx.com 14461625Smax.romanov@nginx.com time.sleep(2) 14471625Smax.romanov@nginx.com 14481625Smax.romanov@nginx.com self.check_close(sock, 1001) # 1001 - CLOSE_GOING_AWAY 14491625Smax.romanov@nginx.com 14501625Smax.romanov@nginx.com def test_asgi_websockets_keepalive_interval(self): 14511625Smax.romanov@nginx.com self.load('websockets/mirror') 14521625Smax.romanov@nginx.com 14531625Smax.romanov@nginx.com assert 'success' in self.conf( 14541625Smax.romanov@nginx.com {'http': {'websocket': {'keepalive_interval': 5}}}, 'settings' 14551625Smax.romanov@nginx.com ), 'configure keepalive_interval' 14561625Smax.romanov@nginx.com 14571625Smax.romanov@nginx.com _, sock, _ = self.ws.upgrade() 14581625Smax.romanov@nginx.com 14591625Smax.romanov@nginx.com frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah') 14601625Smax.romanov@nginx.com sock.sendall(frame[:2]) 14611625Smax.romanov@nginx.com 14621625Smax.romanov@nginx.com time.sleep(2) 14631625Smax.romanov@nginx.com 14641625Smax.romanov@nginx.com frame = self.ws.frame_read(sock) 14651625Smax.romanov@nginx.com self.check_frame(frame, True, self.ws.OP_PING, '') # PING frame 14661625Smax.romanov@nginx.com 14671625Smax.romanov@nginx.com sock.close() 1468