Skip to content

Commit c7e921c

Browse files
Tests: chunked request body
1 parent c88265a commit c7e921c

File tree

2 files changed

+189
-1
lines changed

2 files changed

+189
-1
lines changed

test/test_chunked.py

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import re
2+
3+
import pytest
4+
from unit.applications.lang.python import ApplicationPython
5+
6+
prerequisites = {'modules': {'python': 'any'}}
7+
8+
client = ApplicationPython()
9+
10+
11+
@pytest.fixture(autouse=True)
12+
def setup_method_fixture():
13+
client.load('mirror')
14+
15+
assert 'success' in client.conf(
16+
{"http": {"chunked_transform": True}}, 'settings'
17+
)
18+
19+
20+
def test_chunked():
21+
def chunks(chunks=[]):
22+
body = ''
23+
24+
for c in chunks:
25+
body = f'{body}{len(c):x}\r\n{c}\r\n'
26+
27+
resp = client.get(
28+
headers={
29+
'Host': 'localhost',
30+
'Connection': 'close',
31+
'Transfer-Encoding': 'chunked',
32+
},
33+
body=f'{body}0\r\n\r\n',
34+
)
35+
36+
expect_body = ''.join(chunks)
37+
38+
assert resp['status'] == 200
39+
assert resp['headers']['Content-Length'] == str(len(expect_body))
40+
assert resp['body'] == expect_body
41+
42+
chunks()
43+
chunks(['1'])
44+
chunks(['0123456789'])
45+
chunks(['0123456789' * 128])
46+
chunks(['0123456789' * 512])
47+
chunks(['0123456789' * 128, '1', '1', '0123456789' * 128, '1'])
48+
49+
50+
def test_chunked_pipeline():
51+
sock = client.get(
52+
no_recv=True,
53+
headers={
54+
'Host': 'localhost',
55+
'Transfer-Encoding': 'chunked',
56+
},
57+
body='1\r\n$\r\n0\r\n\r\n',
58+
)
59+
60+
resp = client.get(
61+
sock=sock,
62+
headers={
63+
'Host': 'localhost',
64+
'Transfer-Encoding': 'chunked',
65+
'Connection': 'close',
66+
},
67+
body='1\r\n%\r\n0\r\n\r\n',
68+
raw_resp=True,
69+
)
70+
71+
assert len(re.findall('200 OK', resp)) == 2
72+
assert len(re.findall('Content-Length: 1', resp)) == 2
73+
assert len(re.findall('$', resp)) == 1
74+
assert len(re.findall('%', resp)) == 1
75+
76+
77+
def test_chunked_max_body_size():
78+
assert 'success' in client.conf(
79+
{'max_body_size': 1024, 'chunked_transform': True}, 'settings/http'
80+
)
81+
82+
body = f'{2048:x}\r\n{"x" * 2048}\r\n0\r\n\r\n'
83+
84+
assert (
85+
client.get(
86+
headers={
87+
'Host': 'localhost',
88+
'Connection': 'close',
89+
'Transfer-Encoding': 'chunked',
90+
},
91+
body=body,
92+
)['status']
93+
== 413
94+
)
95+
96+
97+
def test_chunked_after_last():
98+
resp = client.get(
99+
headers={
100+
'Host': 'localhost',
101+
'Connection': 'close',
102+
'Transfer-Encoding': 'chunked',
103+
},
104+
body='1\r\na\r\n0\r\n\r\n1\r\nb\r\n0\r\n\r\n',
105+
)
106+
107+
assert resp['status'] == 200
108+
assert resp['headers']['Content-Length'] == '1'
109+
assert resp['body'] == 'a'
110+
111+
112+
def test_chunked_transform():
113+
assert 'success' in client.conf(
114+
{"http": {"chunked_transform": False}}, 'settings'
115+
)
116+
117+
assert (
118+
client.get(
119+
headers={
120+
'Host': 'localhost',
121+
'Connection': 'close',
122+
'Transfer-Encoding': 'chunked',
123+
},
124+
body='0\r\n\r\n',
125+
)['status']
126+
== 411
127+
)
128+
129+
130+
def test_chunked_invalid():
131+
# invalid chunkes
132+
133+
def check_body(body):
134+
assert (
135+
client.get(
136+
headers={
137+
'Host': 'localhost',
138+
'Connection': 'close',
139+
'Transfer-Encoding': 'chunked',
140+
},
141+
body=body,
142+
)['status']
143+
== 400
144+
)
145+
146+
check_body('1\r\nblah\r\n0\r\n\r\n')
147+
check_body('1\r\n\r\n1\r\n0\r\n\r\n')
148+
check_body('1\r\n1\r\n\r\n0\r\n\r\n')
149+
150+
# invalid transfer encoding header
151+
152+
assert (
153+
client.get(
154+
headers={
155+
'Host': 'localhost',
156+
'Connection': 'close',
157+
'Transfer-Encoding': ['chunked', 'chunked'],
158+
},
159+
body='0\r\n\r\n',
160+
)['status']
161+
== 400
162+
), 'two Transfer-Encoding headers'
163+
164+
assert (
165+
client.get(
166+
headers={
167+
'Host': 'localhost',
168+
'Connection': 'close',
169+
'Transfer-Encoding': 'chunked',
170+
'Content-Length': '5',
171+
},
172+
body='0\r\n\r\n',
173+
)['status']
174+
== 400
175+
), 'Transfer-Encoding and Content-Length'
176+
177+
assert (
178+
client.get(
179+
http_10=True,
180+
headers={
181+
'Host': 'localhost',
182+
'Connection': 'close',
183+
'Transfer-Encoding': 'chunked',
184+
},
185+
body='0\r\n\r\n',
186+
)['status']
187+
== 400
188+
), 'Transfer-Encoding HTTP/1.0'

test/unit/http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def http(self, start_str, **kwargs):
6767

6868
headers['Content-Type'] = content_type
6969

70-
if 'Content-Length' not in headers:
70+
if 'Content-Length' not in headers and 'Transfer-Encoding' not in headers:
7171
headers['Content-Length'] = len(body)
7272

7373
for header, value in headers.items():

0 commit comments

Comments
 (0)