11477Szelenkov@nginx.comimport struct
21130Szelenkov@nginx.comimport time
31477Szelenkov@nginx.com
41635Szelenkov@nginx.comimport pytest
5*1848Szelenkov@nginx.com
61130Szelenkov@nginx.comfrom unit.applications.lang.node import TestApplicationNode
71130Szelenkov@nginx.comfrom unit.applications.websockets import TestApplicationWebsocket
81730Szelenkov@nginx.comfrom unit.option import option
91130Szelenkov@nginx.com
101150Szelenkov@nginx.com
111130Szelenkov@nginx.comclass TestNodeWebsockets(TestApplicationNode):
121467Szelenkov@nginx.com    prerequisites = {'modules': {'node': 'any'}}
131130Szelenkov@nginx.com
141130Szelenkov@nginx.com    ws = TestApplicationWebsocket()
151130Szelenkov@nginx.com
161736Szelenkov@nginx.com    @pytest.fixture(autouse=True)
171736Szelenkov@nginx.com    def setup_method_fixture(self, request, skip_alert):
181596Szelenkov@nginx.com        assert 'success' in self.conf(
191596Szelenkov@nginx.com            {'http': {'websocket': {'keepalive_interval': 0}}}, 'settings'
201596Szelenkov@nginx.com        ), 'clear keepalive_interval'
211138Szelenkov@nginx.com
221596Szelenkov@nginx.com        skip_alert(r'socket close\(\d+\) failed')
231130Szelenkov@nginx.com
241130Szelenkov@nginx.com    def close_connection(self, sock):
251596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc'
261130Szelenkov@nginx.com
271130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
281130Szelenkov@nginx.com
291130Szelenkov@nginx.com        self.check_close(sock)
301130Szelenkov@nginx.com
311819Smax.romanov@nginx.com    def check_close(self, sock, code=1000, no_close=False, frame=None):
321819Smax.romanov@nginx.com        if frame == None:
331819Smax.romanov@nginx.com            frame = self.ws.frame_read(sock)
341130Szelenkov@nginx.com
351596Szelenkov@nginx.com        assert frame['fin'] == True, 'close fin'
361596Szelenkov@nginx.com        assert frame['opcode'] == self.ws.OP_CLOSE, 'close opcode'
371596Szelenkov@nginx.com        assert frame['code'] == code, 'close code'
381130Szelenkov@nginx.com
391130Szelenkov@nginx.com        if not no_close:
401130Szelenkov@nginx.com            sock.close()
411130Szelenkov@nginx.com
421130Szelenkov@nginx.com    def check_frame(self, frame, fin, opcode, payload, decode=True):
431130Szelenkov@nginx.com        if opcode == self.ws.OP_BINARY or not decode:
441130Szelenkov@nginx.com            data = frame['data']
451130Szelenkov@nginx.com        else:
461130Szelenkov@nginx.com            data = frame['data'].decode('utf-8')
471130Szelenkov@nginx.com
481596Szelenkov@nginx.com        assert frame['fin'] == fin, 'fin'
491596Szelenkov@nginx.com        assert frame['opcode'] == opcode, 'opcode'
501596Szelenkov@nginx.com        assert data == payload, 'payload'
511130Szelenkov@nginx.com
521130Szelenkov@nginx.com    def test_node_websockets_handshake(self):
531130Szelenkov@nginx.com        self.load('websockets/mirror')
541130Szelenkov@nginx.com
551130Szelenkov@nginx.com        resp, sock, key = self.ws.upgrade()
561130Szelenkov@nginx.com        sock.close()
571130Szelenkov@nginx.com
581596Szelenkov@nginx.com        assert resp['status'] == 101, 'status'
591596Szelenkov@nginx.com        assert resp['headers']['Upgrade'] == 'websocket', 'upgrade'
601596Szelenkov@nginx.com        assert resp['headers']['Connection'] == 'Upgrade', 'connection'
611596Szelenkov@nginx.com        assert resp['headers']['Sec-WebSocket-Accept'] == self.ws.accept(
621596Szelenkov@nginx.com            key
631596Szelenkov@nginx.com        ), 'key'
641130Szelenkov@nginx.com
651130Szelenkov@nginx.com    def test_node_websockets_mirror(self):
661130Szelenkov@nginx.com        self.load('websockets/mirror')
671130Szelenkov@nginx.com
681130Szelenkov@nginx.com        message = 'blah'
691130Szelenkov@nginx.com
701130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
711130Szelenkov@nginx.com
721130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, message)
731130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
741130Szelenkov@nginx.com
751596Szelenkov@nginx.com        assert message == frame['data'].decode('utf-8'), 'mirror'
761130Szelenkov@nginx.com
771130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, message)
781130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
791130Szelenkov@nginx.com
801596Szelenkov@nginx.com        assert message == frame['data'].decode('utf-8'), 'mirror 2'
811130Szelenkov@nginx.com
821130Szelenkov@nginx.com        sock.close()
831130Szelenkov@nginx.com
841130Szelenkov@nginx.com    def test_node_websockets_no_mask(self):
851130Szelenkov@nginx.com        self.load('websockets/mirror')
861130Szelenkov@nginx.com
871130Szelenkov@nginx.com        message = 'blah'
881130Szelenkov@nginx.com
891130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
901130Szelenkov@nginx.com
911130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, message, mask=False)
921130Szelenkov@nginx.com
931130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
941130Szelenkov@nginx.com
951596Szelenkov@nginx.com        assert frame['opcode'] == self.ws.OP_CLOSE, 'no mask opcode'
961596Szelenkov@nginx.com        assert frame['code'] == 1002, 'no mask close code'
971130Szelenkov@nginx.com
981130Szelenkov@nginx.com        sock.close()
991130Szelenkov@nginx.com
1001130Szelenkov@nginx.com    def test_node_websockets_fragmentation(self):
1011130Szelenkov@nginx.com        self.load('websockets/mirror')
1021130Szelenkov@nginx.com
1031130Szelenkov@nginx.com        message = 'blah'
1041130Szelenkov@nginx.com
1051130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
1061130Szelenkov@nginx.com
1071130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, message, fin=False)
1081130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, ' ', fin=False)
1091130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, message)
1101130Szelenkov@nginx.com
1111130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
1121130Szelenkov@nginx.com
1131596Szelenkov@nginx.com        assert message + ' ' + message == frame['data'].decode(
1141596Szelenkov@nginx.com            'utf-8'
1151596Szelenkov@nginx.com        ), 'mirror framing'
1161130Szelenkov@nginx.com
1171130Szelenkov@nginx.com        sock.close()
1181130Szelenkov@nginx.com
1191130Szelenkov@nginx.com    def test_node_websockets_frame_fragmentation_invalid(self):
1201130Szelenkov@nginx.com        self.load('websockets/mirror')
1211130Szelenkov@nginx.com
1221130Szelenkov@nginx.com        message = 'blah'
1231130Szelenkov@nginx.com
1241130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
1251130Szelenkov@nginx.com
1261130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, message, fin=False)
1271130Szelenkov@nginx.com
1281130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
1291130Szelenkov@nginx.com
1301130Szelenkov@nginx.com        frame.pop('data')
1311596Szelenkov@nginx.com        assert frame == {
1321596Szelenkov@nginx.com            'fin': True,
1331596Szelenkov@nginx.com            'rsv1': False,
1341596Szelenkov@nginx.com            'rsv2': False,
1351596Szelenkov@nginx.com            'rsv3': False,
1361596Szelenkov@nginx.com            'opcode': self.ws.OP_CLOSE,
1371596Szelenkov@nginx.com            'mask': 0,
1381596Szelenkov@nginx.com            'code': 1002,
1391596Szelenkov@nginx.com            'reason': 'Fragmented control frame',
1401596Szelenkov@nginx.com        }, 'close frame'
1411130Szelenkov@nginx.com
1421130Szelenkov@nginx.com        sock.close()
1431130Szelenkov@nginx.com
1441130Szelenkov@nginx.com    def test_node_websockets_large(self):
1451130Szelenkov@nginx.com        self.load('websockets/mirror_fragmentation')
1461130Szelenkov@nginx.com
1471130Szelenkov@nginx.com        message = '0123456789' * 3000
1481130Szelenkov@nginx.com
1491130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
1501130Szelenkov@nginx.com
1511130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, message)
1521130Szelenkov@nginx.com
1531130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
1541130Szelenkov@nginx.com        data = frame['data'].decode('utf-8')
1551130Szelenkov@nginx.com
1561130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
1571130Szelenkov@nginx.com        data += frame['data'].decode('utf-8')
1581130Szelenkov@nginx.com
1591596Szelenkov@nginx.com        assert message == data, 'large'
1601130Szelenkov@nginx.com
1611130Szelenkov@nginx.com        sock.close()
1621130Szelenkov@nginx.com
1631130Szelenkov@nginx.com    def test_node_websockets_two_clients(self):
1641130Szelenkov@nginx.com        self.load('websockets/mirror')
1651130Szelenkov@nginx.com
1661130Szelenkov@nginx.com        message1 = 'blah1'
1671130Szelenkov@nginx.com        message2 = 'blah2'
1681130Szelenkov@nginx.com
1691130Szelenkov@nginx.com        _, sock1, _ = self.ws.upgrade()
1701130Szelenkov@nginx.com        _, sock2, _ = self.ws.upgrade()
1711130Szelenkov@nginx.com
1721130Szelenkov@nginx.com        self.ws.frame_write(sock1, self.ws.OP_TEXT, message1)
1731130Szelenkov@nginx.com        self.ws.frame_write(sock2, self.ws.OP_TEXT, message2)
1741130Szelenkov@nginx.com
1751130Szelenkov@nginx.com        frame1 = self.ws.frame_read(sock1)
1761130Szelenkov@nginx.com        frame2 = self.ws.frame_read(sock2)
1771130Szelenkov@nginx.com
1781596Szelenkov@nginx.com        assert message1 == frame1['data'].decode('utf-8'), 'client 1'
1791596Szelenkov@nginx.com        assert message2 == frame2['data'].decode('utf-8'), 'client 2'
1801130Szelenkov@nginx.com
1811130Szelenkov@nginx.com        sock1.close()
1821130Szelenkov@nginx.com        sock2.close()
1831130Szelenkov@nginx.com
1841596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
1851150Szelenkov@nginx.com    def test_node_websockets_handshake_upgrade_absent(
186*1848Szelenkov@nginx.com        self,
1871150Szelenkov@nginx.com    ):  # FAIL https://tools.ietf.org/html/rfc6455#section-4.2.1
1881130Szelenkov@nginx.com        self.load('websockets/mirror')
1891130Szelenkov@nginx.com
1901150Szelenkov@nginx.com        resp = self.get(
1911150Szelenkov@nginx.com            headers={
1921150Szelenkov@nginx.com                'Host': 'localhost',
1931150Szelenkov@nginx.com                'Connection': 'Upgrade',
1941262Szelenkov@nginx.com                'Sec-WebSocket-Key': self.ws.key(),
1951150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
1961150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
1971150Szelenkov@nginx.com            },
1981150Szelenkov@nginx.com        )
1991130Szelenkov@nginx.com
2001596Szelenkov@nginx.com        assert resp['status'] == 400, 'upgrade absent'
2011130Szelenkov@nginx.com
2021130Szelenkov@nginx.com    def test_node_websockets_handshake_case_insensitive(self):
2031130Szelenkov@nginx.com        self.load('websockets/mirror')
2041130Szelenkov@nginx.com
2051262Szelenkov@nginx.com        resp, sock, _ = self.ws.upgrade(
2061150Szelenkov@nginx.com            headers={
2071150Szelenkov@nginx.com                'Host': 'localhost',
2081150Szelenkov@nginx.com                'Upgrade': 'WEBSOCKET',
2091150Szelenkov@nginx.com                'Connection': 'UPGRADE',
2101262Szelenkov@nginx.com                'Sec-WebSocket-Key': self.ws.key(),
2111150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
2121150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
2131262Szelenkov@nginx.com            }
2141150Szelenkov@nginx.com        )
2151262Szelenkov@nginx.com        sock.close()
2161130Szelenkov@nginx.com
2171596Szelenkov@nginx.com        assert resp['status'] == 101, 'status'
2181130Szelenkov@nginx.com
2191596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
2201150Szelenkov@nginx.com    def test_node_websockets_handshake_connection_absent(self):  # FAIL
2211130Szelenkov@nginx.com        self.load('websockets/mirror')
2221130Szelenkov@nginx.com
2231150Szelenkov@nginx.com        resp = self.get(
2241150Szelenkov@nginx.com            headers={
2251150Szelenkov@nginx.com                'Host': 'localhost',
2261150Szelenkov@nginx.com                'Upgrade': 'websocket',
2271262Szelenkov@nginx.com                'Sec-WebSocket-Key': self.ws.key(),
2281150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
2291150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
2301150Szelenkov@nginx.com            },
2311150Szelenkov@nginx.com        )
2321130Szelenkov@nginx.com
2331596Szelenkov@nginx.com        assert resp['status'] == 400, 'status'
2341130Szelenkov@nginx.com
2351130Szelenkov@nginx.com    def test_node_websockets_handshake_version_absent(self):
2361130Szelenkov@nginx.com        self.load('websockets/mirror')
2371130Szelenkov@nginx.com
2381150Szelenkov@nginx.com        resp = self.get(
2391150Szelenkov@nginx.com            headers={
2401150Szelenkov@nginx.com                'Host': 'localhost',
2411150Szelenkov@nginx.com                'Upgrade': 'websocket',
2421150Szelenkov@nginx.com                'Connection': 'Upgrade',
2431262Szelenkov@nginx.com                'Sec-WebSocket-Key': self.ws.key(),
2441150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
2451150Szelenkov@nginx.com            },
2461150Szelenkov@nginx.com        )
2471130Szelenkov@nginx.com
2481596Szelenkov@nginx.com        assert resp['status'] == 426, 'status'
2491130Szelenkov@nginx.com
2501596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
2511130Szelenkov@nginx.com    def test_node_websockets_handshake_key_invalid(self):
2521130Szelenkov@nginx.com        self.load('websockets/mirror')
2531130Szelenkov@nginx.com
2541150Szelenkov@nginx.com        resp = self.get(
2551150Szelenkov@nginx.com            headers={
2561150Szelenkov@nginx.com                'Host': 'localhost',
2571150Szelenkov@nginx.com                'Upgrade': 'websocket',
2581150Szelenkov@nginx.com                'Connection': 'Upgrade',
2591150Szelenkov@nginx.com                'Sec-WebSocket-Key': '!',
2601150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
2611150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
2621150Szelenkov@nginx.com            },
2631150Szelenkov@nginx.com        )
2641130Szelenkov@nginx.com
2651596Szelenkov@nginx.com        assert resp['status'] == 400, 'key length'
2661130Szelenkov@nginx.com
2671130Szelenkov@nginx.com        key = self.ws.key()
2681150Szelenkov@nginx.com        resp = self.get(
2691150Szelenkov@nginx.com            headers={
2701150Szelenkov@nginx.com                'Host': 'localhost',
2711150Szelenkov@nginx.com                'Upgrade': 'websocket',
2721150Szelenkov@nginx.com                'Connection': 'Upgrade',
2731150Szelenkov@nginx.com                'Sec-WebSocket-Key': [key, key],
2741150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
2751150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
2761150Szelenkov@nginx.com            },
2771150Szelenkov@nginx.com        )
2781130Szelenkov@nginx.com
279*1848Szelenkov@nginx.com        assert (
280*1848Szelenkov@nginx.com            resp['status'] == 400
281*1848Szelenkov@nginx.com        ), 'key double'  # FAIL https://tools.ietf.org/html/rfc6455#section-11.3.1
2821130Szelenkov@nginx.com
2831130Szelenkov@nginx.com    def test_node_websockets_handshake_method_invalid(self):
2841130Szelenkov@nginx.com        self.load('websockets/mirror')
2851130Szelenkov@nginx.com
2861150Szelenkov@nginx.com        resp = self.post(
2871150Szelenkov@nginx.com            headers={
2881150Szelenkov@nginx.com                'Host': 'localhost',
2891150Szelenkov@nginx.com                'Upgrade': 'websocket',
2901150Szelenkov@nginx.com                'Connection': 'Upgrade',
2911262Szelenkov@nginx.com                'Sec-WebSocket-Key': self.ws.key(),
2921150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
2931150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
2941150Szelenkov@nginx.com            },
2951150Szelenkov@nginx.com        )
2961130Szelenkov@nginx.com
2971596Szelenkov@nginx.com        assert resp['status'] == 400, 'status'
2981130Szelenkov@nginx.com
2991130Szelenkov@nginx.com    def test_node_websockets_handshake_http_10(self):
3001130Szelenkov@nginx.com        self.load('websockets/mirror')
3011130Szelenkov@nginx.com
3021150Szelenkov@nginx.com        resp = self.get(
3031150Szelenkov@nginx.com            headers={
3041150Szelenkov@nginx.com                'Host': 'localhost',
3051150Szelenkov@nginx.com                'Upgrade': 'websocket',
3061150Szelenkov@nginx.com                'Connection': 'Upgrade',
3071262Szelenkov@nginx.com                'Sec-WebSocket-Key': self.ws.key(),
3081150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
3091150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
3101150Szelenkov@nginx.com            },
3111150Szelenkov@nginx.com            http_10=True,
3121150Szelenkov@nginx.com        )
3131130Szelenkov@nginx.com
3141596Szelenkov@nginx.com        assert resp['status'] == 400, 'status'
3151130Szelenkov@nginx.com
3161130Szelenkov@nginx.com    def test_node_websockets_handshake_uri_invalid(self):
3171130Szelenkov@nginx.com        self.load('websockets/mirror')
3181130Szelenkov@nginx.com
3191150Szelenkov@nginx.com        resp = self.get(
3201150Szelenkov@nginx.com            headers={
3211150Szelenkov@nginx.com                'Host': 'localhost',
3221150Szelenkov@nginx.com                'Upgrade': 'websocket',
3231150Szelenkov@nginx.com                'Connection': 'Upgrade',
3241262Szelenkov@nginx.com                'Sec-WebSocket-Key': self.ws.key(),
3251150Szelenkov@nginx.com                'Sec-WebSocket-Protocol': 'chat',
3261150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
3271150Szelenkov@nginx.com            },
3281150Szelenkov@nginx.com            url='!',
3291150Szelenkov@nginx.com        )
3301130Szelenkov@nginx.com
3311596Szelenkov@nginx.com        assert resp['status'] == 400, 'status'
3321130Szelenkov@nginx.com
3331130Szelenkov@nginx.com    def test_node_websockets_protocol_absent(self):
3341130Szelenkov@nginx.com        self.load('websockets/mirror')
3351130Szelenkov@nginx.com
3361130Szelenkov@nginx.com        key = self.ws.key()
3371262Szelenkov@nginx.com        resp, sock, _ = self.ws.upgrade(
3381150Szelenkov@nginx.com            headers={
3391150Szelenkov@nginx.com                'Host': 'localhost',
3401150Szelenkov@nginx.com                'Upgrade': 'websocket',
3411150Szelenkov@nginx.com                'Connection': 'Upgrade',
3421150Szelenkov@nginx.com                'Sec-WebSocket-Key': key,
3431150Szelenkov@nginx.com                'Sec-WebSocket-Version': 13,
3441262Szelenkov@nginx.com            }
3451150Szelenkov@nginx.com        )
3461262Szelenkov@nginx.com        sock.close()
3471130Szelenkov@nginx.com
3481596Szelenkov@nginx.com        assert resp['status'] == 101, 'status'
3491596Szelenkov@nginx.com        assert resp['headers']['Upgrade'] == 'websocket', 'upgrade'
3501596Szelenkov@nginx.com        assert resp['headers']['Connection'] == 'Upgrade', 'connection'
3511596Szelenkov@nginx.com        assert resp['headers']['Sec-WebSocket-Accept'] == self.ws.accept(
3521596Szelenkov@nginx.com            key
3531596Szelenkov@nginx.com        ), 'key'
3541130Szelenkov@nginx.com
3551130Szelenkov@nginx.com    # autobahn-testsuite
3561150Szelenkov@nginx.com    #
3571130Szelenkov@nginx.com    # Some following tests fail because of Unit does not support UTF-8
3581130Szelenkov@nginx.com    # validation for websocket frames.  It should be implemented
3591130Szelenkov@nginx.com    # by application, if necessary.
3601130Szelenkov@nginx.com
3611130Szelenkov@nginx.com    def test_node_websockets_1_1_1__1_1_8(self):
3621130Szelenkov@nginx.com        self.load('websockets/mirror')
3631130Szelenkov@nginx.com
3641130Szelenkov@nginx.com        opcode = self.ws.OP_TEXT
3651130Szelenkov@nginx.com
3661130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
3671130Szelenkov@nginx.com
3681130Szelenkov@nginx.com        def check_length(length, chopsize=None):
3691130Szelenkov@nginx.com            payload = '*' * length
3701130Szelenkov@nginx.com
3711130Szelenkov@nginx.com            self.ws.frame_write(sock, opcode, payload, chopsize=chopsize)
3721130Szelenkov@nginx.com
3731130Szelenkov@nginx.com            frame = self.ws.frame_read(sock)
3741130Szelenkov@nginx.com            self.check_frame(frame, True, opcode, payload)
3751130Szelenkov@nginx.com
376*1848Szelenkov@nginx.com        check_length(0)  # 1_1_1
377*1848Szelenkov@nginx.com        check_length(125)  # 1_1_2
378*1848Szelenkov@nginx.com        check_length(126)  # 1_1_3
379*1848Szelenkov@nginx.com        check_length(127)  # 1_1_4
380*1848Szelenkov@nginx.com        check_length(128)  # 1_1_5
381*1848Szelenkov@nginx.com        check_length(65535)  # 1_1_6
382*1848Szelenkov@nginx.com        check_length(65536)  # 1_1_7
383*1848Szelenkov@nginx.com        check_length(65536, chopsize=997)  # 1_1_8
3841130Szelenkov@nginx.com
3851130Szelenkov@nginx.com        self.close_connection(sock)
3861130Szelenkov@nginx.com
3871130Szelenkov@nginx.com    def test_node_websockets_1_2_1__1_2_8(self):
3881130Szelenkov@nginx.com        self.load('websockets/mirror')
3891130Szelenkov@nginx.com
3901130Szelenkov@nginx.com        opcode = self.ws.OP_BINARY
3911130Szelenkov@nginx.com
3921130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
3931130Szelenkov@nginx.com
3941130Szelenkov@nginx.com        def check_length(length, chopsize=None):
3951130Szelenkov@nginx.com            payload = b'\xfe' * length
3961130Szelenkov@nginx.com
3971130Szelenkov@nginx.com            self.ws.frame_write(sock, opcode, payload, chopsize=chopsize)
3981130Szelenkov@nginx.com            frame = self.ws.frame_read(sock)
3991130Szelenkov@nginx.com
4001130Szelenkov@nginx.com            self.check_frame(frame, True, opcode, payload)
4011130Szelenkov@nginx.com
402*1848Szelenkov@nginx.com        check_length(0)  # 1_2_1
403*1848Szelenkov@nginx.com        check_length(125)  # 1_2_2
404*1848Szelenkov@nginx.com        check_length(126)  # 1_2_3
405*1848Szelenkov@nginx.com        check_length(127)  # 1_2_4
406*1848Szelenkov@nginx.com        check_length(128)  # 1_2_5
407*1848Szelenkov@nginx.com        check_length(65535)  # 1_2_6
408*1848Szelenkov@nginx.com        check_length(65536)  # 1_2_7
409*1848Szelenkov@nginx.com        check_length(65536, chopsize=997)  # 1_2_8
4101130Szelenkov@nginx.com
4111130Szelenkov@nginx.com        self.close_connection(sock)
4121130Szelenkov@nginx.com
4131130Szelenkov@nginx.com    def test_node_websockets_2_1__2_6(self):
4141130Szelenkov@nginx.com        self.load('websockets/mirror')
4151130Szelenkov@nginx.com
4161130Szelenkov@nginx.com        op_ping = self.ws.OP_PING
4171130Szelenkov@nginx.com        op_pong = self.ws.OP_PONG
4181130Szelenkov@nginx.com
4191130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
4201130Szelenkov@nginx.com
4211130Szelenkov@nginx.com        def check_ping(payload, chopsize=None, decode=True):
4221130Szelenkov@nginx.com            self.ws.frame_write(sock, op_ping, payload, chopsize=chopsize)
4231130Szelenkov@nginx.com            frame = self.ws.frame_read(sock)
4241130Szelenkov@nginx.com
4251130Szelenkov@nginx.com            self.check_frame(frame, True, op_pong, payload, decode=decode)
4261130Szelenkov@nginx.com
427*1848Szelenkov@nginx.com        check_ping('')  # 2_1
428*1848Szelenkov@nginx.com        check_ping('Hello, world!')  # 2_2
4291130Szelenkov@nginx.com        check_ping(b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff', decode=False)  # 2_3
430*1848Szelenkov@nginx.com        check_ping(b'\xfe' * 125, decode=False)  # 2_4
431*1848Szelenkov@nginx.com        check_ping(b'\xfe' * 125, chopsize=1, decode=False)  # 2_6
4321130Szelenkov@nginx.com
4331130Szelenkov@nginx.com        self.close_connection(sock)
4341130Szelenkov@nginx.com
4351130Szelenkov@nginx.com        # 2_5
4361130Szelenkov@nginx.com
4371130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
4381130Szelenkov@nginx.com
4391130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, b'\xfe' * 126)
4401130Szelenkov@nginx.com        self.check_close(sock, 1002)
4411130Szelenkov@nginx.com
4421130Szelenkov@nginx.com    def test_node_websockets_2_7__2_9(self):
4431130Szelenkov@nginx.com        self.load('websockets/mirror')
4441130Szelenkov@nginx.com
4451130Szelenkov@nginx.com        # 2_7
4461130Szelenkov@nginx.com
4471130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
4481130Szelenkov@nginx.com
4491130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PONG, '')
4501596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', '2_7'
4511130Szelenkov@nginx.com
4521130Szelenkov@nginx.com        # 2_8
4531130Szelenkov@nginx.com
4541130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload')
4551596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', '2_8'
4561130Szelenkov@nginx.com
4571130Szelenkov@nginx.com        # 2_9
4581130Szelenkov@nginx.com
4591130Szelenkov@nginx.com        payload = 'ping payload'
4601130Szelenkov@nginx.com
4611130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload')
4621130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, payload)
4631130Szelenkov@nginx.com
4641130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
4651130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, payload)
4661130Szelenkov@nginx.com
4671130Szelenkov@nginx.com        self.close_connection(sock)
4681130Szelenkov@nginx.com
4691130Szelenkov@nginx.com    def test_node_websockets_2_10__2_11(self):
4701130Szelenkov@nginx.com        self.load('websockets/mirror')
4711130Szelenkov@nginx.com
4721130Szelenkov@nginx.com        # 2_10
4731130Szelenkov@nginx.com
4741130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
4751130Szelenkov@nginx.com
4761130Szelenkov@nginx.com        for i in range(0, 10):
4771130Szelenkov@nginx.com            self.ws.frame_write(sock, self.ws.OP_PING, 'payload-%d' % i)
4781130Szelenkov@nginx.com
4791130Szelenkov@nginx.com        for i in range(0, 10):
4801130Szelenkov@nginx.com            frame = self.ws.frame_read(sock)
4811130Szelenkov@nginx.com            self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i)
4821130Szelenkov@nginx.com
4831130Szelenkov@nginx.com        # 2_11
4841130Szelenkov@nginx.com
4851130Szelenkov@nginx.com        for i in range(0, 10):
4861130Szelenkov@nginx.com            opcode = self.ws.OP_PING
4871130Szelenkov@nginx.com            self.ws.frame_write(sock, opcode, 'payload-%d' % i, chopsize=1)
4881130Szelenkov@nginx.com
4891130Szelenkov@nginx.com        for i in range(0, 10):
4901130Szelenkov@nginx.com            frame = self.ws.frame_read(sock)
4911130Szelenkov@nginx.com            self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i)
4921130Szelenkov@nginx.com
4931130Szelenkov@nginx.com        self.close_connection(sock)
4941130Szelenkov@nginx.com
4951596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
4961130Szelenkov@nginx.com    def test_node_websockets_3_1__3_7(self):
4971130Szelenkov@nginx.com        self.load('websockets/mirror')
4981130Szelenkov@nginx.com
4991130Szelenkov@nginx.com        payload = 'Hello, world!'
5001130Szelenkov@nginx.com
5011130Szelenkov@nginx.com        # 3_1
5021130Szelenkov@nginx.com
5031130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
5041130Szelenkov@nginx.com
5051130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv1=True)
5061130Szelenkov@nginx.com        self.check_close(sock, 1002)
5071130Szelenkov@nginx.com
5081130Szelenkov@nginx.com        # 3_2
5091130Szelenkov@nginx.com
5101130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
5111130Szelenkov@nginx.com
5121130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
5131130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv2=True)
5141130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
5151130Szelenkov@nginx.com
5161130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
5171130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
5181130Szelenkov@nginx.com
5191150Szelenkov@nginx.com        self.check_close(sock, 1002, no_close=True)
5201130Szelenkov@nginx.com
5211596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_2'
5221130Szelenkov@nginx.com        sock.close()
5231130Szelenkov@nginx.com
5241130Szelenkov@nginx.com        # 3_3
5251130Szelenkov@nginx.com
5261130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
5271130Szelenkov@nginx.com
5281130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
5291130Szelenkov@nginx.com
5301130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
5311130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
5321130Szelenkov@nginx.com
5331130Szelenkov@nginx.com        self.ws.frame_write(
5341150Szelenkov@nginx.com            sock, self.ws.OP_TEXT, payload, rsv1=True, rsv2=True
5351130Szelenkov@nginx.com        )
5361130Szelenkov@nginx.com
5371150Szelenkov@nginx.com        self.check_close(sock, 1002, no_close=True)
5381130Szelenkov@nginx.com
5391596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_3'
5401130Szelenkov@nginx.com        sock.close()
5411130Szelenkov@nginx.com
5421130Szelenkov@nginx.com        # 3_4
5431130Szelenkov@nginx.com
5441130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
5451130Szelenkov@nginx.com
5461130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1)
5471130Szelenkov@nginx.com        self.ws.frame_write(
5481150Szelenkov@nginx.com            sock, self.ws.OP_TEXT, payload, rsv3=True, chopsize=1
5491130Szelenkov@nginx.com        )
5501130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
5511130Szelenkov@nginx.com
5521130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
5531130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
5541130Szelenkov@nginx.com
5551150Szelenkov@nginx.com        self.check_close(sock, 1002, no_close=True)
5561130Szelenkov@nginx.com
5571596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_4'
5581130Szelenkov@nginx.com        sock.close()
5591130Szelenkov@nginx.com
5601130Szelenkov@nginx.com        # 3_5
5611130Szelenkov@nginx.com
5621130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
5631130Szelenkov@nginx.com
5641130Szelenkov@nginx.com        self.ws.frame_write(
5651130Szelenkov@nginx.com            sock,
5661130Szelenkov@nginx.com            self.ws.OP_BINARY,
5671130Szelenkov@nginx.com            b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff',
5681130Szelenkov@nginx.com            rsv1=True,
5691130Szelenkov@nginx.com            rsv3=True,
5701130Szelenkov@nginx.com        )
5711130Szelenkov@nginx.com
5721130Szelenkov@nginx.com        self.check_close(sock, 1002)
5731130Szelenkov@nginx.com
5741130Szelenkov@nginx.com        # 3_6
5751130Szelenkov@nginx.com
5761130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
5771130Szelenkov@nginx.com
5781130Szelenkov@nginx.com        self.ws.frame_write(
5791150Szelenkov@nginx.com            sock, self.ws.OP_PING, payload, rsv2=True, rsv3=True
5801130Szelenkov@nginx.com        )
5811130Szelenkov@nginx.com
5821130Szelenkov@nginx.com        self.check_close(sock, 1002)
5831130Szelenkov@nginx.com
5841130Szelenkov@nginx.com        # 3_7
5851130Szelenkov@nginx.com
5861130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
5871130Szelenkov@nginx.com
5881130Szelenkov@nginx.com        self.ws.frame_write(
5891150Szelenkov@nginx.com            sock, self.ws.OP_CLOSE, payload, rsv1=True, rsv2=True, rsv3=True
5901130Szelenkov@nginx.com        )
5911130Szelenkov@nginx.com
5921130Szelenkov@nginx.com        self.check_close(sock, 1002)
5931130Szelenkov@nginx.com
5941130Szelenkov@nginx.com    def test_node_websockets_4_1_1__4_2_5(self):
5951130Szelenkov@nginx.com        self.load('websockets/mirror')
5961130Szelenkov@nginx.com
5971130Szelenkov@nginx.com        payload = 'Hello, world!'
5981130Szelenkov@nginx.com
5991130Szelenkov@nginx.com        # 4_1_1
6001130Szelenkov@nginx.com
6011130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6021130Szelenkov@nginx.com
6031130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x03, '')
6041130Szelenkov@nginx.com        self.check_close(sock, 1002)
6051130Szelenkov@nginx.com
6061130Szelenkov@nginx.com        # 4_1_2
6071130Szelenkov@nginx.com
6081130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6091130Szelenkov@nginx.com
6101130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x04, 'reserved opcode payload')
6111130Szelenkov@nginx.com        self.check_close(sock, 1002)
6121130Szelenkov@nginx.com
6131130Szelenkov@nginx.com        # 4_1_3
6141130Szelenkov@nginx.com
6151130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6161130Szelenkov@nginx.com
6171130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
6181130Szelenkov@nginx.com
6191130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
6201130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
6211130Szelenkov@nginx.com
6221130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x05, '')
6231130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
6241130Szelenkov@nginx.com
6251130Szelenkov@nginx.com        self.check_close(sock, 1002)
6261130Szelenkov@nginx.com
6271130Szelenkov@nginx.com        # 4_1_4
6281130Szelenkov@nginx.com
6291130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6301130Szelenkov@nginx.com
6311130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
6321130Szelenkov@nginx.com
6331130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
6341130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
6351130Szelenkov@nginx.com
6361130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x06, payload)
6371130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
6381130Szelenkov@nginx.com
6391130Szelenkov@nginx.com        self.check_close(sock, 1002)
6401130Szelenkov@nginx.com
6411130Szelenkov@nginx.com        # 4_1_5
6421130Szelenkov@nginx.com
6431130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6441130Szelenkov@nginx.com
6451130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1)
6461130Szelenkov@nginx.com
6471130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
6481130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
6491130Szelenkov@nginx.com
6501130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x07, payload, chopsize=1)
6511130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
6521130Szelenkov@nginx.com
6531130Szelenkov@nginx.com        self.check_close(sock, 1002)
6541130Szelenkov@nginx.com
6551130Szelenkov@nginx.com        # 4_2_1
6561130Szelenkov@nginx.com
6571130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6581130Szelenkov@nginx.com
6591130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x0B, '')
6601130Szelenkov@nginx.com        self.check_close(sock, 1002)
6611130Szelenkov@nginx.com
6621130Szelenkov@nginx.com        # 4_2_2
6631130Szelenkov@nginx.com
6641130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6651130Szelenkov@nginx.com
6661130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x0C, 'reserved opcode payload')
6671130Szelenkov@nginx.com        self.check_close(sock, 1002)
6681130Szelenkov@nginx.com
6691130Szelenkov@nginx.com        # 4_2_3
6701130Szelenkov@nginx.com
6711130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6721130Szelenkov@nginx.com
6731130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
6741130Szelenkov@nginx.com
6751130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
6761130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
6771130Szelenkov@nginx.com
6781130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x0D, '')
6791130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
6801130Szelenkov@nginx.com
6811130Szelenkov@nginx.com        self.check_close(sock, 1002)
6821130Szelenkov@nginx.com
6831130Szelenkov@nginx.com        # 4_2_4
6841130Szelenkov@nginx.com
6851130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
6861130Szelenkov@nginx.com
6871130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
6881130Szelenkov@nginx.com
6891130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
6901130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
6911130Szelenkov@nginx.com
6921130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x0E, payload)
6931130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
6941130Szelenkov@nginx.com
6951130Szelenkov@nginx.com        self.check_close(sock, 1002)
6961130Szelenkov@nginx.com
6971130Szelenkov@nginx.com        # 4_2_5
6981130Szelenkov@nginx.com
6991130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
7001130Szelenkov@nginx.com
7011130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1)
7021130Szelenkov@nginx.com
7031130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7041130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
7051130Szelenkov@nginx.com
7061130Szelenkov@nginx.com        self.ws.frame_write(sock, 0x0F, payload, chopsize=1)
7071130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, '')
7081130Szelenkov@nginx.com
7091130Szelenkov@nginx.com        self.check_close(sock, 1002)
7101130Szelenkov@nginx.com
7111130Szelenkov@nginx.com    def test_node_websockets_5_1__5_20(self):
7121130Szelenkov@nginx.com        self.load('websockets/mirror')
7131130Szelenkov@nginx.com
7141130Szelenkov@nginx.com        # 5_1
7151130Szelenkov@nginx.com
7161130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
7171130Szelenkov@nginx.com
7181130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, 'fragment1', fin=False)
7191130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
7201130Szelenkov@nginx.com        self.check_close(sock, 1002)
7211130Szelenkov@nginx.com
7221130Szelenkov@nginx.com        # 5_2
7231130Szelenkov@nginx.com
7241130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
7251130Szelenkov@nginx.com
7261130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PONG, 'fragment1', fin=False)
7271130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
7281130Szelenkov@nginx.com        self.check_close(sock, 1002)
7291130Szelenkov@nginx.com
7301130Szelenkov@nginx.com        # 5_3
7311130Szelenkov@nginx.com
7321130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
7331130Szelenkov@nginx.com
7341130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
7351130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
7361130Szelenkov@nginx.com
7371130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7381130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
7391130Szelenkov@nginx.com
7401130Szelenkov@nginx.com        # 5_4
7411130Szelenkov@nginx.com
7421130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
7431596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', '5_4'
7441130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
7451130Szelenkov@nginx.com
7461130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7471130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
7481130Szelenkov@nginx.com
7491130Szelenkov@nginx.com        # 5_5
7501130Szelenkov@nginx.com
7511130Szelenkov@nginx.com        self.ws.frame_write(
7521150Szelenkov@nginx.com            sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1
7531130Szelenkov@nginx.com        )
7541130Szelenkov@nginx.com        self.ws.frame_write(
7551150Szelenkov@nginx.com            sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1
7561130Szelenkov@nginx.com        )
7571130Szelenkov@nginx.com
7581130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7591130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
7601130Szelenkov@nginx.com
7611130Szelenkov@nginx.com        # 5_6
7621130Szelenkov@nginx.com
7631130Szelenkov@nginx.com        ping_payload = 'ping payload'
7641130Szelenkov@nginx.com
7651130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
7661130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, ping_payload)
7671130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
7681130Szelenkov@nginx.com
7691130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7701130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, ping_payload)
7711130Szelenkov@nginx.com
7721130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7731130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
7741130Szelenkov@nginx.com
7751130Szelenkov@nginx.com        # 5_7
7761130Szelenkov@nginx.com
7771130Szelenkov@nginx.com        ping_payload = 'ping payload'
7781130Szelenkov@nginx.com
7791130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
7801596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', '5_7'
7811130Szelenkov@nginx.com
7821130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, ping_payload)
7831130Szelenkov@nginx.com
7841130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7851130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, ping_payload)
7861130Szelenkov@nginx.com
7871130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
7881130Szelenkov@nginx.com
7891130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
7901130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
7911130Szelenkov@nginx.com
7921130Szelenkov@nginx.com        # 5_8
7931130Szelenkov@nginx.com
7941130Szelenkov@nginx.com        ping_payload = 'ping payload'
7951130Szelenkov@nginx.com
7961130Szelenkov@nginx.com        self.ws.frame_write(
7971150Szelenkov@nginx.com            sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1
7981130Szelenkov@nginx.com        )
7991130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, ping_payload, chopsize=1)
8001130Szelenkov@nginx.com        self.ws.frame_write(
8011150Szelenkov@nginx.com            sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1
8021130Szelenkov@nginx.com        )
8031130Szelenkov@nginx.com
8041130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
8051130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, ping_payload)
8061130Szelenkov@nginx.com
8071130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
8081130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
8091130Szelenkov@nginx.com
8101130Szelenkov@nginx.com        # 5_9
8111130Szelenkov@nginx.com
8121130Szelenkov@nginx.com        self.ws.frame_write(
8131150Szelenkov@nginx.com            sock, self.ws.OP_CONT, 'non-continuation payload', fin=True
8141130Szelenkov@nginx.com        )
8151130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
8161130Szelenkov@nginx.com        self.check_close(sock, 1002)
8171130Szelenkov@nginx.com
8181130Szelenkov@nginx.com        # 5_10
8191130Szelenkov@nginx.com
8201130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
8211130Szelenkov@nginx.com
8221130Szelenkov@nginx.com        self.ws.frame_write(
8231150Szelenkov@nginx.com            sock, self.ws.OP_CONT, 'non-continuation payload', fin=True
8241130Szelenkov@nginx.com        )
8251130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
8261130Szelenkov@nginx.com        self.check_close(sock, 1002)
8271130Szelenkov@nginx.com
8281130Szelenkov@nginx.com        # 5_11
8291130Szelenkov@nginx.com
8301130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
8311130Szelenkov@nginx.com
8321130Szelenkov@nginx.com        self.ws.frame_write(
8331130Szelenkov@nginx.com            sock,
8341130Szelenkov@nginx.com            self.ws.OP_CONT,
8351130Szelenkov@nginx.com            'non-continuation payload',
8361130Szelenkov@nginx.com            fin=True,
8371130Szelenkov@nginx.com            chopsize=1,
8381130Szelenkov@nginx.com        )
8391130Szelenkov@nginx.com        self.ws.frame_write(
8401150Szelenkov@nginx.com            sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1
8411130Szelenkov@nginx.com        )
8421130Szelenkov@nginx.com        self.check_close(sock, 1002)
8431130Szelenkov@nginx.com
8441130Szelenkov@nginx.com        # 5_12
8451130Szelenkov@nginx.com
8461130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
8471130Szelenkov@nginx.com
8481130Szelenkov@nginx.com        self.ws.frame_write(
8491150Szelenkov@nginx.com            sock, self.ws.OP_CONT, 'non-continuation payload', fin=False
8501130Szelenkov@nginx.com        )
8511130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
8521130Szelenkov@nginx.com        self.check_close(sock, 1002)
8531130Szelenkov@nginx.com
8541130Szelenkov@nginx.com        # 5_13
8551130Szelenkov@nginx.com
8561130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
8571130Szelenkov@nginx.com
8581130Szelenkov@nginx.com        self.ws.frame_write(
8591150Szelenkov@nginx.com            sock, self.ws.OP_CONT, 'non-continuation payload', fin=False
8601130Szelenkov@nginx.com        )
8611130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
8621130Szelenkov@nginx.com        self.check_close(sock, 1002)
8631130Szelenkov@nginx.com
8641130Szelenkov@nginx.com        # 5_14
8651130Szelenkov@nginx.com
8661130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
8671130Szelenkov@nginx.com
8681130Szelenkov@nginx.com        self.ws.frame_write(
8691130Szelenkov@nginx.com            sock,
8701130Szelenkov@nginx.com            self.ws.OP_CONT,
8711130Szelenkov@nginx.com            'non-continuation payload',
8721130Szelenkov@nginx.com            fin=False,
8731130Szelenkov@nginx.com            chopsize=1,
8741130Szelenkov@nginx.com        )
8751130Szelenkov@nginx.com        self.ws.frame_write(
8761150Szelenkov@nginx.com            sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1
8771130Szelenkov@nginx.com        )
8781130Szelenkov@nginx.com        self.check_close(sock, 1002)
8791130Szelenkov@nginx.com
8801130Szelenkov@nginx.com        # 5_15
8811130Szelenkov@nginx.com
8821130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
8831130Szelenkov@nginx.com
8841130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
8851130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
8861130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False)
8871130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment4', fin=True)
8881819Smax.romanov@nginx.com
8891819Smax.romanov@nginx.com        frame = self.ws.frame_read(sock)
8901819Smax.romanov@nginx.com
8911819Smax.romanov@nginx.com        if frame['opcode'] == self.ws.OP_TEXT:
892*1848Szelenkov@nginx.com            self.check_frame(
893*1848Szelenkov@nginx.com                frame, True, self.ws.OP_TEXT, 'fragment1fragment2'
894*1848Szelenkov@nginx.com            )
8951819Smax.romanov@nginx.com            frame = None
8961819Smax.romanov@nginx.com
8971819Smax.romanov@nginx.com        self.check_close(sock, 1002, frame=frame)
8981130Szelenkov@nginx.com
8991130Szelenkov@nginx.com        # 5_16
9001130Szelenkov@nginx.com
9011130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
9021130Szelenkov@nginx.com
9031130Szelenkov@nginx.com        for i in range(0, 2):
9041130Szelenkov@nginx.com            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=False)
9051130Szelenkov@nginx.com            self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False)
9061130Szelenkov@nginx.com            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True)
9071130Szelenkov@nginx.com        self.check_close(sock, 1002)
9081130Szelenkov@nginx.com
9091130Szelenkov@nginx.com        # 5_17
9101130Szelenkov@nginx.com
9111130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
9121130Szelenkov@nginx.com
9131130Szelenkov@nginx.com        for i in range(0, 2):
9141130Szelenkov@nginx.com            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=True)
9151130Szelenkov@nginx.com            self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False)
9161130Szelenkov@nginx.com            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True)
9171130Szelenkov@nginx.com        self.check_close(sock, 1002)
9181130Szelenkov@nginx.com
9191130Szelenkov@nginx.com        # 5_18
9201130Szelenkov@nginx.com
9211130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
9221130Szelenkov@nginx.com
9231130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
9241130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2')
9251130Szelenkov@nginx.com        self.check_close(sock, 1002)
9261130Szelenkov@nginx.com
9271130Szelenkov@nginx.com        # 5_19
9281130Szelenkov@nginx.com
9291130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
9301130Szelenkov@nginx.com
9311130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
9321130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False)
9331130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!')
9341130Szelenkov@nginx.com
9351130Szelenkov@nginx.com        time.sleep(1)
9361130Szelenkov@nginx.com
9371130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False)
9381130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False)
9391130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!')
9401130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5')
9411130Szelenkov@nginx.com
9421130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
9431130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!')
9441130Szelenkov@nginx.com
9451130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
9461130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!')
9471130Szelenkov@nginx.com
9481130Szelenkov@nginx.com        self.check_frame(
9491130Szelenkov@nginx.com            self.ws.frame_read(sock),
9501130Szelenkov@nginx.com            True,
9511130Szelenkov@nginx.com            self.ws.OP_TEXT,
9521130Szelenkov@nginx.com            'fragment1fragment2fragment3fragment4fragment5',
9531130Szelenkov@nginx.com        )
9541130Szelenkov@nginx.com
9551130Szelenkov@nginx.com        # 5_20
9561130Szelenkov@nginx.com
9571130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
9581130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False)
9591130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!')
9601130Szelenkov@nginx.com
9611130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
9621130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!')
9631130Szelenkov@nginx.com
9641130Szelenkov@nginx.com        time.sleep(1)
9651130Szelenkov@nginx.com
9661130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False)
9671130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False)
9681130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!')
9691130Szelenkov@nginx.com
9701130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
9711130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!')
9721130Szelenkov@nginx.com
9731596Szelenkov@nginx.com        assert self.recvall(sock, read_timeout=0.1) == b'', '5_20'
9741130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5')
9751130Szelenkov@nginx.com
9761130Szelenkov@nginx.com        self.check_frame(
9771130Szelenkov@nginx.com            self.ws.frame_read(sock),
9781130Szelenkov@nginx.com            True,
9791130Szelenkov@nginx.com            self.ws.OP_TEXT,
9801130Szelenkov@nginx.com            'fragment1fragment2fragment3fragment4fragment5',
9811130Szelenkov@nginx.com        )
9821130Szelenkov@nginx.com
9831130Szelenkov@nginx.com        self.close_connection(sock)
9841130Szelenkov@nginx.com
9851130Szelenkov@nginx.com    def test_node_websockets_6_1_1__6_4_4(self):
9861130Szelenkov@nginx.com        self.load('websockets/mirror')
9871130Szelenkov@nginx.com
9881130Szelenkov@nginx.com        # 6_1_1
9891130Szelenkov@nginx.com
9901130Szelenkov@nginx.com        _, sock, _ = self.ws.upgrade()
9911130Szelenkov@nginx.com
9921130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, '')
9931130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
9941130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, '')
9951130Szelenkov@nginx.com
9961130Szelenkov@nginx.com        # 6_1_2
9971130Szelenkov@nginx.com
9981130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False)
9991130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, '', fin=False)
10001130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, '')
10011130Szelenkov@nginx.com
10021130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
10031130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, '')
10041130Szelenkov@nginx.com
10051130Szelenkov@nginx.com        # 6_1_3
10061130Szelenkov@nginx.com
10071130Szelenkov@nginx.com        payload = 'middle frame payload'
10081130Szelenkov@nginx.com
10091130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False)
10101130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, payload, fin=False)
10111130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, '')
10121130Szelenkov@nginx.com
10131130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
10141130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
10151130Szelenkov@nginx.com
10161130Szelenkov@nginx.com        # 6_2_1
10171130Szelenkov@nginx.com
10181130Szelenkov@nginx.com        payload = 'Hello-µ@ßöäüàá-UTF-8!!'
10191130Szelenkov@nginx.com
10201130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
10211130Szelenkov@nginx.com
10221130Szelenkov@nginx.com        frame = self.ws.frame_read(sock)
10231130Szelenkov@nginx.com        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
10241130Szelenkov@nginx.com
10251130Szelenkov@nginx.com        # 6_2_2
10261130Szelenkov@nginx.com
10271130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_TEXT, payload[:12], fin=False)
10281130Szelenkov@nginx.com        self.ws.frame_write(sock, self.ws.OP_CONT, payload[12:])
10291130