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