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