xref: /unit/test/test_proxy.py (revision 1596)
1*1596Szelenkov@nginx.comimport pytest
21274Szelenkov@nginx.comimport re
31477Szelenkov@nginx.comimport socket
41274Szelenkov@nginx.comimport time
51477Szelenkov@nginx.com
61274Szelenkov@nginx.comfrom unit.applications.lang.python import TestApplicationPython
7*1596Szelenkov@nginx.comfrom conftest import option, skip_alert
81274Szelenkov@nginx.com
91274Szelenkov@nginx.com
101274Szelenkov@nginx.comclass TestProxy(TestApplicationPython):
111467Szelenkov@nginx.com    prerequisites = {'modules': {'python': 'any'}}
121274Szelenkov@nginx.com
131274Szelenkov@nginx.com    SERVER_PORT = 7999
141274Szelenkov@nginx.com
151353Smax.romanov@nginx.com    @staticmethod
161353Smax.romanov@nginx.com    def run_server(server_port):
171274Szelenkov@nginx.com        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
181274Szelenkov@nginx.com        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
191274Szelenkov@nginx.com
201353Smax.romanov@nginx.com        server_address = ('', server_port)
211274Szelenkov@nginx.com        sock.bind(server_address)
221274Szelenkov@nginx.com        sock.listen(5)
231274Szelenkov@nginx.com
241274Szelenkov@nginx.com        def recvall(sock):
251274Szelenkov@nginx.com            buff_size = 4096
261274Szelenkov@nginx.com            data = b''
271274Szelenkov@nginx.com            while True:
281274Szelenkov@nginx.com                part = sock.recv(buff_size)
291274Szelenkov@nginx.com                data += part
301274Szelenkov@nginx.com                if len(part) < buff_size:
311274Szelenkov@nginx.com                    break
321274Szelenkov@nginx.com            return data
331274Szelenkov@nginx.com
341274Szelenkov@nginx.com        req = b"""HTTP/1.1 200 OK
351274Szelenkov@nginx.comContent-Length: 10
361274Szelenkov@nginx.com
371274Szelenkov@nginx.com"""
381274Szelenkov@nginx.com
391274Szelenkov@nginx.com        while True:
401274Szelenkov@nginx.com            connection, client_address = sock.accept()
411274Szelenkov@nginx.com
421274Szelenkov@nginx.com            data = recvall(connection).decode()
431274Szelenkov@nginx.com
441274Szelenkov@nginx.com            to_send = req
451274Szelenkov@nginx.com
46*1596Szelenkov@nginx.com            m = re.search(r'X-Len: (\d+)', data)
471274Szelenkov@nginx.com            if m:
481274Szelenkov@nginx.com                to_send += b'X' * int(m.group(1))
491274Szelenkov@nginx.com
501274Szelenkov@nginx.com            connection.sendall(to_send)
511274Szelenkov@nginx.com
521274Szelenkov@nginx.com            connection.close()
531274Szelenkov@nginx.com
541274Szelenkov@nginx.com    def get_http10(self, *args, **kwargs):
551274Szelenkov@nginx.com        return self.get(*args, http_10=True, **kwargs)
561274Szelenkov@nginx.com
571274Szelenkov@nginx.com    def post_http10(self, *args, **kwargs):
581274Szelenkov@nginx.com        return self.post(*args, http_10=True, **kwargs)
591274Szelenkov@nginx.com
60*1596Szelenkov@nginx.com    def setup_method(self):
61*1596Szelenkov@nginx.com        super().setup_method()
621274Szelenkov@nginx.com
631353Smax.romanov@nginx.com        self.run_process(self.run_server, self.SERVER_PORT)
641274Szelenkov@nginx.com        self.waitforsocket(self.SERVER_PORT)
651274Szelenkov@nginx.com
66*1596Szelenkov@nginx.com        assert 'success' in self.conf(
67*1596Szelenkov@nginx.com            {
68*1596Szelenkov@nginx.com                "listeners": {
69*1596Szelenkov@nginx.com                    "*:7080": {"pass": "routes"},
70*1596Szelenkov@nginx.com                    "*:7081": {"pass": "applications/mirror"},
71*1596Szelenkov@nginx.com                },
72*1596Szelenkov@nginx.com                "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
73*1596Szelenkov@nginx.com                "applications": {
74*1596Szelenkov@nginx.com                    "mirror": {
75*1596Szelenkov@nginx.com                        "type": "python",
76*1596Szelenkov@nginx.com                        "processes": {"spare": 0},
77*1596Szelenkov@nginx.com                        "path": option.test_dir + "/python/mirror",
78*1596Szelenkov@nginx.com                        "working_directory": option.test_dir
79*1596Szelenkov@nginx.com                        + "/python/mirror",
80*1596Szelenkov@nginx.com                        "module": "wsgi",
811274Szelenkov@nginx.com                    },
82*1596Szelenkov@nginx.com                    "custom_header": {
83*1596Szelenkov@nginx.com                        "type": "python",
84*1596Szelenkov@nginx.com                        "processes": {"spare": 0},
85*1596Szelenkov@nginx.com                        "path": option.test_dir + "/python/custom_header",
86*1596Szelenkov@nginx.com                        "working_directory": option.test_dir
87*1596Szelenkov@nginx.com                        + "/python/custom_header",
88*1596Szelenkov@nginx.com                        "module": "wsgi",
891274Szelenkov@nginx.com                    },
90*1596Szelenkov@nginx.com                    "delayed": {
91*1596Szelenkov@nginx.com                        "type": "python",
92*1596Szelenkov@nginx.com                        "processes": {"spare": 0},
93*1596Szelenkov@nginx.com                        "path": option.test_dir + "/python/delayed",
94*1596Szelenkov@nginx.com                        "working_directory": option.test_dir
95*1596Szelenkov@nginx.com                        + "/python/delayed",
96*1596Szelenkov@nginx.com                        "module": "wsgi",
97*1596Szelenkov@nginx.com                    },
98*1596Szelenkov@nginx.com                },
99*1596Szelenkov@nginx.com            }
100*1596Szelenkov@nginx.com        ), 'proxy initial configuration'
1011274Szelenkov@nginx.com
1021274Szelenkov@nginx.com    def test_proxy_http10(self):
1031274Szelenkov@nginx.com        for _ in range(10):
104*1596Szelenkov@nginx.com            assert self.get_http10()['status'] == 200, 'status'
1051274Szelenkov@nginx.com
1061274Szelenkov@nginx.com    def test_proxy_chain(self):
107*1596Szelenkov@nginx.com        assert 'success' in self.conf(
108*1596Szelenkov@nginx.com            {
109*1596Szelenkov@nginx.com                "listeners": {
110*1596Szelenkov@nginx.com                    "*:7080": {"pass": "routes/first"},
111*1596Szelenkov@nginx.com                    "*:7081": {"pass": "routes/second"},
112*1596Szelenkov@nginx.com                    "*:7082": {"pass": "routes/third"},
113*1596Szelenkov@nginx.com                    "*:7083": {"pass": "routes/fourth"},
114*1596Szelenkov@nginx.com                    "*:7084": {"pass": "routes/fifth"},
115*1596Szelenkov@nginx.com                    "*:7085": {"pass": "applications/mirror"},
116*1596Szelenkov@nginx.com                },
117*1596Szelenkov@nginx.com                "routes": {
118*1596Szelenkov@nginx.com                    "first": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
119*1596Szelenkov@nginx.com                    "second": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
120*1596Szelenkov@nginx.com                    "third": [{"action": {"proxy": "http://127.0.0.1:7083"}}],
121*1596Szelenkov@nginx.com                    "fourth": [{"action": {"proxy": "http://127.0.0.1:7084"}}],
122*1596Szelenkov@nginx.com                    "fifth": [{"action": {"proxy": "http://127.0.0.1:7085"}}],
123*1596Szelenkov@nginx.com                },
124*1596Szelenkov@nginx.com                "applications": {
125*1596Szelenkov@nginx.com                    "mirror": {
126*1596Szelenkov@nginx.com                        "type": "python",
127*1596Szelenkov@nginx.com                        "processes": {"spare": 0},
128*1596Szelenkov@nginx.com                        "path": option.test_dir + "/python/mirror",
129*1596Szelenkov@nginx.com                        "working_directory": option.test_dir
130*1596Szelenkov@nginx.com                        + "/python/mirror",
131*1596Szelenkov@nginx.com                        "module": "wsgi",
132*1596Szelenkov@nginx.com                    }
133*1596Szelenkov@nginx.com                },
134*1596Szelenkov@nginx.com            }
135*1596Szelenkov@nginx.com        ), 'proxy chain configuration'
1361274Szelenkov@nginx.com
137*1596Szelenkov@nginx.com        assert self.get_http10()['status'] == 200, 'status'
1381274Szelenkov@nginx.com
1391274Szelenkov@nginx.com    def test_proxy_body(self):
1401274Szelenkov@nginx.com        payload = '0123456789'
1411274Szelenkov@nginx.com        for _ in range(10):
1421274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
1431274Szelenkov@nginx.com
144*1596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
145*1596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1461274Szelenkov@nginx.com
1471274Szelenkov@nginx.com        payload = 'X' * 4096
1481274Szelenkov@nginx.com        for _ in range(10):
1491274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
1501274Szelenkov@nginx.com
151*1596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
152*1596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1531274Szelenkov@nginx.com
1541274Szelenkov@nginx.com        payload = 'X' * 4097
1551274Szelenkov@nginx.com        for _ in range(10):
1561274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
1571274Szelenkov@nginx.com
158*1596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
159*1596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1601274Szelenkov@nginx.com
1611274Szelenkov@nginx.com        payload = 'X' * 4096 * 256
1621274Szelenkov@nginx.com        for _ in range(10):
1631274Szelenkov@nginx.com            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
1641274Szelenkov@nginx.com
165*1596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
166*1596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1671274Szelenkov@nginx.com
1681274Szelenkov@nginx.com        payload = 'X' * 4096 * 257
1691274Szelenkov@nginx.com        for _ in range(10):
1701274Szelenkov@nginx.com            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
1711274Szelenkov@nginx.com
172*1596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
173*1596Szelenkov@nginx.com            assert resp['body'] == payload, 'body'
1741274Szelenkov@nginx.com
1751366Szelenkov@nginx.com        self.conf({'http': {'max_body_size': 32 * 1024 * 1024}}, 'settings')
1761366Szelenkov@nginx.com
1771366Szelenkov@nginx.com        payload = '0123456789abcdef' * 32 * 64 * 1024
1781366Szelenkov@nginx.com        resp = self.post_http10(body=payload, read_buffer_size=1024 * 1024)
179*1596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
180*1596Szelenkov@nginx.com        assert resp['body'] == payload, 'body'
1811366Szelenkov@nginx.com
1821274Szelenkov@nginx.com    def test_proxy_parallel(self):
1831274Szelenkov@nginx.com        payload = 'X' * 4096 * 257
1841274Szelenkov@nginx.com        buff_size = 4096 * 258
1851274Szelenkov@nginx.com
1861274Szelenkov@nginx.com        socks = []
1871274Szelenkov@nginx.com        for i in range(10):
1881274Szelenkov@nginx.com            _, sock = self.post_http10(
1891274Szelenkov@nginx.com                body=payload + str(i),
1901274Szelenkov@nginx.com                start=True,
1911274Szelenkov@nginx.com                no_recv=True,
1921274Szelenkov@nginx.com                read_buffer_size=buff_size,
1931274Szelenkov@nginx.com            )
1941274Szelenkov@nginx.com            socks.append(sock)
1951274Szelenkov@nginx.com
1961274Szelenkov@nginx.com        for i in range(10):
1971274Szelenkov@nginx.com            resp = self.recvall(socks[i], buff_size=buff_size).decode()
1981274Szelenkov@nginx.com            socks[i].close()
1991274Szelenkov@nginx.com
2001274Szelenkov@nginx.com            resp = self._resp_to_dict(resp)
2011274Szelenkov@nginx.com
202*1596Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
203*1596Szelenkov@nginx.com            assert resp['body'] == payload + str(i), 'body'
2041274Szelenkov@nginx.com
2051274Szelenkov@nginx.com    def test_proxy_header(self):
206*1596Szelenkov@nginx.com        assert 'success' in self.conf(
207*1596Szelenkov@nginx.com            {"pass": "applications/custom_header"}, 'listeners/*:7081'
208*1596Szelenkov@nginx.com        ), 'custom_header configure'
2091274Szelenkov@nginx.com
2101274Szelenkov@nginx.com        header_value = 'blah'
211*1596Szelenkov@nginx.com        assert (
2121274Szelenkov@nginx.com            self.get_http10(
2131274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
214*1596Szelenkov@nginx.com            )['headers']['Custom-Header']
215*1596Szelenkov@nginx.com            == header_value
216*1596Szelenkov@nginx.com        ), 'custom header'
2171274Szelenkov@nginx.com
2181274Szelenkov@nginx.com        header_value = '(),/:;<=>?@[\]{}\t !#$%&\'*+-.^_`|~'
219*1596Szelenkov@nginx.com        assert (
2201274Szelenkov@nginx.com            self.get_http10(
2211274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
222*1596Szelenkov@nginx.com            )['headers']['Custom-Header']
223*1596Szelenkov@nginx.com            == header_value
224*1596Szelenkov@nginx.com        ), 'custom header 2'
2251274Szelenkov@nginx.com
2261274Szelenkov@nginx.com        header_value = 'X' * 4096
227*1596Szelenkov@nginx.com        assert (
2281274Szelenkov@nginx.com            self.get_http10(
2291274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
230*1596Szelenkov@nginx.com            )['headers']['Custom-Header']
231*1596Szelenkov@nginx.com            == header_value
232*1596Szelenkov@nginx.com        ), 'custom header 3'
2331274Szelenkov@nginx.com
2341274Szelenkov@nginx.com        header_value = 'X' * 8191
235*1596Szelenkov@nginx.com        assert (
2361274Szelenkov@nginx.com            self.get_http10(
2371274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
238*1596Szelenkov@nginx.com            )['headers']['Custom-Header']
239*1596Szelenkov@nginx.com            == header_value
240*1596Szelenkov@nginx.com        ), 'custom header 4'
2411274Szelenkov@nginx.com
2421274Szelenkov@nginx.com        header_value = 'X' * 8192
243*1596Szelenkov@nginx.com        assert (
2441274Szelenkov@nginx.com            self.get_http10(
2451274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
246*1596Szelenkov@nginx.com            )['status']
247*1596Szelenkov@nginx.com            == 431
248*1596Szelenkov@nginx.com        ), 'custom header 5'
2491274Szelenkov@nginx.com
2501274Szelenkov@nginx.com    def test_proxy_fragmented(self):
2511274Szelenkov@nginx.com        _, sock = self.http(
2521274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
2531274Szelenkov@nginx.com        )
2541274Szelenkov@nginx.com
2551274Szelenkov@nginx.com        time.sleep(1)
2561274Szelenkov@nginx.com
2571274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhos".encode())
2581274Szelenkov@nginx.com
2591274Szelenkov@nginx.com        time.sleep(1)
2601274Szelenkov@nginx.com
2611274Szelenkov@nginx.com        sock.sendall("t\r\n\r\n".encode())
2621274Szelenkov@nginx.com
263*1596Szelenkov@nginx.com        assert re.search(
264*1596Szelenkov@nginx.com            '200 OK', self.recvall(sock).decode()
265*1596Szelenkov@nginx.com        ), 'fragmented send'
2661274Szelenkov@nginx.com        sock.close()
2671274Szelenkov@nginx.com
2681274Szelenkov@nginx.com    def test_proxy_fragmented_close(self):
2691274Szelenkov@nginx.com        _, sock = self.http(
2701274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
2711274Szelenkov@nginx.com        )
2721274Szelenkov@nginx.com
2731274Szelenkov@nginx.com        time.sleep(1)
2741274Szelenkov@nginx.com
2751274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHo".encode())
2761274Szelenkov@nginx.com
2771274Szelenkov@nginx.com        sock.close()
2781274Szelenkov@nginx.com
2791274Szelenkov@nginx.com    def test_proxy_fragmented_body(self):
2801274Szelenkov@nginx.com        _, sock = self.http(
2811274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
2821274Szelenkov@nginx.com        )
2831274Szelenkov@nginx.com
2841274Szelenkov@nginx.com        time.sleep(1)
2851274Szelenkov@nginx.com
2861274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
2871274Szelenkov@nginx.com        sock.sendall("Content-Length: 30000\r\n".encode())
2881274Szelenkov@nginx.com
2891274Szelenkov@nginx.com        time.sleep(1)
2901274Szelenkov@nginx.com
2911274Szelenkov@nginx.com        sock.sendall("\r\n".encode())
2921274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
2931274Szelenkov@nginx.com
2941274Szelenkov@nginx.com        time.sleep(1)
2951274Szelenkov@nginx.com
2961274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
2971274Szelenkov@nginx.com
2981274Szelenkov@nginx.com        time.sleep(1)
2991274Szelenkov@nginx.com
3001274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
3011274Szelenkov@nginx.com
3021274Szelenkov@nginx.com        resp = self._resp_to_dict(self.recvall(sock).decode())
3031274Szelenkov@nginx.com        sock.close()
3041274Szelenkov@nginx.com
305*1596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
306*1596Szelenkov@nginx.com        assert resp['body'] == "X" * 30000, 'body'
3071274Szelenkov@nginx.com
3081274Szelenkov@nginx.com    def test_proxy_fragmented_body_close(self):
3091274Szelenkov@nginx.com        _, sock = self.http(
3101274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
3111274Szelenkov@nginx.com        )
3121274Szelenkov@nginx.com
3131274Szelenkov@nginx.com        time.sleep(1)
3141274Szelenkov@nginx.com
3151274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
3161274Szelenkov@nginx.com        sock.sendall("Content-Length: 30000\r\n".encode())
3171274Szelenkov@nginx.com
3181274Szelenkov@nginx.com        time.sleep(1)
3191274Szelenkov@nginx.com
3201274Szelenkov@nginx.com        sock.sendall("\r\n".encode())
3211274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
3221274Szelenkov@nginx.com
3231274Szelenkov@nginx.com        sock.close()
3241274Szelenkov@nginx.com
3251274Szelenkov@nginx.com    def test_proxy_nowhere(self):
326*1596Szelenkov@nginx.com        assert 'success' in self.conf(
327*1596Szelenkov@nginx.com            [{"action": {"proxy": "http://127.0.0.1:7082"}}], 'routes'
328*1596Szelenkov@nginx.com        ), 'proxy path changed'
3291274Szelenkov@nginx.com
330*1596Szelenkov@nginx.com        assert self.get_http10()['status'] == 502, 'status'
3311274Szelenkov@nginx.com
3321274Szelenkov@nginx.com    def test_proxy_ipv6(self):
333*1596Szelenkov@nginx.com        assert 'success' in self.conf(
334*1596Szelenkov@nginx.com            {
335*1596Szelenkov@nginx.com                "*:7080": {"pass": "routes"},
336*1596Szelenkov@nginx.com                "[::1]:7081": {'application': 'mirror'},
337*1596Szelenkov@nginx.com            },
338*1596Szelenkov@nginx.com            'listeners',
339*1596Szelenkov@nginx.com        ), 'add ipv6 listener configure'
3401274Szelenkov@nginx.com
341*1596Szelenkov@nginx.com        assert 'success' in self.conf(
342*1596Szelenkov@nginx.com            [{"action": {"proxy": "http://[::1]:7081"}}], 'routes'
343*1596Szelenkov@nginx.com        ), 'proxy ipv6 configure'
3441274Szelenkov@nginx.com
345*1596Szelenkov@nginx.com        assert self.get_http10()['status'] == 200, 'status'
3461274Szelenkov@nginx.com
3471274Szelenkov@nginx.com    def test_proxy_unix(self):
348*1596Szelenkov@nginx.com        addr = self.temp_dir + '/sock'
3491274Szelenkov@nginx.com
350*1596Szelenkov@nginx.com        assert 'success' in self.conf(
351*1596Szelenkov@nginx.com            {
352*1596Szelenkov@nginx.com                "*:7080": {"pass": "routes"},
353*1596Szelenkov@nginx.com                "unix:" + addr: {'application': 'mirror'},
354*1596Szelenkov@nginx.com            },
355*1596Szelenkov@nginx.com            'listeners',
356*1596Szelenkov@nginx.com        ), 'add unix listener configure'
3571274Szelenkov@nginx.com
358*1596Szelenkov@nginx.com        assert 'success' in self.conf(
359*1596Szelenkov@nginx.com            [{"action": {"proxy": 'http://unix:' + addr}}], 'routes'
360*1596Szelenkov@nginx.com        ), 'proxy unix configure'
3611274Szelenkov@nginx.com
362*1596Szelenkov@nginx.com        assert self.get_http10()['status'] == 200, 'status'
3631274Szelenkov@nginx.com
3641274Szelenkov@nginx.com    def test_proxy_delayed(self):
365*1596Szelenkov@nginx.com        assert 'success' in self.conf(
366*1596Szelenkov@nginx.com            {"pass": "applications/delayed"}, 'listeners/*:7081'
367*1596Szelenkov@nginx.com        ), 'delayed configure'
3681274Szelenkov@nginx.com
3691274Szelenkov@nginx.com        body = '0123456789' * 1000
3701274Szelenkov@nginx.com        resp = self.post_http10(
3711274Szelenkov@nginx.com            headers={
3721274Szelenkov@nginx.com                'Host': 'localhost',
3731274Szelenkov@nginx.com                'Content-Type': 'text/html',
3741274Szelenkov@nginx.com                'Content-Length': str(len(body)),
3751274Szelenkov@nginx.com                'X-Parts': '2',
3761274Szelenkov@nginx.com                'X-Delay': '1',
3771274Szelenkov@nginx.com            },
3781274Szelenkov@nginx.com            body=body,
3791274Szelenkov@nginx.com        )
3801274Szelenkov@nginx.com
381*1596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
382*1596Szelenkov@nginx.com        assert resp['body'] == body, 'body'
3831274Szelenkov@nginx.com
3841274Szelenkov@nginx.com        resp = self.post_http10(
3851274Szelenkov@nginx.com            headers={
3861274Szelenkov@nginx.com                'Host': 'localhost',
3871274Szelenkov@nginx.com                'Content-Type': 'text/html',
3881274Szelenkov@nginx.com                'Content-Length': str(len(body)),
3891274Szelenkov@nginx.com                'X-Parts': '2',
3901274Szelenkov@nginx.com                'X-Delay': '1',
3911274Szelenkov@nginx.com            },
3921274Szelenkov@nginx.com            body=body,
3931274Szelenkov@nginx.com        )
3941274Szelenkov@nginx.com
395*1596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
396*1596Szelenkov@nginx.com        assert resp['body'] == body, 'body'
3971274Szelenkov@nginx.com
3981274Szelenkov@nginx.com    def test_proxy_delayed_close(self):
399*1596Szelenkov@nginx.com        assert 'success' in self.conf(
400*1596Szelenkov@nginx.com            {"pass": "applications/delayed"}, 'listeners/*:7081'
401*1596Szelenkov@nginx.com        ), 'delayed configure'
4021274Szelenkov@nginx.com
4031274Szelenkov@nginx.com        _, sock = self.post_http10(
4041274Szelenkov@nginx.com            headers={
4051274Szelenkov@nginx.com                'Host': 'localhost',
4061274Szelenkov@nginx.com                'Content-Type': 'text/html',
4071274Szelenkov@nginx.com                'Content-Length': '10000',
4081274Szelenkov@nginx.com                'X-Parts': '3',
4091274Szelenkov@nginx.com                'X-Delay': '1',
4101274Szelenkov@nginx.com            },
4111274Szelenkov@nginx.com            body='0123456789' * 1000,
4121274Szelenkov@nginx.com            start=True,
4131274Szelenkov@nginx.com            no_recv=True,
4141274Szelenkov@nginx.com        )
4151274Szelenkov@nginx.com
416*1596Szelenkov@nginx.com        assert re.search('200 OK', sock.recv(100).decode()), 'first'
4171274Szelenkov@nginx.com        sock.close()
4181274Szelenkov@nginx.com
4191274Szelenkov@nginx.com        _, sock = self.post_http10(
4201274Szelenkov@nginx.com            headers={
4211274Szelenkov@nginx.com                'Host': 'localhost',
4221274Szelenkov@nginx.com                'Content-Type': 'text/html',
4231274Szelenkov@nginx.com                'Content-Length': '10000',
4241274Szelenkov@nginx.com                'X-Parts': '3',
4251274Szelenkov@nginx.com                'X-Delay': '1',
4261274Szelenkov@nginx.com            },
4271274Szelenkov@nginx.com            body='0123456789' * 1000,
4281274Szelenkov@nginx.com            start=True,
4291274Szelenkov@nginx.com            no_recv=True,
4301274Szelenkov@nginx.com        )
4311274Szelenkov@nginx.com
432*1596Szelenkov@nginx.com        assert re.search('200 OK', sock.recv(100).decode()), 'second'
4331274Szelenkov@nginx.com        sock.close()
4341274Szelenkov@nginx.com
435*1596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
4361274Szelenkov@nginx.com    def test_proxy_content_length(self):
437*1596Szelenkov@nginx.com        assert 'success' in self.conf(
438*1596Szelenkov@nginx.com            [
439*1596Szelenkov@nginx.com                {
440*1596Szelenkov@nginx.com                    "action": {
441*1596Szelenkov@nginx.com                        "proxy": "http://127.0.0.1:" + str(self.SERVER_PORT)
4421274Szelenkov@nginx.com                    }
443*1596Szelenkov@nginx.com                }
444*1596Szelenkov@nginx.com            ],
445*1596Szelenkov@nginx.com            'routes',
446*1596Szelenkov@nginx.com        ), 'proxy backend configure'
4471274Szelenkov@nginx.com
4481274Szelenkov@nginx.com        resp = self.get_http10()
449*1596Szelenkov@nginx.com        assert len(resp['body']) == 0, 'body lt Content-Length 0'
4501274Szelenkov@nginx.com
4511274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '5'})
452*1596Szelenkov@nginx.com        assert len(resp['body']) == 5, 'body lt Content-Length 5'
4531274Szelenkov@nginx.com
4541274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '9'})
455*1596Szelenkov@nginx.com        assert len(resp['body']) == 9, 'body lt Content-Length 9'
4561274Szelenkov@nginx.com
4571274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '11'})
458*1596Szelenkov@nginx.com        assert len(resp['body']) == 10, 'body gt Content-Length 11'
4591274Szelenkov@nginx.com
4601274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '15'})
461*1596Szelenkov@nginx.com        assert len(resp['body']) == 10, 'body gt Content-Length 15'
4621274Szelenkov@nginx.com
4631274Szelenkov@nginx.com    def test_proxy_invalid(self):
4641476Szelenkov@nginx.com        def check_proxy(proxy):
465*1596Szelenkov@nginx.com            assert 'error' in \
466*1596Szelenkov@nginx.com                self.conf([{"action": {"proxy": proxy}}], 'routes'), \
467*1596Szelenkov@nginx.com                'proxy invalid'
4681476Szelenkov@nginx.com
4691476Szelenkov@nginx.com        check_proxy('blah')
4701476Szelenkov@nginx.com        check_proxy('/blah')
4711476Szelenkov@nginx.com        check_proxy('unix:/blah')
4721476Szelenkov@nginx.com        check_proxy('http://blah')
4731476Szelenkov@nginx.com        check_proxy('http://127.0.0.1')
4741476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:')
4751476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:blah')
4761476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:-1')
4771476Szelenkov@nginx.com        check_proxy('http://127.0.0.1:7080b')
4781476Szelenkov@nginx.com        check_proxy('http://[]')
4791476Szelenkov@nginx.com        check_proxy('http://[]:7080')
4801476Szelenkov@nginx.com        check_proxy('http://[:]:7080')
4811476Szelenkov@nginx.com        check_proxy('http://[::7080')
4821274Szelenkov@nginx.com
4831274Szelenkov@nginx.com    def test_proxy_loop(self):
484*1596Szelenkov@nginx.com        skip_alert(
485*1596Szelenkov@nginx.com            r'socket.*failed',
486*1596Szelenkov@nginx.com            r'accept.*failed',
487*1596Szelenkov@nginx.com            r'new connections are not accepted',
4881465Szelenkov@nginx.com        )
4891274Szelenkov@nginx.com        self.conf(
4901274Szelenkov@nginx.com            {
4911274Szelenkov@nginx.com                "listeners": {
4921274Szelenkov@nginx.com                    "*:7080": {"pass": "routes"},
4931274Szelenkov@nginx.com                    "*:7081": {"pass": "applications/mirror"},
4941274Szelenkov@nginx.com                    "*:7082": {"pass": "routes"},
4951274Szelenkov@nginx.com                },
4961274Szelenkov@nginx.com                "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
4971274Szelenkov@nginx.com                "applications": {
4981274Szelenkov@nginx.com                    "mirror": {
4991274Szelenkov@nginx.com                        "type": "python",
5001274Szelenkov@nginx.com                        "processes": {"spare": 0},
501*1596Szelenkov@nginx.com                        "path": option.test_dir + "/python/mirror",
502*1596Szelenkov@nginx.com                        "working_directory": option.test_dir + "/python/mirror",
5031274Szelenkov@nginx.com                        "module": "wsgi",
5041274Szelenkov@nginx.com                    },
5051274Szelenkov@nginx.com                },
5061274Szelenkov@nginx.com            }
5071274Szelenkov@nginx.com        )
5081274Szelenkov@nginx.com
5091274Szelenkov@nginx.com        self.get_http10(no_recv=True)
5101465Szelenkov@nginx.com        self.get_http10(read_timeout=1)
511