xref: /unit/test/test_proxy.py (revision 1274)
1*1274Szelenkov@nginx.comimport re
2*1274Szelenkov@nginx.comimport time
3*1274Szelenkov@nginx.comimport socket
4*1274Szelenkov@nginx.comimport unittest
5*1274Szelenkov@nginx.comfrom unit.applications.lang.python import TestApplicationPython
6*1274Szelenkov@nginx.com
7*1274Szelenkov@nginx.com
8*1274Szelenkov@nginx.comclass TestProxy(TestApplicationPython):
9*1274Szelenkov@nginx.com    prerequisites = {'modules': ['python']}
10*1274Szelenkov@nginx.com
11*1274Szelenkov@nginx.com    SERVER_PORT = 7999
12*1274Szelenkov@nginx.com
13*1274Szelenkov@nginx.com    def run_server(self):
14*1274Szelenkov@nginx.com        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
15*1274Szelenkov@nginx.com        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
16*1274Szelenkov@nginx.com
17*1274Szelenkov@nginx.com        server_address = ('', self.SERVER_PORT)
18*1274Szelenkov@nginx.com        sock.bind(server_address)
19*1274Szelenkov@nginx.com        sock.listen(5)
20*1274Szelenkov@nginx.com
21*1274Szelenkov@nginx.com        def recvall(sock):
22*1274Szelenkov@nginx.com            buff_size = 4096
23*1274Szelenkov@nginx.com            data = b''
24*1274Szelenkov@nginx.com            while True:
25*1274Szelenkov@nginx.com                part = sock.recv(buff_size)
26*1274Szelenkov@nginx.com                data += part
27*1274Szelenkov@nginx.com                if len(part) < buff_size:
28*1274Szelenkov@nginx.com                    break
29*1274Szelenkov@nginx.com            return data
30*1274Szelenkov@nginx.com
31*1274Szelenkov@nginx.com        req = b"""HTTP/1.1 200 OK
32*1274Szelenkov@nginx.comContent-Length: 10
33*1274Szelenkov@nginx.com
34*1274Szelenkov@nginx.com"""
35*1274Szelenkov@nginx.com
36*1274Szelenkov@nginx.com        while True:
37*1274Szelenkov@nginx.com            connection, client_address = sock.accept()
38*1274Szelenkov@nginx.com
39*1274Szelenkov@nginx.com            data = recvall(connection).decode()
40*1274Szelenkov@nginx.com
41*1274Szelenkov@nginx.com            to_send = req
42*1274Szelenkov@nginx.com
43*1274Szelenkov@nginx.com            m = re.search('X-Len: (\d+)', data)
44*1274Szelenkov@nginx.com            if m:
45*1274Szelenkov@nginx.com                to_send += b'X' * int(m.group(1))
46*1274Szelenkov@nginx.com
47*1274Szelenkov@nginx.com            connection.sendall(to_send)
48*1274Szelenkov@nginx.com
49*1274Szelenkov@nginx.com            connection.close()
50*1274Szelenkov@nginx.com
51*1274Szelenkov@nginx.com    def get_http10(self, *args, **kwargs):
52*1274Szelenkov@nginx.com        return self.get(*args, http_10=True, **kwargs)
53*1274Szelenkov@nginx.com
54*1274Szelenkov@nginx.com    def post_http10(self, *args, **kwargs):
55*1274Szelenkov@nginx.com        return self.post(*args, http_10=True, **kwargs)
56*1274Szelenkov@nginx.com
57*1274Szelenkov@nginx.com    def setUp(self):
58*1274Szelenkov@nginx.com        super().setUp()
59*1274Szelenkov@nginx.com
60*1274Szelenkov@nginx.com        self.run_process(self.run_server)
61*1274Szelenkov@nginx.com        self.waitforsocket(self.SERVER_PORT)
62*1274Szelenkov@nginx.com
63*1274Szelenkov@nginx.com        self.assertIn(
64*1274Szelenkov@nginx.com            'success',
65*1274Szelenkov@nginx.com            self.conf(
66*1274Szelenkov@nginx.com                {
67*1274Szelenkov@nginx.com                    "listeners": {
68*1274Szelenkov@nginx.com                        "*:7080": {"pass": "routes"},
69*1274Szelenkov@nginx.com                        "*:7081": {"pass": "applications/mirror"},
70*1274Szelenkov@nginx.com                    },
71*1274Szelenkov@nginx.com                    "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
72*1274Szelenkov@nginx.com                    "applications": {
73*1274Szelenkov@nginx.com                        "mirror": {
74*1274Szelenkov@nginx.com                            "type": "python",
75*1274Szelenkov@nginx.com                            "processes": {"spare": 0},
76*1274Szelenkov@nginx.com                            "path": self.current_dir + "/python/mirror",
77*1274Szelenkov@nginx.com                            "working_directory": self.current_dir
78*1274Szelenkov@nginx.com                            + "/python/mirror",
79*1274Szelenkov@nginx.com                            "module": "wsgi",
80*1274Szelenkov@nginx.com                        },
81*1274Szelenkov@nginx.com                        "custom_header": {
82*1274Szelenkov@nginx.com                            "type": "python",
83*1274Szelenkov@nginx.com                            "processes": {"spare": 0},
84*1274Szelenkov@nginx.com                            "path": self.current_dir + "/python/custom_header",
85*1274Szelenkov@nginx.com                            "working_directory": self.current_dir
86*1274Szelenkov@nginx.com                            + "/python/custom_header",
87*1274Szelenkov@nginx.com                            "module": "wsgi",
88*1274Szelenkov@nginx.com                        },
89*1274Szelenkov@nginx.com                        "delayed": {
90*1274Szelenkov@nginx.com                            "type": "python",
91*1274Szelenkov@nginx.com                            "processes": {"spare": 0},
92*1274Szelenkov@nginx.com                            "path": self.current_dir + "/python/delayed",
93*1274Szelenkov@nginx.com                            "working_directory": self.current_dir
94*1274Szelenkov@nginx.com                            + "/python/delayed",
95*1274Szelenkov@nginx.com                            "module": "wsgi",
96*1274Szelenkov@nginx.com                        },
97*1274Szelenkov@nginx.com                    },
98*1274Szelenkov@nginx.com                }
99*1274Szelenkov@nginx.com            ),
100*1274Szelenkov@nginx.com            'proxy initial configuration',
101*1274Szelenkov@nginx.com        )
102*1274Szelenkov@nginx.com
103*1274Szelenkov@nginx.com    def test_proxy_http10(self):
104*1274Szelenkov@nginx.com        for _ in range(10):
105*1274Szelenkov@nginx.com            self.assertEqual(self.get_http10()['status'], 200, 'status')
106*1274Szelenkov@nginx.com
107*1274Szelenkov@nginx.com    def test_proxy_chain(self):
108*1274Szelenkov@nginx.com        self.assertIn(
109*1274Szelenkov@nginx.com            'success',
110*1274Szelenkov@nginx.com            self.conf(
111*1274Szelenkov@nginx.com                {
112*1274Szelenkov@nginx.com                    "listeners": {
113*1274Szelenkov@nginx.com                        "*:7080": {"pass": "routes/first"},
114*1274Szelenkov@nginx.com                        "*:7081": {"pass": "routes/second"},
115*1274Szelenkov@nginx.com                        "*:7082": {"pass": "routes/third"},
116*1274Szelenkov@nginx.com                        "*:7083": {"pass": "routes/fourth"},
117*1274Szelenkov@nginx.com                        "*:7084": {"pass": "routes/fifth"},
118*1274Szelenkov@nginx.com                        "*:7085": {"pass": "applications/mirror"},
119*1274Szelenkov@nginx.com                    },
120*1274Szelenkov@nginx.com                    "routes": {
121*1274Szelenkov@nginx.com                        "first": [
122*1274Szelenkov@nginx.com                            {"action": {"proxy": "http://127.0.0.1:7081"}}
123*1274Szelenkov@nginx.com                        ],
124*1274Szelenkov@nginx.com                        "second": [
125*1274Szelenkov@nginx.com                            {"action": {"proxy": "http://127.0.0.1:7082"}}
126*1274Szelenkov@nginx.com                        ],
127*1274Szelenkov@nginx.com                        "third": [
128*1274Szelenkov@nginx.com                            {"action": {"proxy": "http://127.0.0.1:7083"}}
129*1274Szelenkov@nginx.com                        ],
130*1274Szelenkov@nginx.com                        "fourth": [
131*1274Szelenkov@nginx.com                            {"action": {"proxy": "http://127.0.0.1:7084"}}
132*1274Szelenkov@nginx.com                        ],
133*1274Szelenkov@nginx.com                        "fifth": [
134*1274Szelenkov@nginx.com                            {"action": {"proxy": "http://127.0.0.1:7085"}}
135*1274Szelenkov@nginx.com                        ],
136*1274Szelenkov@nginx.com                    },
137*1274Szelenkov@nginx.com                    "applications": {
138*1274Szelenkov@nginx.com                        "mirror": {
139*1274Szelenkov@nginx.com                            "type": "python",
140*1274Szelenkov@nginx.com                            "processes": {"spare": 0},
141*1274Szelenkov@nginx.com                            "path": self.current_dir + "/python/mirror",
142*1274Szelenkov@nginx.com                            "working_directory": self.current_dir
143*1274Szelenkov@nginx.com                            + "/python/mirror",
144*1274Szelenkov@nginx.com                            "module": "wsgi",
145*1274Szelenkov@nginx.com                        }
146*1274Szelenkov@nginx.com                    },
147*1274Szelenkov@nginx.com                }
148*1274Szelenkov@nginx.com            ),
149*1274Szelenkov@nginx.com            'proxy chain configuration',
150*1274Szelenkov@nginx.com        )
151*1274Szelenkov@nginx.com
152*1274Szelenkov@nginx.com        self.assertEqual(self.get_http10()['status'], 200, 'status')
153*1274Szelenkov@nginx.com
154*1274Szelenkov@nginx.com    def test_proxy_body(self):
155*1274Szelenkov@nginx.com        payload = '0123456789'
156*1274Szelenkov@nginx.com        for _ in range(10):
157*1274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
158*1274Szelenkov@nginx.com
159*1274Szelenkov@nginx.com            self.assertEqual(resp['status'], 200, 'status')
160*1274Szelenkov@nginx.com            self.assertEqual(resp['body'], payload, 'body')
161*1274Szelenkov@nginx.com
162*1274Szelenkov@nginx.com        payload = 'X' * 4096
163*1274Szelenkov@nginx.com        for _ in range(10):
164*1274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
165*1274Szelenkov@nginx.com
166*1274Szelenkov@nginx.com            self.assertEqual(resp['status'], 200, 'status')
167*1274Szelenkov@nginx.com            self.assertEqual(resp['body'], payload, 'body')
168*1274Szelenkov@nginx.com
169*1274Szelenkov@nginx.com        payload = 'X' * 4097
170*1274Szelenkov@nginx.com        for _ in range(10):
171*1274Szelenkov@nginx.com            resp = self.post_http10(body=payload)
172*1274Szelenkov@nginx.com
173*1274Szelenkov@nginx.com            self.assertEqual(resp['status'], 200, 'status')
174*1274Szelenkov@nginx.com            self.assertEqual(resp['body'], payload, 'body')
175*1274Szelenkov@nginx.com
176*1274Szelenkov@nginx.com        payload = 'X' * 4096 * 256
177*1274Szelenkov@nginx.com        for _ in range(10):
178*1274Szelenkov@nginx.com            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
179*1274Szelenkov@nginx.com
180*1274Szelenkov@nginx.com            self.assertEqual(resp['status'], 200, 'status')
181*1274Szelenkov@nginx.com            self.assertEqual(resp['body'], payload, 'body')
182*1274Szelenkov@nginx.com
183*1274Szelenkov@nginx.com        payload = 'X' * 4096 * 257
184*1274Szelenkov@nginx.com        for _ in range(10):
185*1274Szelenkov@nginx.com            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
186*1274Szelenkov@nginx.com
187*1274Szelenkov@nginx.com            self.assertEqual(resp['status'], 200, 'status')
188*1274Szelenkov@nginx.com            self.assertEqual(resp['body'], payload, 'body')
189*1274Szelenkov@nginx.com
190*1274Szelenkov@nginx.com    def test_proxy_parallel(self):
191*1274Szelenkov@nginx.com        payload = 'X' * 4096 * 257
192*1274Szelenkov@nginx.com        buff_size = 4096 * 258
193*1274Szelenkov@nginx.com
194*1274Szelenkov@nginx.com        socks = []
195*1274Szelenkov@nginx.com        for i in range(10):
196*1274Szelenkov@nginx.com            _, sock = self.post_http10(
197*1274Szelenkov@nginx.com                body=payload + str(i),
198*1274Szelenkov@nginx.com                start=True,
199*1274Szelenkov@nginx.com                no_recv=True,
200*1274Szelenkov@nginx.com                read_buffer_size=buff_size,
201*1274Szelenkov@nginx.com            )
202*1274Szelenkov@nginx.com            socks.append(sock)
203*1274Szelenkov@nginx.com
204*1274Szelenkov@nginx.com        for i in range(10):
205*1274Szelenkov@nginx.com            resp = self.recvall(socks[i], buff_size=buff_size).decode()
206*1274Szelenkov@nginx.com            socks[i].close()
207*1274Szelenkov@nginx.com
208*1274Szelenkov@nginx.com            resp = self._resp_to_dict(resp)
209*1274Szelenkov@nginx.com
210*1274Szelenkov@nginx.com            self.assertEqual(resp['status'], 200, 'status')
211*1274Szelenkov@nginx.com            self.assertEqual(resp['body'], payload + str(i), 'body')
212*1274Szelenkov@nginx.com
213*1274Szelenkov@nginx.com    def test_proxy_header(self):
214*1274Szelenkov@nginx.com        self.assertIn(
215*1274Szelenkov@nginx.com            'success',
216*1274Szelenkov@nginx.com            self.conf(
217*1274Szelenkov@nginx.com                {"pass": "applications/custom_header"}, 'listeners/*:7081'
218*1274Szelenkov@nginx.com            ),
219*1274Szelenkov@nginx.com            'custom_header configure',
220*1274Szelenkov@nginx.com        )
221*1274Szelenkov@nginx.com
222*1274Szelenkov@nginx.com        header_value = 'blah'
223*1274Szelenkov@nginx.com        self.assertEqual(
224*1274Szelenkov@nginx.com            self.get_http10(
225*1274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
226*1274Szelenkov@nginx.com            )['headers']['Custom-Header'],
227*1274Szelenkov@nginx.com            header_value,
228*1274Szelenkov@nginx.com            'custom header',
229*1274Szelenkov@nginx.com        )
230*1274Szelenkov@nginx.com
231*1274Szelenkov@nginx.com        header_value = '(),/:;<=>?@[\]{}\t !#$%&\'*+-.^_`|~'
232*1274Szelenkov@nginx.com        self.assertEqual(
233*1274Szelenkov@nginx.com            self.get_http10(
234*1274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
235*1274Szelenkov@nginx.com            )['headers']['Custom-Header'],
236*1274Szelenkov@nginx.com            header_value,
237*1274Szelenkov@nginx.com            'custom header 2',
238*1274Szelenkov@nginx.com        )
239*1274Szelenkov@nginx.com
240*1274Szelenkov@nginx.com        header_value = 'X' * 4096
241*1274Szelenkov@nginx.com        self.assertEqual(
242*1274Szelenkov@nginx.com            self.get_http10(
243*1274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
244*1274Szelenkov@nginx.com            )['headers']['Custom-Header'],
245*1274Szelenkov@nginx.com            header_value,
246*1274Szelenkov@nginx.com            'custom header 3',
247*1274Szelenkov@nginx.com        )
248*1274Szelenkov@nginx.com
249*1274Szelenkov@nginx.com        header_value = 'X' * 8191
250*1274Szelenkov@nginx.com        self.assertEqual(
251*1274Szelenkov@nginx.com            self.get_http10(
252*1274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
253*1274Szelenkov@nginx.com            )['headers']['Custom-Header'],
254*1274Szelenkov@nginx.com            header_value,
255*1274Szelenkov@nginx.com            'custom header 4',
256*1274Szelenkov@nginx.com        )
257*1274Szelenkov@nginx.com
258*1274Szelenkov@nginx.com        header_value = 'X' * 8192
259*1274Szelenkov@nginx.com        self.assertEqual(
260*1274Szelenkov@nginx.com            self.get_http10(
261*1274Szelenkov@nginx.com                headers={'Host': 'localhost', 'Custom-Header': header_value}
262*1274Szelenkov@nginx.com            )['status'],
263*1274Szelenkov@nginx.com            431,
264*1274Szelenkov@nginx.com            'custom header 5',
265*1274Szelenkov@nginx.com        )
266*1274Szelenkov@nginx.com
267*1274Szelenkov@nginx.com    def test_proxy_fragmented(self):
268*1274Szelenkov@nginx.com        _, sock = self.http(
269*1274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
270*1274Szelenkov@nginx.com        )
271*1274Szelenkov@nginx.com
272*1274Szelenkov@nginx.com        time.sleep(1)
273*1274Szelenkov@nginx.com
274*1274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhos".encode())
275*1274Szelenkov@nginx.com
276*1274Szelenkov@nginx.com        time.sleep(1)
277*1274Szelenkov@nginx.com
278*1274Szelenkov@nginx.com        sock.sendall("t\r\n\r\n".encode())
279*1274Szelenkov@nginx.com
280*1274Szelenkov@nginx.com        self.assertRegex(
281*1274Szelenkov@nginx.com            self.recvall(sock).decode(), '200 OK', 'fragmented send'
282*1274Szelenkov@nginx.com        )
283*1274Szelenkov@nginx.com        sock.close()
284*1274Szelenkov@nginx.com
285*1274Szelenkov@nginx.com    def test_proxy_fragmented_close(self):
286*1274Szelenkov@nginx.com        _, sock = self.http(
287*1274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
288*1274Szelenkov@nginx.com        )
289*1274Szelenkov@nginx.com
290*1274Szelenkov@nginx.com        time.sleep(1)
291*1274Szelenkov@nginx.com
292*1274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHo".encode())
293*1274Szelenkov@nginx.com
294*1274Szelenkov@nginx.com        sock.close()
295*1274Szelenkov@nginx.com
296*1274Szelenkov@nginx.com    def test_proxy_fragmented_body(self):
297*1274Szelenkov@nginx.com        _, sock = self.http(
298*1274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
299*1274Szelenkov@nginx.com        )
300*1274Szelenkov@nginx.com
301*1274Szelenkov@nginx.com        time.sleep(1)
302*1274Szelenkov@nginx.com
303*1274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
304*1274Szelenkov@nginx.com        sock.sendall("Content-Length: 30000\r\n".encode())
305*1274Szelenkov@nginx.com
306*1274Szelenkov@nginx.com        time.sleep(1)
307*1274Szelenkov@nginx.com
308*1274Szelenkov@nginx.com        sock.sendall("\r\n".encode())
309*1274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
310*1274Szelenkov@nginx.com
311*1274Szelenkov@nginx.com        time.sleep(1)
312*1274Szelenkov@nginx.com
313*1274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
314*1274Szelenkov@nginx.com
315*1274Szelenkov@nginx.com        time.sleep(1)
316*1274Szelenkov@nginx.com
317*1274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
318*1274Szelenkov@nginx.com
319*1274Szelenkov@nginx.com        resp = self._resp_to_dict(self.recvall(sock).decode())
320*1274Szelenkov@nginx.com        sock.close()
321*1274Szelenkov@nginx.com
322*1274Szelenkov@nginx.com        self.assertEqual(resp['status'], 200, 'status')
323*1274Szelenkov@nginx.com        self.assertEqual(resp['body'], "X" * 30000, 'body')
324*1274Szelenkov@nginx.com
325*1274Szelenkov@nginx.com    def test_proxy_fragmented_body_close(self):
326*1274Szelenkov@nginx.com        _, sock = self.http(
327*1274Szelenkov@nginx.com            b"""GET / HTT""", raw=True, start=True, no_recv=True
328*1274Szelenkov@nginx.com        )
329*1274Szelenkov@nginx.com
330*1274Szelenkov@nginx.com        time.sleep(1)
331*1274Szelenkov@nginx.com
332*1274Szelenkov@nginx.com        sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
333*1274Szelenkov@nginx.com        sock.sendall("Content-Length: 30000\r\n".encode())
334*1274Szelenkov@nginx.com
335*1274Szelenkov@nginx.com        time.sleep(1)
336*1274Szelenkov@nginx.com
337*1274Szelenkov@nginx.com        sock.sendall("\r\n".encode())
338*1274Szelenkov@nginx.com        sock.sendall(("X" * 10000).encode())
339*1274Szelenkov@nginx.com
340*1274Szelenkov@nginx.com        sock.close()
341*1274Szelenkov@nginx.com
342*1274Szelenkov@nginx.com    def test_proxy_nowhere(self):
343*1274Szelenkov@nginx.com        self.assertIn(
344*1274Szelenkov@nginx.com            'success',
345*1274Szelenkov@nginx.com            self.conf(
346*1274Szelenkov@nginx.com                [{"action": {"proxy": "http://127.0.0.1:7082"}}], 'routes'
347*1274Szelenkov@nginx.com            ),
348*1274Szelenkov@nginx.com            'proxy path changed',
349*1274Szelenkov@nginx.com        )
350*1274Szelenkov@nginx.com
351*1274Szelenkov@nginx.com        self.assertEqual(self.get_http10()['status'], 502, 'status')
352*1274Szelenkov@nginx.com
353*1274Szelenkov@nginx.com    def test_proxy_ipv6(self):
354*1274Szelenkov@nginx.com        self.assertIn(
355*1274Szelenkov@nginx.com            'success',
356*1274Szelenkov@nginx.com            self.conf(
357*1274Szelenkov@nginx.com                {
358*1274Szelenkov@nginx.com                    "*:7080": {"pass": "routes"},
359*1274Szelenkov@nginx.com                    "[::1]:7081": {'application': 'mirror'},
360*1274Szelenkov@nginx.com                },
361*1274Szelenkov@nginx.com                'listeners',
362*1274Szelenkov@nginx.com            ),
363*1274Szelenkov@nginx.com            'add ipv6 listener configure',
364*1274Szelenkov@nginx.com        )
365*1274Szelenkov@nginx.com
366*1274Szelenkov@nginx.com        self.assertIn(
367*1274Szelenkov@nginx.com            'success',
368*1274Szelenkov@nginx.com            self.conf([{"action": {"proxy": "http://[::1]:7081"}}], 'routes'),
369*1274Szelenkov@nginx.com            'proxy ipv6 configure',
370*1274Szelenkov@nginx.com        )
371*1274Szelenkov@nginx.com
372*1274Szelenkov@nginx.com        self.assertEqual(self.get_http10()['status'], 200, 'status')
373*1274Szelenkov@nginx.com
374*1274Szelenkov@nginx.com    def test_proxy_unix(self):
375*1274Szelenkov@nginx.com        addr = self.testdir + '/sock'
376*1274Szelenkov@nginx.com
377*1274Szelenkov@nginx.com        self.assertIn(
378*1274Szelenkov@nginx.com            'success',
379*1274Szelenkov@nginx.com            self.conf(
380*1274Szelenkov@nginx.com                {
381*1274Szelenkov@nginx.com                    "*:7080": {"pass": "routes"},
382*1274Szelenkov@nginx.com                    "unix:" + addr: {'application': 'mirror'},
383*1274Szelenkov@nginx.com                },
384*1274Szelenkov@nginx.com                'listeners',
385*1274Szelenkov@nginx.com            ),
386*1274Szelenkov@nginx.com            'add unix listener configure',
387*1274Szelenkov@nginx.com        )
388*1274Szelenkov@nginx.com
389*1274Szelenkov@nginx.com        self.assertIn(
390*1274Szelenkov@nginx.com            'success',
391*1274Szelenkov@nginx.com            self.conf(
392*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://unix:' + addr}}], 'routes'
393*1274Szelenkov@nginx.com            ),
394*1274Szelenkov@nginx.com            'proxy unix configure',
395*1274Szelenkov@nginx.com        )
396*1274Szelenkov@nginx.com
397*1274Szelenkov@nginx.com        self.assertEqual(self.get_http10()['status'], 200, 'status')
398*1274Szelenkov@nginx.com
399*1274Szelenkov@nginx.com    def test_proxy_delayed(self):
400*1274Szelenkov@nginx.com        self.assertIn(
401*1274Szelenkov@nginx.com            'success',
402*1274Szelenkov@nginx.com            self.conf(
403*1274Szelenkov@nginx.com                {"pass": "applications/delayed"}, 'listeners/*:7081'
404*1274Szelenkov@nginx.com            ),
405*1274Szelenkov@nginx.com            'delayed configure',
406*1274Szelenkov@nginx.com        )
407*1274Szelenkov@nginx.com
408*1274Szelenkov@nginx.com        body = '0123456789' * 1000
409*1274Szelenkov@nginx.com        resp = self.post_http10(
410*1274Szelenkov@nginx.com            headers={
411*1274Szelenkov@nginx.com                'Host': 'localhost',
412*1274Szelenkov@nginx.com                'Content-Type': 'text/html',
413*1274Szelenkov@nginx.com                'Content-Length': str(len(body)),
414*1274Szelenkov@nginx.com                'X-Parts': '2',
415*1274Szelenkov@nginx.com                'X-Delay': '1',
416*1274Szelenkov@nginx.com            },
417*1274Szelenkov@nginx.com            body=body,
418*1274Szelenkov@nginx.com        )
419*1274Szelenkov@nginx.com
420*1274Szelenkov@nginx.com        self.assertEqual(resp['status'], 200, 'status')
421*1274Szelenkov@nginx.com        self.assertEqual(resp['body'], body, 'body')
422*1274Szelenkov@nginx.com
423*1274Szelenkov@nginx.com        resp = self.post_http10(
424*1274Szelenkov@nginx.com            headers={
425*1274Szelenkov@nginx.com                'Host': 'localhost',
426*1274Szelenkov@nginx.com                'Content-Type': 'text/html',
427*1274Szelenkov@nginx.com                'Content-Length': str(len(body)),
428*1274Szelenkov@nginx.com                'X-Parts': '2',
429*1274Szelenkov@nginx.com                'X-Delay': '1',
430*1274Szelenkov@nginx.com            },
431*1274Szelenkov@nginx.com            body=body,
432*1274Szelenkov@nginx.com        )
433*1274Szelenkov@nginx.com
434*1274Szelenkov@nginx.com        self.assertEqual(resp['status'], 200, 'status')
435*1274Szelenkov@nginx.com        self.assertEqual(resp['body'], body, 'body')
436*1274Szelenkov@nginx.com
437*1274Szelenkov@nginx.com    def test_proxy_delayed_close(self):
438*1274Szelenkov@nginx.com        self.assertIn(
439*1274Szelenkov@nginx.com            'success',
440*1274Szelenkov@nginx.com            self.conf(
441*1274Szelenkov@nginx.com                {"pass": "applications/delayed"}, 'listeners/*:7081'
442*1274Szelenkov@nginx.com            ),
443*1274Szelenkov@nginx.com            'delayed configure',
444*1274Szelenkov@nginx.com        )
445*1274Szelenkov@nginx.com
446*1274Szelenkov@nginx.com        _, sock = self.post_http10(
447*1274Szelenkov@nginx.com            headers={
448*1274Szelenkov@nginx.com                'Host': 'localhost',
449*1274Szelenkov@nginx.com                'Content-Type': 'text/html',
450*1274Szelenkov@nginx.com                'Content-Length': '10000',
451*1274Szelenkov@nginx.com                'X-Parts': '3',
452*1274Szelenkov@nginx.com                'X-Delay': '1',
453*1274Szelenkov@nginx.com            },
454*1274Szelenkov@nginx.com            body='0123456789' * 1000,
455*1274Szelenkov@nginx.com            start=True,
456*1274Szelenkov@nginx.com            no_recv=True,
457*1274Szelenkov@nginx.com        )
458*1274Szelenkov@nginx.com
459*1274Szelenkov@nginx.com        self.assertRegex(
460*1274Szelenkov@nginx.com            sock.recv(100).decode(), '200 OK', 'first'
461*1274Szelenkov@nginx.com        )
462*1274Szelenkov@nginx.com        sock.close()
463*1274Szelenkov@nginx.com
464*1274Szelenkov@nginx.com        _, sock = self.post_http10(
465*1274Szelenkov@nginx.com            headers={
466*1274Szelenkov@nginx.com                'Host': 'localhost',
467*1274Szelenkov@nginx.com                'Content-Type': 'text/html',
468*1274Szelenkov@nginx.com                'Content-Length': '10000',
469*1274Szelenkov@nginx.com                'X-Parts': '3',
470*1274Szelenkov@nginx.com                'X-Delay': '1',
471*1274Szelenkov@nginx.com            },
472*1274Szelenkov@nginx.com            body='0123456789' * 1000,
473*1274Szelenkov@nginx.com            start=True,
474*1274Szelenkov@nginx.com            no_recv=True,
475*1274Szelenkov@nginx.com        )
476*1274Szelenkov@nginx.com
477*1274Szelenkov@nginx.com        self.assertRegex(
478*1274Szelenkov@nginx.com            sock.recv(100).decode(), '200 OK', 'second'
479*1274Szelenkov@nginx.com        )
480*1274Szelenkov@nginx.com        sock.close()
481*1274Szelenkov@nginx.com
482*1274Szelenkov@nginx.com    @unittest.skip('not yet')
483*1274Szelenkov@nginx.com    def test_proxy_content_length(self):
484*1274Szelenkov@nginx.com        self.assertIn(
485*1274Szelenkov@nginx.com            'success',
486*1274Szelenkov@nginx.com            self.conf(
487*1274Szelenkov@nginx.com                [
488*1274Szelenkov@nginx.com                    {
489*1274Szelenkov@nginx.com                        "action": {
490*1274Szelenkov@nginx.com                            "proxy": "http://127.0.0.1:"
491*1274Szelenkov@nginx.com                            + str(self.SERVER_PORT)
492*1274Szelenkov@nginx.com                        }
493*1274Szelenkov@nginx.com                    }
494*1274Szelenkov@nginx.com                ],
495*1274Szelenkov@nginx.com                'routes',
496*1274Szelenkov@nginx.com            ),
497*1274Szelenkov@nginx.com            'proxy backend configure',
498*1274Szelenkov@nginx.com        )
499*1274Szelenkov@nginx.com
500*1274Szelenkov@nginx.com        resp = self.get_http10()
501*1274Szelenkov@nginx.com        self.assertEqual(len(resp['body']), 0, 'body lt Content-Length 0')
502*1274Szelenkov@nginx.com
503*1274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '5'})
504*1274Szelenkov@nginx.com        self.assertEqual(len(resp['body']), 5, 'body lt Content-Length 5')
505*1274Szelenkov@nginx.com
506*1274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '9'})
507*1274Szelenkov@nginx.com        self.assertEqual(len(resp['body']), 9, 'body lt Content-Length 9')
508*1274Szelenkov@nginx.com
509*1274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '11'})
510*1274Szelenkov@nginx.com        self.assertEqual(len(resp['body']), 10, 'body gt Content-Length 11')
511*1274Szelenkov@nginx.com
512*1274Szelenkov@nginx.com        resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '15'})
513*1274Szelenkov@nginx.com        self.assertEqual(len(resp['body']), 10, 'body gt Content-Length 15')
514*1274Szelenkov@nginx.com
515*1274Szelenkov@nginx.com    def test_proxy_invalid(self):
516*1274Szelenkov@nginx.com        self.assertIn(
517*1274Szelenkov@nginx.com            'error',
518*1274Szelenkov@nginx.com            self.conf([{"action": {"proxy": 'blah'}}], 'routes'),
519*1274Szelenkov@nginx.com            'proxy invalid',
520*1274Szelenkov@nginx.com        )
521*1274Szelenkov@nginx.com        self.assertIn(
522*1274Szelenkov@nginx.com            'error',
523*1274Szelenkov@nginx.com            self.conf([{"action": {"proxy": '/blah'}}], 'routes'),
524*1274Szelenkov@nginx.com            'proxy invalid 2',
525*1274Szelenkov@nginx.com        )
526*1274Szelenkov@nginx.com        self.assertIn(
527*1274Szelenkov@nginx.com            'error',
528*1274Szelenkov@nginx.com            self.conf([{"action": {"proxy": 'unix:/blah'}}], 'routes'),
529*1274Szelenkov@nginx.com            'proxy unix invalid 2',
530*1274Szelenkov@nginx.com        )
531*1274Szelenkov@nginx.com        self.assertIn(
532*1274Szelenkov@nginx.com            'error',
533*1274Szelenkov@nginx.com            self.conf([{"action": {"proxy": 'http://blah'}}], 'routes'),
534*1274Szelenkov@nginx.com            'proxy unix invalid 3',
535*1274Szelenkov@nginx.com        )
536*1274Szelenkov@nginx.com        self.assertIn(
537*1274Szelenkov@nginx.com            'error',
538*1274Szelenkov@nginx.com            self.conf([{"action": {"proxy": 'http://127.0.0.1'}}], 'routes'),
539*1274Szelenkov@nginx.com            'proxy ipv4 invalid',
540*1274Szelenkov@nginx.com        )
541*1274Szelenkov@nginx.com        self.assertIn(
542*1274Szelenkov@nginx.com            'error',
543*1274Szelenkov@nginx.com            self.conf([{"action": {"proxy": 'http://127.0.0.1:'}}], 'routes'),
544*1274Szelenkov@nginx.com            'proxy ipv4 invalid 2',
545*1274Szelenkov@nginx.com        )
546*1274Szelenkov@nginx.com        self.assertIn(
547*1274Szelenkov@nginx.com            'error',
548*1274Szelenkov@nginx.com            self.conf(
549*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://127.0.0.1:blah'}}], 'routes'
550*1274Szelenkov@nginx.com            ),
551*1274Szelenkov@nginx.com            'proxy ipv4 invalid 3',
552*1274Szelenkov@nginx.com        )
553*1274Szelenkov@nginx.com        self.assertIn(
554*1274Szelenkov@nginx.com            'error',
555*1274Szelenkov@nginx.com            self.conf(
556*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://127.0.0.1:-1'}}], 'routes'
557*1274Szelenkov@nginx.com            ),
558*1274Szelenkov@nginx.com            'proxy ipv4 invalid 4',
559*1274Szelenkov@nginx.com        )
560*1274Szelenkov@nginx.com        self.assertIn(
561*1274Szelenkov@nginx.com            'error',
562*1274Szelenkov@nginx.com            self.conf(
563*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://127.0.0.1:7080b'}}], 'routes'
564*1274Szelenkov@nginx.com            ),
565*1274Szelenkov@nginx.com            'proxy ipv4 invalid 5',
566*1274Szelenkov@nginx.com        )
567*1274Szelenkov@nginx.com        self.assertIn(
568*1274Szelenkov@nginx.com            'error',
569*1274Szelenkov@nginx.com            self.conf(
570*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://[]'}}], 'routes'
571*1274Szelenkov@nginx.com            ),
572*1274Szelenkov@nginx.com            'proxy ipv6 invalid',
573*1274Szelenkov@nginx.com        )
574*1274Szelenkov@nginx.com        self.assertIn(
575*1274Szelenkov@nginx.com            'error',
576*1274Szelenkov@nginx.com            self.conf(
577*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://[]:7080'}}], 'routes'
578*1274Szelenkov@nginx.com            ),
579*1274Szelenkov@nginx.com            'proxy ipv6 invalid 2',
580*1274Szelenkov@nginx.com        )
581*1274Szelenkov@nginx.com        self.assertIn(
582*1274Szelenkov@nginx.com            'error',
583*1274Szelenkov@nginx.com            self.conf(
584*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://[:]:7080'}}], 'routes'
585*1274Szelenkov@nginx.com            ),
586*1274Szelenkov@nginx.com            'proxy ipv6 invalid 3',
587*1274Szelenkov@nginx.com        )
588*1274Szelenkov@nginx.com        self.assertIn(
589*1274Szelenkov@nginx.com            'error',
590*1274Szelenkov@nginx.com            self.conf(
591*1274Szelenkov@nginx.com                [{"action": {"proxy": 'http://[::7080'}}], 'routes'
592*1274Szelenkov@nginx.com            ),
593*1274Szelenkov@nginx.com            'proxy ipv6 invalid 4',
594*1274Szelenkov@nginx.com        )
595*1274Szelenkov@nginx.com
596*1274Szelenkov@nginx.com    @unittest.skip('not yet')
597*1274Szelenkov@nginx.com    def test_proxy_loop(self):
598*1274Szelenkov@nginx.com        self.conf(
599*1274Szelenkov@nginx.com            {
600*1274Szelenkov@nginx.com                "listeners": {
601*1274Szelenkov@nginx.com                    "*:7080": {"pass": "routes"},
602*1274Szelenkov@nginx.com                    "*:7081": {"pass": "applications/mirror"},
603*1274Szelenkov@nginx.com                    "*:7082": {"pass": "routes"},
604*1274Szelenkov@nginx.com                },
605*1274Szelenkov@nginx.com                "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
606*1274Szelenkov@nginx.com                "applications": {
607*1274Szelenkov@nginx.com                    "mirror": {
608*1274Szelenkov@nginx.com                        "type": "python",
609*1274Szelenkov@nginx.com                        "processes": {"spare": 0},
610*1274Szelenkov@nginx.com                        "path": self.current_dir + "/python/mirror",
611*1274Szelenkov@nginx.com                        "working_directory": self.current_dir
612*1274Szelenkov@nginx.com                        + "/python/mirror",
613*1274Szelenkov@nginx.com                        "module": "wsgi",
614*1274Szelenkov@nginx.com                    },
615*1274Szelenkov@nginx.com                },
616*1274Szelenkov@nginx.com            }
617*1274Szelenkov@nginx.com        )
618*1274Szelenkov@nginx.com
619*1274Szelenkov@nginx.com        self.get_http10(no_recv=True)
620*1274Szelenkov@nginx.com
621*1274Szelenkov@nginx.comif __name__ == '__main__':
622*1274Szelenkov@nginx.com    TestProxy.main()
623