xref: /unit/test/test_proxy.py (revision 1848)
11274Szelenkov@nginx.comimport re
21477Szelenkov@nginx.comimport socket
31274Szelenkov@nginx.comimport time
41477Szelenkov@nginx.com
51635Szelenkov@nginx.comimport pytest
6*1848Szelenkov@nginx.com
71654Szelenkov@nginx.comfrom conftest import run_process
81274Szelenkov@nginx.comfrom unit.applications.lang.python import TestApplicationPython
91730Szelenkov@nginx.comfrom unit.option import option
101735Szelenkov@nginx.comfrom unit.utils import waitforsocket
111274Szelenkov@nginx.com
121274Szelenkov@nginx.com
131274Szelenkov@nginx.comclass TestProxy(TestApplicationPython):
141467Szelenkov@nginx.com    prerequisites = {'modules': {'python': 'any'}}
151274Szelenkov@nginx.com
161274Szelenkov@nginx.com    SERVER_PORT = 7999
171274Szelenkov@nginx.com
181353Smax.romanov@nginx.com    @staticmethod
191353Smax.romanov@nginx.com    def run_server(server_port):
201274Szelenkov@nginx.com        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
211274Szelenkov@nginx.com        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
221274Szelenkov@nginx.com
231353Smax.romanov@nginx.com        server_address = ('', server_port)
241274Szelenkov@nginx.com        sock.bind(server_address)
251274Szelenkov@nginx.com        sock.listen(5)
261274Szelenkov@nginx.com
271274Szelenkov@nginx.com        def recvall(sock):
281274Szelenkov@nginx.com            buff_size = 4096
291274Szelenkov@nginx.com            data = b''
301274Szelenkov@nginx.com            while True:
311274Szelenkov@nginx.com                part = sock.recv(buff_size)
321274Szelenkov@nginx.com                data += part
331274Szelenkov@nginx.com                if len(part) < buff_size:
341274Szelenkov@nginx.com                    break
351274Szelenkov@nginx.com            return data
361274Szelenkov@nginx.com
371274Szelenkov@nginx.com        req = b"""HTTP/1.1 200 OK
381274Szelenkov@nginx.comContent-Length: 10
391274Szelenkov@nginx.com
401274Szelenkov@nginx.com"""
411274Szelenkov@nginx.com
421274Szelenkov@nginx.com        while True:
431274Szelenkov@nginx.com            connection, client_address = sock.accept()
441274Szelenkov@nginx.com
451274Szelenkov@nginx.com            data = recvall(connection).decode()
461274Szelenkov@nginx.com
471274Szelenkov@nginx.com            to_send = req
481274Szelenkov@nginx.com
491596Szelenkov@nginx.com            m = re.search(r'X-Len: (\d+)', data)
501274Szelenkov@nginx.com            if m:
511274Szelenkov@nginx.com                to_send += b'X' * int(m.group(1))
521274Szelenkov@nginx.com
531274Szelenkov@nginx.com            connection.sendall(to_send)
541274Szelenkov@nginx.com
551274Szelenkov@nginx.com            connection.close()
561274Szelenkov@nginx.com
571274Szelenkov@nginx.com    def get_http10(self, *args, **kwargs):
581274Szelenkov@nginx.com        return self.get(*args, http_10=True, **kwargs)
591274Szelenkov@nginx.com
601274Szelenkov@nginx.com    def post_http10(self, *args, **kwargs):
611274Szelenkov@nginx.com        return self.post(*args, http_10=True, **kwargs)
621274Szelenkov@nginx.com
631596Szelenkov@nginx.com    def setup_method(self):
641654Szelenkov@nginx.com        run_process(self.run_server, self.SERVER_PORT)
651654Szelenkov@nginx.com        waitforsocket(self.SERVER_PORT)
661274Szelenkov@nginx.com
671596Szelenkov@nginx.com        assert 'success' in self.conf(
681596Szelenkov@nginx.com            {
691596Szelenkov@nginx.com                "listeners": {
701596Szelenkov@nginx.com                    "*:7080": {"pass": "routes"},
711596Szelenkov@nginx.com                    "*:7081": {"pass": "applications/mirror"},
721596Szelenkov@nginx.com                },
731596Szelenkov@nginx.com                "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
741596Szelenkov@nginx.com                "applications": {
751596Szelenkov@nginx.com                    "mirror": {
761596Szelenkov@nginx.com                        "type": "python",
771596Szelenkov@nginx.com                        "processes": {"spare": 0},
781596Szelenkov@nginx.com                        "path": option.test_dir + "/python/mirror",
791596Szelenkov@nginx.com                        "working_directory": option.test_dir
801596Szelenkov@nginx.com                        + "/python/mirror",
811596Szelenkov@nginx.com                        "module": "wsgi",
821274Szelenkov@nginx.com                    },
831596Szelenkov@nginx.com                    "custom_header": {
841596Szelenkov@nginx.com                        "type": "python",
851596Szelenkov@nginx.com                        "processes": {"spare": 0},
861596Szelenkov@nginx.com                        "path": option.test_dir + "/python/custom_header",
871596Szelenkov@nginx.com                        "working_directory": option.test_dir
881596Szelenkov@nginx.com                        + "/python/custom_header",
891596Szelenkov@nginx.com                        "module": "wsgi",
901274Szelenkov@nginx.com                    },
911596Szelenkov@nginx.com                    "delayed": {
921596Szelenkov@nginx.com                        "type": "python",
931596Szelenkov@nginx.com                        "processes": {"spare": 0},
941596Szelenkov@nginx.com                        "path": option.test_dir + "/python/delayed",
951596Szelenkov@nginx.com                        "working_directory": option.test_dir
961596Szelenkov@nginx.com                        + "/python/delayed",
971596Szelenkov@nginx.com                        "module": "wsgi",
981596Szelenkov@nginx.com                    },
991596Szelenkov@nginx.com                },
1001596Szelenkov@nginx.com            }
1011596Szelenkov@nginx.com        ), 'proxy initial configuration'
1021274Szelenkov@nginx.com
1031274Szelenkov@nginx.com    def test_proxy_http10(self):
1041274Szelenkov@nginx.com        for _ in range(10):
1051596Szelenkov@nginx.com            assert self.get_http10()['status'] == 200, 'status'
1061274Szelenkov@nginx.com
1071274Szelenkov@nginx.com    def test_proxy_chain(self):
1081596Szelenkov@nginx.com        assert 'success' in self.conf(
1091596Szelenkov@nginx.com            {
1101596Szelenkov@nginx.com                "listeners": {
1111596Szelenkov@nginx.com                    "*:7080": {"pass": "routes/first"},
1121596Szelenkov@nginx.com                    "*:7081": {"pass": "routes/second"},
1131596Szelenkov@nginx.com                    "*:7082": {"pass": "routes/third"},
1141596Szelenkov@nginx.com                    "*:7083": {"pass": "routes/fourth"},
1151596Szelenkov@nginx.com                    "*:7084": {"pass": "routes/fifth"},
1161596Szelenkov@nginx.com                    "*:7085": {"pass": "applications/mirror"},
1171596Szelenkov@nginx.com                },
1181596Szelenkov@nginx.com                "routes": {
1191596Szelenkov@nginx.com                    "first": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
1201596Szelenkov@nginx.com                    "second": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
1211596Szelenkov@nginx.com                    "third": [{"action": {"proxy": "http://127.0.0.1:7083"}}],
1221596Szelenkov@nginx.com                    "fourth": [{"action": {"proxy": "http://127.0.0.1:7084"}}],
1231596Szelenkov@nginx.com                    "fifth": [{"action": {"proxy": "http://127.0.0.1:7085"}}],
1241596Szelenkov@nginx.com                },
1251596Szelenkov@nginx.com                "applications": {
1261596Szelenkov@nginx.com                    "mirror": {
1271596Szelenkov@nginx.com                        "type": "python",
1281596Szelenkov@nginx.com                        "processes": {"spare": 0},
1291596Szelenkov@nginx.com                        "path": option.test_dir + "/python/mirror",
1301596Szelenkov@nginx.com                        "working_directory": option.test_dir
1311596Szelenkov@nginx.com                        + "/python/mirror",
1321596Szelenkov@nginx.com                        "module": "wsgi",
1331596Szelenkov@nginx.com                    }
1341596Szelenkov@nginx.com                },
1351596Szelenkov@nginx.com            }
1361596Szelenkov@nginx.com        ), 'proxy chain configuration'
1371274Szelenkov@nginx.com
1381596Szelenkov@nginx.com        assert self.get_http10()['status'] == 200, 'status'
1391274Szelenkov@nginx.com
1401274Szelenkov@nginx.com    def test_proxy_body(self):
1411274Szelenkov@nginx.com        payload = '0123456789'
1421274Szelenkov@nginx.com        for _ in range(10):
1431274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
1441274Szelenkov@nginx.com
1451596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
1461596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1471274Szelenkov@nginx.com
1481274Szelenkov@nginx.com        payload = 'X' * 4096
1491274Szelenkov@nginx.com        for _ in range(10):
1501274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
1511274Szelenkov@nginx.com
1521596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
1531596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1541274Szelenkov@nginx.com
1551274Szelenkov@nginx.com        payload = 'X' * 4097
1561274Szelenkov@nginx.com        for _ in range(10):
1571274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
1581274Szelenkov@nginx.com
1591596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
1601596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1611274Szelenkov@nginx.com
1621274Szelenkov@nginx.com        payload = 'X' * 4096 * 256
1631274Szelenkov@nginx.com        for _ in range(10):
1641274Szelenkov@nginx.com            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
1651274Szelenkov@nginx.com
1661596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
1671596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1681274Szelenkov@nginx.com
1691274Szelenkov@nginx.com        payload = 'X' * 4096 * 257
1701274Szelenkov@nginx.com        for _ in range(10):
1711274Szelenkov@nginx.com            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
1721274Szelenkov@nginx.com
1731596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
1741596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1751274Szelenkov@nginx.com
1761775Szelenkov@nginx.com        assert 'success' in self.conf(
1771775Szelenkov@nginx.com            {'http': {'max_body_size': 32 * 1024 * 1024}}, 'settings'
1781775Szelenkov@nginx.com        )
1791366Szelenkov@nginx.com
1801366Szelenkov@nginx.com        payload = '0123456789abcdef' * 32 * 64 * 1024
1811366Szelenkov@nginx.com        resp = self.post_http10(body=payload, read_buffer_size=1024 * 1024)
1821596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
1831596Szelenkov@nginx.com        assert resp['body'] == payload, 'body'
1841366Szelenkov@nginx.com
1851274Szelenkov@nginx.com    def test_proxy_parallel(self):
1861274Szelenkov@nginx.com        payload = 'X' * 4096 * 257
1871274Szelenkov@nginx.com        buff_size = 4096 * 258
1881274Szelenkov@nginx.com
1891274Szelenkov@nginx.com        socks = []
1901274Szelenkov@nginx.com        for i in range(10):
1911274Szelenkov@nginx.com            _, sock = self.post_http10(
1921274Szelenkov@nginx.com                body=payload + str(i),
1931274Szelenkov@nginx.com                start=True,
1941274Szelenkov@nginx.com                no_recv=True,
1951274Szelenkov@nginx.com                read_buffer_size=buff_size,
1961274Szelenkov@nginx.com            )
1971274Szelenkov@nginx.com            socks.append(sock)
1981274Szelenkov@nginx.com
1991274Szelenkov@nginx.com        for i in range(10):
2001274Szelenkov@nginx.com            resp = self.recvall(socks[i], buff_size=buff_size).decode()
2011274Szelenkov@nginx.com            socks[i].close()
2021274Szelenkov@nginx.com
2031274Szelenkov@nginx.com            resp = self._resp_to_dict(resp)
2041274Szelenkov@nginx.com
2051596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
2061596Szelenkov@nginx.com            assert resp['body'] == payload + str(i), 'body'
2071274Szelenkov@nginx.com
2081274Szelenkov@nginx.com    def test_proxy_header(self):
2091596Szelenkov@nginx.com        assert 'success' in self.conf(
2101596Szelenkov@nginx.com            {"pass": "applications/custom_header"}, 'listeners/*:7081'
2111596Szelenkov@nginx.com        ), 'custom_header configure'
2121274Szelenkov@nginx.com
2131274Szelenkov@nginx.com        header_value = 'blah'
2141596Szelenkov@nginx.com        assert (
2151274Szelenkov@nginx.com            self.get_http10(
2161274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
2171596Szelenkov@nginx.com            )['headers']['Custom-Header']
2181596Szelenkov@nginx.com            == header_value
2191596Szelenkov@nginx.com        ), 'custom header'
2201274Szelenkov@nginx.com
2211635Szelenkov@nginx.com        header_value = r'(),/:;<=>?@[\]{}\t !#$%&\'*+-.^_`|~'
2221596Szelenkov@nginx.com        assert (
2231274Szelenkov@nginx.com            self.get_http10(
2241274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
2251596Szelenkov@nginx.com            )['headers']['Custom-Header']
2261596Szelenkov@nginx.com            == header_value
2271596Szelenkov@nginx.com        ), 'custom header 2'
2281274Szelenkov@nginx.com
2291274Szelenkov@nginx.com        header_value = 'X' * 4096
2301596Szelenkov@nginx.com        assert (
2311274Szelenkov@nginx.com            self.get_http10(
2321274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
2331596Szelenkov@nginx.com            )['headers']['Custom-Header']
2341596Szelenkov@nginx.com            == header_value
2351596Szelenkov@nginx.com        ), 'custom header 3'
2361274Szelenkov@nginx.com
2371274Szelenkov@nginx.com        header_value = 'X' * 8191
2381596Szelenkov@nginx.com        assert (
2391274Szelenkov@nginx.com            self.get_http10(
2401274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
2411596Szelenkov@nginx.com            )['headers']['Custom-Header']
2421596Szelenkov@nginx.com            == header_value
2431596Szelenkov@nginx.com        ), 'custom header 4'
2441274Szelenkov@nginx.com
2451274Szelenkov@nginx.com        header_value = 'X' * 8192
2461596Szelenkov@nginx.com        assert (
2471274Szelenkov@nginx.com            self.get_http10(
2481274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
2491596Szelenkov@nginx.com            )['status']
2501596Szelenkov@nginx.com            == 431
2511596Szelenkov@nginx.com        ), 'custom header 5'
2521274Szelenkov@nginx.com
2531274Szelenkov@nginx.com    def test_proxy_fragmented(self):
2541274Szelenkov@nginx.com        _, sock = self.http(
2551274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
2561274Szelenkov@nginx.com        )
2571274Szelenkov@nginx.com
2581274Szelenkov@nginx.com        time.sleep(1)
2591274Szelenkov@nginx.com
2601274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhos".encode())
2611274Szelenkov@nginx.com
2621274Szelenkov@nginx.com        time.sleep(1)
2631274Szelenkov@nginx.com
2641274Szelenkov@nginx.com        sock.sendall("t\r\n\r\n".encode())
2651274Szelenkov@nginx.com
2661596Szelenkov@nginx.com        assert re.search(
2671596Szelenkov@nginx.com            '200 OK', self.recvall(sock).decode()
2681596Szelenkov@nginx.com        ), 'fragmented send'
2691274Szelenkov@nginx.com        sock.close()
2701274Szelenkov@nginx.com
2711274Szelenkov@nginx.com    def test_proxy_fragmented_close(self):
2721274Szelenkov@nginx.com        _, sock = self.http(
2731274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
2741274Szelenkov@nginx.com        )
2751274Szelenkov@nginx.com
2761274Szelenkov@nginx.com        time.sleep(1)
2771274Szelenkov@nginx.com
2781274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHo".encode())
2791274Szelenkov@nginx.com
2801274Szelenkov@nginx.com        sock.close()
2811274Szelenkov@nginx.com
2821274Szelenkov@nginx.com    def test_proxy_fragmented_body(self):
2831274Szelenkov@nginx.com        _, sock = self.http(
2841274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
2851274Szelenkov@nginx.com        )
2861274Szelenkov@nginx.com
2871274Szelenkov@nginx.com        time.sleep(1)
2881274Szelenkov@nginx.com
2891274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
2901274Szelenkov@nginx.com        sock.sendall("Content-Length: 30000\r\n".encode())
2911274Szelenkov@nginx.com
2921274Szelenkov@nginx.com        time.sleep(1)
2931274Szelenkov@nginx.com
2941274Szelenkov@nginx.com        sock.sendall("\r\n".encode())
2951274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
2961274Szelenkov@nginx.com
2971274Szelenkov@nginx.com        time.sleep(1)
2981274Szelenkov@nginx.com
2991274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
3001274Szelenkov@nginx.com
3011274Szelenkov@nginx.com        time.sleep(1)
3021274Szelenkov@nginx.com
3031274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
3041274Szelenkov@nginx.com
3051274Szelenkov@nginx.com        resp = self._resp_to_dict(self.recvall(sock).decode())
3061274Szelenkov@nginx.com        sock.close()
3071274Szelenkov@nginx.com
3081596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
3091596Szelenkov@nginx.com        assert resp['body'] == "X" * 30000, 'body'
3101274Szelenkov@nginx.com
3111274Szelenkov@nginx.com    def test_proxy_fragmented_body_close(self):
3121274Szelenkov@nginx.com        _, sock = self.http(
3131274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
3141274Szelenkov@nginx.com        )
3151274Szelenkov@nginx.com
3161274Szelenkov@nginx.com        time.sleep(1)
3171274Szelenkov@nginx.com
3181274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
3191274Szelenkov@nginx.com        sock.sendall("Content-Length: 30000\r\n".encode())
3201274Szelenkov@nginx.com
3211274Szelenkov@nginx.com        time.sleep(1)
3221274Szelenkov@nginx.com
3231274Szelenkov@nginx.com        sock.sendall("\r\n".encode())
3241274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
3251274Szelenkov@nginx.com
3261274Szelenkov@nginx.com        sock.close()
3271274Szelenkov@nginx.com
3281274Szelenkov@nginx.com    def test_proxy_nowhere(self):
3291596Szelenkov@nginx.com        assert 'success' in self.conf(
3301596Szelenkov@nginx.com            [{"action": {"proxy": "http://127.0.0.1:7082"}}], 'routes'
3311596Szelenkov@nginx.com        ), 'proxy path changed'
3321274Szelenkov@nginx.com
3331596Szelenkov@nginx.com        assert self.get_http10()['status'] == 502, 'status'
3341274Szelenkov@nginx.com
3351274Szelenkov@nginx.com    def test_proxy_ipv6(self):
3361596Szelenkov@nginx.com        assert 'success' in self.conf(
3371596Szelenkov@nginx.com            {
3381596Szelenkov@nginx.com                "*:7080": {"pass": "routes"},
3391596Szelenkov@nginx.com                "[::1]:7081": {'application': 'mirror'},
3401596Szelenkov@nginx.com            },
3411596Szelenkov@nginx.com            'listeners',
3421596Szelenkov@nginx.com        ), 'add ipv6 listener configure'
3431274Szelenkov@nginx.com
3441596Szelenkov@nginx.com        assert 'success' in self.conf(
3451596Szelenkov@nginx.com            [{"action": {"proxy": "http://[::1]:7081"}}], 'routes'
3461596Szelenkov@nginx.com        ), 'proxy ipv6 configure'
3471274Szelenkov@nginx.com
3481596Szelenkov@nginx.com        assert self.get_http10()['status'] == 200, 'status'
3491274Szelenkov@nginx.com
3501654Szelenkov@nginx.com    def test_proxy_unix(self, temp_dir):
3511654Szelenkov@nginx.com        addr = temp_dir + '/sock'
3521274Szelenkov@nginx.com
3531596Szelenkov@nginx.com        assert 'success' in self.conf(
3541596Szelenkov@nginx.com            {
3551596Szelenkov@nginx.com                "*:7080": {"pass": "routes"},
3561596Szelenkov@nginx.com                "unix:" + addr: {'application': 'mirror'},
3571596Szelenkov@nginx.com            },
3581596Szelenkov@nginx.com            'listeners',
3591596Szelenkov@nginx.com        ), 'add unix listener configure'
3601274Szelenkov@nginx.com
3611596Szelenkov@nginx.com        assert 'success' in self.conf(
3621596Szelenkov@nginx.com            [{"action": {"proxy": 'http://unix:' + addr}}], 'routes'
3631596Szelenkov@nginx.com        ), 'proxy unix configure'
3641274Szelenkov@nginx.com
3651596Szelenkov@nginx.com        assert self.get_http10()['status'] == 200, 'status'
3661274Szelenkov@nginx.com
3671274Szelenkov@nginx.com    def test_proxy_delayed(self):
3681596Szelenkov@nginx.com        assert 'success' in self.conf(
3691596Szelenkov@nginx.com            {"pass": "applications/delayed"}, 'listeners/*:7081'
3701596Szelenkov@nginx.com        ), 'delayed configure'
3711274Szelenkov@nginx.com
3721274Szelenkov@nginx.com        body = '0123456789' * 1000
3731274Szelenkov@nginx.com        resp = self.post_http10(
3741274Szelenkov@nginx.com            headers={
3751274Szelenkov@nginx.com                'Host': 'localhost',
3761274Szelenkov@nginx.com                'Content-Type': 'text/html',
3771274Szelenkov@nginx.com                'Content-Length': str(len(body)),
3781274Szelenkov@nginx.com                'X-Parts': '2',
3791274Szelenkov@nginx.com                'X-Delay': '1',
3801274Szelenkov@nginx.com            },
3811274Szelenkov@nginx.com            body=body,
3821274Szelenkov@nginx.com        )
3831274Szelenkov@nginx.com
3841596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
3851596Szelenkov@nginx.com        assert resp['body'] == body, 'body'
3861274Szelenkov@nginx.com
3871274Szelenkov@nginx.com        resp = self.post_http10(
3881274Szelenkov@nginx.com            headers={
3891274Szelenkov@nginx.com                'Host': 'localhost',
3901274Szelenkov@nginx.com                'Content-Type': 'text/html',
3911274Szelenkov@nginx.com                'Content-Length': str(len(body)),
3921274Szelenkov@nginx.com                'X-Parts': '2',
3931274Szelenkov@nginx.com                'X-Delay': '1',
3941274Szelenkov@nginx.com            },
3951274Szelenkov@nginx.com            body=body,
3961274Szelenkov@nginx.com        )
3971274Szelenkov@nginx.com
3981596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
3991596Szelenkov@nginx.com        assert resp['body'] == body, 'body'
4001274Szelenkov@nginx.com
4011274Szelenkov@nginx.com    def test_proxy_delayed_close(self):
4021596Szelenkov@nginx.com        assert 'success' in self.conf(
4031596Szelenkov@nginx.com            {"pass": "applications/delayed"}, 'listeners/*:7081'
4041596Szelenkov@nginx.com        ), 'delayed configure'
4051274Szelenkov@nginx.com
4061274Szelenkov@nginx.com        _, sock = self.post_http10(
4071274Szelenkov@nginx.com            headers={
4081274Szelenkov@nginx.com                'Host': 'localhost',
4091274Szelenkov@nginx.com                'Content-Type': 'text/html',
4101274Szelenkov@nginx.com                'Content-Length': '10000',
4111274Szelenkov@nginx.com                'X-Parts': '3',
4121274Szelenkov@nginx.com                'X-Delay': '1',
4131274Szelenkov@nginx.com            },
4141274Szelenkov@nginx.com            body='0123456789' * 1000,
4151274Szelenkov@nginx.com            start=True,
4161274Szelenkov@nginx.com            no_recv=True,
4171274Szelenkov@nginx.com        )
4181274Szelenkov@nginx.com
4191596Szelenkov@nginx.com        assert re.search('200 OK', sock.recv(100).decode()), 'first'
4201274Szelenkov@nginx.com        sock.close()
4211274Szelenkov@nginx.com
4221274Szelenkov@nginx.com        _, sock = self.post_http10(
4231274Szelenkov@nginx.com            headers={
4241274Szelenkov@nginx.com                'Host': 'localhost',
4251274Szelenkov@nginx.com                'Content-Type': 'text/html',
4261274Szelenkov@nginx.com                'Content-Length': '10000',
4271274Szelenkov@nginx.com                'X-Parts': '3',
4281274Szelenkov@nginx.com                'X-Delay': '1',
4291274Szelenkov@nginx.com            },
4301274Szelenkov@nginx.com            body='0123456789' * 1000,
4311274Szelenkov@nginx.com            start=True,
4321274Szelenkov@nginx.com            no_recv=True,
4331274Szelenkov@nginx.com        )
4341274Szelenkov@nginx.com
4351596Szelenkov@nginx.com        assert re.search('200 OK', sock.recv(100).decode()), 'second'
4361274Szelenkov@nginx.com        sock.close()
4371274Szelenkov@nginx.com
4381596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
4391274Szelenkov@nginx.com    def test_proxy_content_length(self):
4401596Szelenkov@nginx.com        assert 'success' in self.conf(
4411596Szelenkov@nginx.com            [
4421596Szelenkov@nginx.com                {
4431596Szelenkov@nginx.com                    "action": {
4441596Szelenkov@nginx.com                        "proxy": "http://127.0.0.1:" + str(self.SERVER_PORT)
4451274Szelenkov@nginx.com                    }
4461596Szelenkov@nginx.com                }
4471596Szelenkov@nginx.com            ],
4481596Szelenkov@nginx.com            'routes',
4491596Szelenkov@nginx.com        ), 'proxy backend configure'
4501274Szelenkov@nginx.com
4511274Szelenkov@nginx.com        resp = self.get_http10()
4521596Szelenkov@nginx.com        assert len(resp['body']) == 0, 'body lt Content-Length 0'
4531274Szelenkov@nginx.com
4541274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '5'})
4551596Szelenkov@nginx.com        assert len(resp['body']) == 5, 'body lt Content-Length 5'
4561274Szelenkov@nginx.com
4571274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '9'})
4581596Szelenkov@nginx.com        assert len(resp['body']) == 9, 'body lt Content-Length 9'
4591274Szelenkov@nginx.com
4601274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '11'})
4611596Szelenkov@nginx.com        assert len(resp['body']) == 10, 'body gt Content-Length 11'
4621274Szelenkov@nginx.com
4631274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '15'})
4641596Szelenkov@nginx.com        assert len(resp['body']) == 10, 'body gt Content-Length 15'
4651274Szelenkov@nginx.com
4661274Szelenkov@nginx.com    def test_proxy_invalid(self):
4671476Szelenkov@nginx.com        def check_proxy(proxy):
468*1848Szelenkov@nginx.com            assert 'error' in self.conf(
469*1848Szelenkov@nginx.com                [{"action": {"proxy": proxy}}], 'routes'
470*1848Szelenkov@nginx.com            ), 'proxy invalid'
4711476Szelenkov@nginx.com
4721476Szelenkov@nginx.com        check_proxy('blah')
4731476Szelenkov@nginx.com        check_proxy('/blah')
4741476Szelenkov@nginx.com        check_proxy('unix:/blah')
4751476Szelenkov@nginx.com        check_proxy('http://blah')
4761476Szelenkov@nginx.com        check_proxy('http://127.0.0.1')
4771476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:')
4781476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:blah')
4791476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:-1')
4801476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:7080b')
4811476Szelenkov@nginx.com        check_proxy('http://[]')
4821476Szelenkov@nginx.com        check_proxy('http://[]:7080')
4831476Szelenkov@nginx.com        check_proxy('http://[:]:7080')
4841476Szelenkov@nginx.com        check_proxy('http://[::7080')
4851274Szelenkov@nginx.com
4861803Szelenkov@nginx.com    @pytest.mark.skip('not yet')
4871736Szelenkov@nginx.com    def test_proxy_loop(self, skip_alert):
4881596Szelenkov@nginx.com        skip_alert(
4891596Szelenkov@nginx.com            r'socket.*failed',
4901596Szelenkov@nginx.com            r'accept.*failed',
4911596Szelenkov@nginx.com            r'new connections are not accepted',
4921465Szelenkov@nginx.com        )
4931775Szelenkov@nginx.com        assert 'success' in self.conf(
4941274Szelenkov@nginx.com            {
4951274Szelenkov@nginx.com                "listeners": {
4961274Szelenkov@nginx.com                    "*:7080": {"pass": "routes"},
4971274Szelenkov@nginx.com                    "*:7081": {"pass": "applications/mirror"},
4981274Szelenkov@nginx.com                    "*:7082": {"pass": "routes"},
4991274Szelenkov@nginx.com                },
5001274Szelenkov@nginx.com                "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
5011274Szelenkov@nginx.com                "applications": {
5021274Szelenkov@nginx.com                    "mirror": {
5031274Szelenkov@nginx.com                        "type": "python",
5041274Szelenkov@nginx.com                        "processes": {"spare": 0},
5051596Szelenkov@nginx.com                        "path": option.test_dir + "/python/mirror",
506*1848Szelenkov@nginx.com                        "working_directory": option.test_dir
507*1848Szelenkov@nginx.com                        + "/python/mirror",
5081274Szelenkov@nginx.com                        "module": "wsgi",
5091274Szelenkov@nginx.com                    },
5101274Szelenkov@nginx.com                },
5111274Szelenkov@nginx.com            }
5121274Szelenkov@nginx.com        )
5131274Szelenkov@nginx.com
5141274Szelenkov@nginx.com        self.get_http10(no_recv=True)
5151465Szelenkov@nginx.com        self.get_http10(read_timeout=1)
516