summaryrefslogtreecommitdiffhomepage
path: root/test/test_proxy.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_proxy.py')
-rw-r--r--test/test_proxy.py805
1 files changed, 411 insertions, 394 deletions
diff --git a/test/test_proxy.py b/test/test_proxy.py
index ad14c23d..207e90e7 100644
--- a/test/test_proxy.py
+++ b/test/test_proxy.py
@@ -4,487 +4,504 @@ import time
import pytest
from conftest import run_process
-from unit.applications.lang.python import TestApplicationPython
+from unit.applications.lang.python import ApplicationPython
from unit.option import option
from unit.utils import waitforsocket
prerequisites = {'modules': {'python': 'any'}}
+client = ApplicationPython()
+SERVER_PORT = 7999
-class TestProxy(TestApplicationPython):
- SERVER_PORT = 7999
- @pytest.fixture(autouse=True)
- def setup_method_fixture(self):
- run_process(self.run_server, self.SERVER_PORT)
- waitforsocket(self.SERVER_PORT)
+@pytest.fixture(autouse=True)
+def setup_method_fixture():
+ run_process(run_server, SERVER_PORT)
+ waitforsocket(SERVER_PORT)
- python_dir = f'{option.test_dir}/python'
- assert 'success' in self.conf(
- {
- "listeners": {
- "*:7080": {"pass": "routes"},
- "*:7081": {"pass": "applications/mirror"},
+ python_dir = f'{option.test_dir}/python'
+ assert 'success' in client.conf(
+ {
+ "listeners": {
+ "*:7080": {"pass": "routes"},
+ "*:7081": {"pass": "applications/mirror"},
+ },
+ "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
+ "applications": {
+ "mirror": {
+ "type": client.get_application_type(),
+ "processes": {"spare": 0},
+ "path": f'{python_dir}/mirror',
+ "working_directory": f'{python_dir}/mirror',
+ "module": "wsgi",
+ },
+ "custom_header": {
+ "type": client.get_application_type(),
+ "processes": {"spare": 0},
+ "path": f'{python_dir}/custom_header',
+ "working_directory": f'{python_dir}/custom_header',
+ "module": "wsgi",
},
- "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
- "applications": {
- "mirror": {
- "type": self.get_application_type(),
- "processes": {"spare": 0},
- "path": f'{python_dir}/mirror',
- "working_directory": f'{python_dir}/mirror',
- "module": "wsgi",
- },
- "custom_header": {
- "type": self.get_application_type(),
- "processes": {"spare": 0},
- "path": f'{python_dir}/custom_header',
- "working_directory": f'{python_dir}/custom_header',
- "module": "wsgi",
- },
- "delayed": {
- "type": self.get_application_type(),
- "processes": {"spare": 0},
- "path": f'{python_dir}/delayed',
- "working_directory": f'{python_dir}/delayed',
- "module": "wsgi",
- },
+ "delayed": {
+ "type": client.get_application_type(),
+ "processes": {"spare": 0},
+ "path": f'{python_dir}/delayed',
+ "working_directory": f'{python_dir}/delayed',
+ "module": "wsgi",
},
- }
- ), 'proxy initial configuration'
-
- @staticmethod
- def run_server(server_port):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- server_address = ('', server_port)
- sock.bind(server_address)
- sock.listen(5)
-
- def recvall(sock):
- buff_size = 4096
- data = b''
- while True:
- part = sock.recv(buff_size)
- data += part
- if len(part) < buff_size:
- break
- return data
-
- req = b"""HTTP/1.1 200 OK
+ },
+ }
+ ), 'proxy initial configuration'
+
+
+def run_server(server_port):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+ server_address = ('', server_port)
+ sock.bind(server_address)
+ sock.listen(5)
+
+ def recvall(sock):
+ buff_size = 4096
+ data = b''
+ while True:
+ part = sock.recv(buff_size)
+ data += part
+ if len(part) < buff_size:
+ break
+ return data
+
+ req = b"""HTTP/1.1 200 OK
Content-Length: 10
"""
- while True:
- connection, _ = sock.accept()
+ while True:
+ connection, _ = sock.accept()
- data = recvall(connection).decode()
+ data = recvall(connection).decode()
- to_send = req
+ to_send = req
- m = re.search(r'X-Len: (\d+)', data)
- if m:
- to_send += b'X' * int(m.group(1))
+ m = re.search(r'X-Len: (\d+)', data)
+ if m:
+ to_send += b'X' * int(m.group(1))
- connection.sendall(to_send)
+ connection.sendall(to_send)
- connection.close()
+ connection.close()
- def get_http10(self, *args, **kwargs):
- return self.get(*args, http_10=True, **kwargs)
- def post_http10(self, *args, **kwargs):
- return self.post(*args, http_10=True, **kwargs)
+def get_http10(*args, **kwargs):
+ return client.get(*args, http_10=True, **kwargs)
- def test_proxy_http10(self):
- for _ in range(10):
- assert self.get_http10()['status'] == 200, 'status'
- def test_proxy_chain(self):
- assert 'success' in self.conf(
- {
- "listeners": {
- "*:7080": {"pass": "routes/first"},
- "*:7081": {"pass": "routes/second"},
- "*:7082": {"pass": "routes/third"},
- "*:7083": {"pass": "routes/fourth"},
- "*:7084": {"pass": "routes/fifth"},
- "*:7085": {"pass": "applications/mirror"},
- },
- "routes": {
- "first": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
- "second": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
- "third": [{"action": {"proxy": "http://127.0.0.1:7083"}}],
- "fourth": [{"action": {"proxy": "http://127.0.0.1:7084"}}],
- "fifth": [{"action": {"proxy": "http://127.0.0.1:7085"}}],
- },
- "applications": {
- "mirror": {
- "type": self.get_application_type(),
- "processes": {"spare": 0},
- "path": f'{option.test_dir}/python/mirror',
- "working_directory": f'{option.test_dir}/python/mirror',
- "module": "wsgi",
- }
- },
- }
- ), 'proxy chain configuration'
+def post_http10(*args, **kwargs):
+ return client.post(*args, http_10=True, **kwargs)
- assert self.get_http10()['status'] == 200, 'status'
- def test_proxy_body(self):
- payload = '0123456789'
- for _ in range(10):
- resp = self.post_http10(body=payload)
+def test_proxy_http10():
+ for _ in range(10):
+ assert get_http10()['status'] == 200, 'status'
- assert resp['status'] == 200, 'status'
- assert resp['body'] == payload, 'body'
- payload = 'X' * 4096
- for _ in range(10):
- resp = self.post_http10(body=payload)
+def test_proxy_chain():
+ assert 'success' in client.conf(
+ {
+ "listeners": {
+ "*:7080": {"pass": "routes/first"},
+ "*:7081": {"pass": "routes/second"},
+ "*:7082": {"pass": "routes/third"},
+ "*:7083": {"pass": "routes/fourth"},
+ "*:7084": {"pass": "routes/fifth"},
+ "*:7085": {"pass": "applications/mirror"},
+ },
+ "routes": {
+ "first": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
+ "second": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
+ "third": [{"action": {"proxy": "http://127.0.0.1:7083"}}],
+ "fourth": [{"action": {"proxy": "http://127.0.0.1:7084"}}],
+ "fifth": [{"action": {"proxy": "http://127.0.0.1:7085"}}],
+ },
+ "applications": {
+ "mirror": {
+ "type": client.get_application_type(),
+ "processes": {"spare": 0},
+ "path": f'{option.test_dir}/python/mirror',
+ "working_directory": f'{option.test_dir}/python/mirror',
+ "module": "wsgi",
+ }
+ },
+ }
+ ), 'proxy chain configuration'
- assert resp['status'] == 200, 'status'
- assert resp['body'] == payload, 'body'
+ assert get_http10()['status'] == 200, 'status'
- payload = 'X' * 4097
- for _ in range(10):
- resp = self.post_http10(body=payload)
- assert resp['status'] == 200, 'status'
- assert resp['body'] == payload, 'body'
+def test_proxy_body():
+ payload = '0123456789'
+ for _ in range(10):
+ resp = post_http10(body=payload)
- payload = 'X' * 4096 * 256
- for _ in range(10):
- resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == payload, 'body'
- assert resp['status'] == 200, 'status'
- assert resp['body'] == payload, 'body'
+ payload = 'X' * 4096
+ for _ in range(10):
+ resp = post_http10(body=payload)
- payload = 'X' * 4096 * 257
- for _ in range(10):
- resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == payload, 'body'
- assert resp['status'] == 200, 'status'
- assert resp['body'] == payload, 'body'
+ payload = 'X' * 4097
+ for _ in range(10):
+ resp = post_http10(body=payload)
- assert 'success' in self.conf(
- {'http': {'max_body_size': 32 * 1024 * 1024}}, 'settings'
- )
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == payload, 'body'
+
+ payload = 'X' * 4096 * 256
+ for _ in range(10):
+ resp = post_http10(body=payload, read_buffer_size=4096 * 128)
- payload = '0123456789abcdef' * 32 * 64 * 1024
- resp = self.post_http10(body=payload, read_buffer_size=1024 * 1024)
assert resp['status'] == 200, 'status'
assert resp['body'] == payload, 'body'
- def test_proxy_parallel(self):
- payload = 'X' * 4096 * 257
- buff_size = 4096 * 258
+ payload = 'X' * 4096 * 257
+ for _ in range(10):
+ resp = post_http10(body=payload, read_buffer_size=4096 * 128)
- socks = []
- for i in range(10):
- sock = self.post_http10(
- body=f'{payload}{i}',
- no_recv=True,
- read_buffer_size=buff_size,
- )
- socks.append(sock)
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == payload, 'body'
- for i in range(10):
- resp = self.recvall(socks[i], buff_size=buff_size).decode()
- socks[i].close()
+ assert 'success' in client.conf(
+ {'http': {'max_body_size': 32 * 1024 * 1024}}, 'settings'
+ )
- resp = self._resp_to_dict(resp)
+ payload = '0123456789abcdef' * 32 * 64 * 1024
+ resp = post_http10(body=payload, read_buffer_size=1024 * 1024)
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == payload, 'body'
- assert resp['status'] == 200, 'status'
- assert resp['body'] == f'{payload}{i}', 'body'
- def test_proxy_header(self):
- assert 'success' in self.conf(
- {"pass": "applications/custom_header"}, 'listeners/*:7081'
- ), 'custom_header configure'
+def test_proxy_parallel():
+ payload = 'X' * 4096 * 257
+ buff_size = 4096 * 258
- header_value = 'blah'
- assert (
- self.get_http10(
- headers={'Host': 'localhost', 'Custom-Header': header_value}
- )['headers']['Custom-Header']
- == header_value
- ), 'custom header'
+ socks = []
+ for i in range(10):
+ sock = post_http10(
+ body=f'{payload}{i}',
+ no_recv=True,
+ read_buffer_size=buff_size,
+ )
+ socks.append(sock)
- header_value = r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~"
- assert (
- self.get_http10(
- headers={'Host': 'localhost', 'Custom-Header': header_value}
- )['headers']['Custom-Header']
- == header_value
- ), 'custom header 2'
+ for i in range(10):
+ resp = client.recvall(socks[i], buff_size=buff_size).decode()
+ socks[i].close()
- header_value = 'X' * 4096
- assert (
- self.get_http10(
- headers={'Host': 'localhost', 'Custom-Header': header_value}
- )['headers']['Custom-Header']
- == header_value
- ), 'custom header 3'
+ resp = client._resp_to_dict(resp)
- header_value = 'X' * 8191
- assert (
- self.get_http10(
- headers={'Host': 'localhost', 'Custom-Header': header_value}
- )['headers']['Custom-Header']
- == header_value
- ), 'custom header 4'
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == f'{payload}{i}', 'body'
- header_value = 'X' * 8192
- assert (
- self.get_http10(
- headers={'Host': 'localhost', 'Custom-Header': header_value}
- )['status']
- == 431
- ), 'custom header 5'
- def test_proxy_fragmented(self):
- sock = self.http(b"""GET / HTT""", raw=True, no_recv=True)
+def test_proxy_header():
+ assert 'success' in client.conf(
+ {"pass": "applications/custom_header"}, 'listeners/*:7081'
+ ), 'custom_header configure'
- time.sleep(1)
+ header_value = 'blah'
+ assert (
+ get_http10(
+ headers={'Host': 'localhost', 'Custom-Header': header_value}
+ )['headers']['Custom-Header']
+ == header_value
+ ), 'custom header'
- sock.sendall("P/1.0\r\nHost: localhos".encode())
+ header_value = r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~"
+ assert (
+ get_http10(
+ headers={'Host': 'localhost', 'Custom-Header': header_value}
+ )['headers']['Custom-Header']
+ == header_value
+ ), 'custom header 2'
- time.sleep(1)
+ header_value = 'X' * 4096
+ assert (
+ get_http10(
+ headers={'Host': 'localhost', 'Custom-Header': header_value}
+ )['headers']['Custom-Header']
+ == header_value
+ ), 'custom header 3'
- sock.sendall("t\r\n\r\n".encode())
+ header_value = 'X' * 8191
+ assert (
+ get_http10(
+ headers={'Host': 'localhost', 'Custom-Header': header_value}
+ )['headers']['Custom-Header']
+ == header_value
+ ), 'custom header 4'
- assert re.search(
- '200 OK', self.recvall(sock).decode()
- ), 'fragmented send'
- sock.close()
+ header_value = 'X' * 8192
+ assert (
+ get_http10(
+ headers={'Host': 'localhost', 'Custom-Header': header_value}
+ )['status']
+ == 431
+ ), 'custom header 5'
- def test_proxy_fragmented_close(self):
- sock = self.http(b"""GET / HTT""", raw=True, no_recv=True)
- time.sleep(1)
+def test_proxy_fragmented():
+ sock = client.http(b"""GET / HTT""", raw=True, no_recv=True)
- sock.sendall("P/1.0\r\nHo".encode())
+ time.sleep(1)
- sock.close()
+ sock.sendall("P/1.0\r\nHost: localhos".encode())
- def test_proxy_fragmented_body(self):
- sock = self.http(b"""GET / HTT""", raw=True, no_recv=True)
+ time.sleep(1)
- time.sleep(1)
+ sock.sendall("t\r\n\r\n".encode())
- sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
- sock.sendall("Content-Length: 30000\r\n".encode())
+ assert re.search('200 OK', client.recvall(sock).decode()), 'fragmented send'
+ sock.close()
- time.sleep(1)
- sock.sendall("\r\n".encode())
- sock.sendall(("X" * 10000).encode())
+def test_proxy_fragmented_close():
+ sock = client.http(b"""GET / HTT""", raw=True, no_recv=True)
- time.sleep(1)
+ time.sleep(1)
- sock.sendall(("X" * 10000).encode())
+ sock.sendall("P/1.0\r\nHo".encode())
- time.sleep(1)
+ sock.close()
- sock.sendall(("X" * 10000).encode())
- resp = self._resp_to_dict(self.recvall(sock).decode())
- sock.close()
+def test_proxy_fragmented_body():
+ sock = client.http(b"""GET / HTT""", raw=True, no_recv=True)
- assert resp['status'] == 200, 'status'
- assert resp['body'] == "X" * 30000, 'body'
+ time.sleep(1)
- def test_proxy_fragmented_body_close(self):
- sock = self.http(b"""GET / HTT""", raw=True, no_recv=True)
+ sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
+ sock.sendall("Content-Length: 30000\r\n".encode())
- time.sleep(1)
+ time.sleep(1)
- sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
- sock.sendall("Content-Length: 30000\r\n".encode())
+ sock.sendall("\r\n".encode())
+ sock.sendall(("X" * 10000).encode())
- time.sleep(1)
+ time.sleep(1)
- sock.sendall("\r\n".encode())
- sock.sendall(("X" * 10000).encode())
+ sock.sendall(("X" * 10000).encode())
- sock.close()
+ time.sleep(1)
- def test_proxy_nowhere(self):
- assert 'success' in self.conf(
- [{"action": {"proxy": "http://127.0.0.1:7082"}}], 'routes'
- ), 'proxy path changed'
+ sock.sendall(("X" * 10000).encode())
- assert self.get_http10()['status'] == 502, 'status'
+ resp = client._resp_to_dict(client.recvall(sock).decode())
+ sock.close()
- def test_proxy_ipv6(self):
- assert 'success' in self.conf(
- {
- "*:7080": {"pass": "routes"},
- "[::1]:7081": {'application': 'mirror'},
- },
- 'listeners',
- ), 'add ipv6 listener configure'
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == "X" * 30000, 'body'
- assert 'success' in self.conf(
- [{"action": {"proxy": "http://[::1]:7081"}}], 'routes'
- ), 'proxy ipv6 configure'
- assert self.get_http10()['status'] == 200, 'status'
+def test_proxy_fragmented_body_close():
+ sock = client.http(b"""GET / HTT""", raw=True, no_recv=True)
- def test_proxy_unix(self, temp_dir):
- addr = f'{temp_dir}/sock'
+ time.sleep(1)
- assert 'success' in self.conf(
- {
- "*:7080": {"pass": "routes"},
- f'unix:{addr}': {'application': 'mirror'},
- },
- 'listeners',
- ), 'add unix listener configure'
-
- assert 'success' in self.conf(
- [{"action": {"proxy": f'http://unix:{addr}'}}], 'routes'
- ), 'proxy unix configure'
-
- assert self.get_http10()['status'] == 200, 'status'
-
- def test_proxy_delayed(self):
- assert 'success' in self.conf(
- {"pass": "applications/delayed"}, 'listeners/*:7081'
- ), 'delayed configure'
-
- body = '0123456789' * 1000
- resp = self.post_http10(
- headers={
- 'Host': 'localhost',
- 'Content-Length': str(len(body)),
- 'X-Parts': '2',
- 'X-Delay': '1',
- },
- body=body,
- )
+ sock.sendall("P/1.0\r\nHost: localhost\r\n".encode())
+ sock.sendall("Content-Length: 30000\r\n".encode())
- assert resp['status'] == 200, 'status'
- assert resp['body'] == body, 'body'
-
- resp = self.post_http10(
- headers={
- 'Host': 'localhost',
- 'Content-Length': str(len(body)),
- 'X-Parts': '2',
- 'X-Delay': '1',
- },
- body=body,
- )
+ time.sleep(1)
- assert resp['status'] == 200, 'status'
- assert resp['body'] == body, 'body'
-
- def test_proxy_delayed_close(self):
- assert 'success' in self.conf(
- {"pass": "applications/delayed"}, 'listeners/*:7081'
- ), 'delayed configure'
-
- sock = self.post_http10(
- headers={
- 'Host': 'localhost',
- 'Content-Length': '10000',
- 'X-Parts': '3',
- 'X-Delay': '1',
- },
- body='0123456789' * 1000,
- no_recv=True,
- )
+ sock.sendall("\r\n".encode())
+ sock.sendall(("X" * 10000).encode())
- assert re.search('200 OK', sock.recv(100).decode()), 'first'
- sock.close()
+ sock.close()
- sock = self.post_http10(
- headers={
- 'Host': 'localhost',
- 'Content-Length': '10000',
- 'X-Parts': '3',
- 'X-Delay': '1',
- },
- body='0123456789' * 1000,
- no_recv=True,
- )
- assert re.search('200 OK', sock.recv(100).decode()), 'second'
- sock.close()
-
- @pytest.mark.skip('not yet')
- def test_proxy_content_length(self):
- assert 'success' in self.conf(
- [{"action": {"proxy": f'http://127.0.0.1:{self.SERVER_PORT}'}}],
- 'routes',
- ), 'proxy backend configure'
-
- resp = self.get_http10()
- assert len(resp['body']) == 0, 'body lt Content-Length 0'
-
- resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '5'})
- assert len(resp['body']) == 5, 'body lt Content-Length 5'
-
- resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '9'})
- assert len(resp['body']) == 9, 'body lt Content-Length 9'
-
- resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '11'})
- assert len(resp['body']) == 10, 'body gt Content-Length 11'
-
- resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '15'})
- assert len(resp['body']) == 10, 'body gt Content-Length 15'
-
- def test_proxy_invalid(self):
- def check_proxy(proxy):
- assert 'error' in self.conf(
- [{"action": {"proxy": proxy}}], 'routes'
- ), 'proxy invalid'
-
- check_proxy('blah')
- check_proxy('/blah')
- check_proxy('unix:/blah')
- check_proxy('http://blah')
- check_proxy('http://127.0.0.1')
- check_proxy('http://127.0.0.1:')
- check_proxy('http://127.0.0.1:blah')
- check_proxy('http://127.0.0.1:-1')
- check_proxy('http://127.0.0.1:7080b')
- check_proxy('http://[]')
- check_proxy('http://[]:7080')
- check_proxy('http://[:]:7080')
- check_proxy('http://[::7080')
-
- @pytest.mark.skip('not yet')
- def test_proxy_loop(self, skip_alert):
- skip_alert(
- r'socket.*failed',
- r'accept.*failed',
- r'new connections are not accepted',
- )
- assert 'success' in self.conf(
- {
- "listeners": {
- "*:7080": {"pass": "routes"},
- "*:7081": {"pass": "applications/mirror"},
- "*:7082": {"pass": "routes"},
- },
- "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
- "applications": {
- "mirror": {
- "type": self.get_application_type(),
- "processes": {"spare": 0},
- "path": f'{option.test_dir}/python/mirror',
- "working_directory": f'{option.test_dir}/python/mirror',
- "module": "wsgi",
- },
+def test_proxy_nowhere():
+ assert 'success' in client.conf(
+ [{"action": {"proxy": "http://127.0.0.1:7082"}}], 'routes'
+ ), 'proxy path changed'
+
+ assert get_http10()['status'] == 502, 'status'
+
+
+def test_proxy_ipv6():
+ assert 'success' in client.conf(
+ {
+ "*:7080": {"pass": "routes"},
+ "[::1]:7081": {'application': 'mirror'},
+ },
+ 'listeners',
+ ), 'add ipv6 listener configure'
+
+ assert 'success' in client.conf(
+ [{"action": {"proxy": "http://[::1]:7081"}}], 'routes'
+ ), 'proxy ipv6 configure'
+
+ assert get_http10()['status'] == 200, 'status'
+
+
+def test_proxy_unix(temp_dir):
+ addr = f'{temp_dir}/sock'
+
+ assert 'success' in client.conf(
+ {
+ "*:7080": {"pass": "routes"},
+ f'unix:{addr}': {'application': 'mirror'},
+ },
+ 'listeners',
+ ), 'add unix listener configure'
+
+ assert 'success' in client.conf(
+ [{"action": {"proxy": f'http://unix:{addr}'}}], 'routes'
+ ), 'proxy unix configure'
+
+ assert get_http10()['status'] == 200, 'status'
+
+
+def test_proxy_delayed():
+ assert 'success' in client.conf(
+ {"pass": "applications/delayed"}, 'listeners/*:7081'
+ ), 'delayed configure'
+
+ body = '0123456789' * 1000
+ resp = post_http10(
+ headers={
+ 'Host': 'localhost',
+ 'Content-Length': str(len(body)),
+ 'X-Parts': '2',
+ 'X-Delay': '1',
+ },
+ body=body,
+ )
+
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == body, 'body'
+
+ resp = post_http10(
+ headers={
+ 'Host': 'localhost',
+ 'Content-Length': str(len(body)),
+ 'X-Parts': '2',
+ 'X-Delay': '1',
+ },
+ body=body,
+ )
+
+ assert resp['status'] == 200, 'status'
+ assert resp['body'] == body, 'body'
+
+
+def test_proxy_delayed_close():
+ assert 'success' in client.conf(
+ {"pass": "applications/delayed"}, 'listeners/*:7081'
+ ), 'delayed configure'
+
+ sock = post_http10(
+ headers={
+ 'Host': 'localhost',
+ 'Content-Length': '10000',
+ 'X-Parts': '3',
+ 'X-Delay': '1',
+ },
+ body='0123456789' * 1000,
+ no_recv=True,
+ )
+
+ assert re.search('200 OK', sock.recv(100).decode()), 'first'
+ sock.close()
+
+ sock = post_http10(
+ headers={
+ 'Host': 'localhost',
+ 'Content-Length': '10000',
+ 'X-Parts': '3',
+ 'X-Delay': '1',
+ },
+ body='0123456789' * 1000,
+ no_recv=True,
+ )
+
+ assert re.search('200 OK', sock.recv(100).decode()), 'second'
+ sock.close()
+
+
+@pytest.mark.skip('not yet')
+def test_proxy_content_length():
+ assert 'success' in client.conf(
+ [{"action": {"proxy": f'http://127.0.0.1:{SERVER_PORT}'}}],
+ 'routes',
+ ), 'proxy backend configure'
+
+ resp = get_http10()
+ assert len(resp['body']) == 0, 'body lt Content-Length 0'
+
+ resp = get_http10(headers={'Host': 'localhost', 'X-Len': '5'})
+ assert len(resp['body']) == 5, 'body lt Content-Length 5'
+
+ resp = get_http10(headers={'Host': 'localhost', 'X-Len': '9'})
+ assert len(resp['body']) == 9, 'body lt Content-Length 9'
+
+ resp = get_http10(headers={'Host': 'localhost', 'X-Len': '11'})
+ assert len(resp['body']) == 10, 'body gt Content-Length 11'
+
+ resp = get_http10(headers={'Host': 'localhost', 'X-Len': '15'})
+ assert len(resp['body']) == 10, 'body gt Content-Length 15'
+
+
+def test_proxy_invalid():
+ def check_proxy(proxy):
+ assert 'error' in client.conf(
+ [{"action": {"proxy": proxy}}], 'routes'
+ ), 'proxy invalid'
+
+ check_proxy('blah')
+ check_proxy('/blah')
+ check_proxy('unix:/blah')
+ check_proxy('http://blah')
+ check_proxy('http://127.0.0.1')
+ check_proxy('http://127.0.0.1:')
+ check_proxy('http://127.0.0.1:blah')
+ check_proxy('http://127.0.0.1:-1')
+ check_proxy('http://127.0.0.1:7080b')
+ check_proxy('http://[]')
+ check_proxy('http://[]:7080')
+ check_proxy('http://[:]:7080')
+ check_proxy('http://[::7080')
+
+
+@pytest.mark.skip('not yet')
+def test_proxy_loop(skip_alert):
+ skip_alert(
+ r'socket.*failed',
+ r'accept.*failed',
+ r'new connections are not accepted',
+ )
+ assert 'success' in client.conf(
+ {
+ "listeners": {
+ "*:7080": {"pass": "routes"},
+ "*:7081": {"pass": "applications/mirror"},
+ "*:7082": {"pass": "routes"},
+ },
+ "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
+ "applications": {
+ "mirror": {
+ "type": client.get_application_type(),
+ "processes": {"spare": 0},
+ "path": f'{option.test_dir}/python/mirror',
+ "working_directory": f'{option.test_dir}/python/mirror',
+ "module": "wsgi",
},
- }
- )
+ },
+ }
+ )
- self.get_http10(no_recv=True)
- self.get_http10(read_timeout=1)
+ get_http10(no_recv=True)
+ get_http10(read_timeout=1)