summaryrefslogtreecommitdiffhomepage
path: root/test/test_http_header.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_http_header.py')
-rw-r--r--test/test_http_header.py840
1 files changed, 436 insertions, 404 deletions
diff --git a/test/test_http_header.py b/test/test_http_header.py
index 3202ae9c..af836e6f 100644
--- a/test/test_http_header.py
+++ b/test/test_http_header.py
@@ -1,468 +1,500 @@
import pytest
-from unit.applications.lang.python import TestApplicationPython
+from unit.applications.lang.python import ApplicationPython
prerequisites = {'modules': {'python': 'any'}}
+client = ApplicationPython()
-class TestHTTPHeader(TestApplicationPython):
- def test_http_header_value_leading_sp(self):
- self.load('custom_header')
- resp = self.get(
+def test_http_header_value_leading_sp():
+ client.load('custom_header')
+
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ 'Custom-Header': ' ,',
+ 'Connection': 'close',
+ }
+ )
+
+ assert resp['status'] == 200, 'value leading sp status'
+ assert (
+ resp['headers']['Custom-Header'] == ','
+ ), 'value leading sp custom header'
+
+
+def test_http_header_value_leading_htab():
+ client.load('custom_header')
+
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ 'Custom-Header': '\t,',
+ 'Connection': 'close',
+ }
+ )
+
+ assert resp['status'] == 200, 'value leading htab status'
+ assert (
+ resp['headers']['Custom-Header'] == ','
+ ), 'value leading htab custom header'
+
+
+def test_http_header_value_trailing_sp():
+ client.load('custom_header')
+
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ 'Custom-Header': ', ',
+ 'Connection': 'close',
+ }
+ )
+
+ assert resp['status'] == 200, 'value trailing sp status'
+ assert (
+ resp['headers']['Custom-Header'] == ','
+ ), 'value trailing sp custom header'
+
+
+def test_http_header_value_trailing_htab():
+ client.load('custom_header')
+
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ 'Custom-Header': ',\t',
+ 'Connection': 'close',
+ }
+ )
+
+ assert resp['status'] == 200, 'value trailing htab status'
+ assert (
+ resp['headers']['Custom-Header'] == ','
+ ), 'value trailing htab custom header'
+
+
+def test_http_header_value_both_sp():
+ client.load('custom_header')
+
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ 'Custom-Header': ' , ',
+ 'Connection': 'close',
+ }
+ )
+
+ assert resp['status'] == 200, 'value both sp status'
+ assert (
+ resp['headers']['Custom-Header'] == ','
+ ), 'value both sp custom header'
+
+
+def test_http_header_value_both_htab():
+ client.load('custom_header')
+
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ 'Custom-Header': '\t,\t',
+ 'Connection': 'close',
+ }
+ )
+
+ assert resp['status'] == 200, 'value both htab status'
+ assert (
+ resp['headers']['Custom-Header'] == ','
+ ), 'value both htab custom header'
+
+
+def test_http_header_value_chars():
+ client.load('custom_header')
+
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ 'Custom-Header': r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~",
+ 'Connection': 'close',
+ }
+ )
+
+ assert resp['status'] == 200, 'value chars status'
+ assert (
+ resp['headers']['Custom-Header']
+ == r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~"
+ ), 'value chars custom header'
+
+
+def test_http_header_value_chars_edge():
+ client.load('custom_header')
+
+ resp = client.http(
+ b"""GET / HTTP/1.1
+Host: localhost
+Custom-Header: \x20\xFF
+Connection: close
+
+""",
+ raw=True,
+ encoding='latin1',
+ )
+
+ assert resp['status'] == 200, 'value chars edge status'
+ assert resp['headers']['Custom-Header'] == '\xFF', 'value chars edge'
+
+
+def test_http_header_value_chars_below():
+ client.load('custom_header')
+
+ resp = client.http(
+ b"""GET / HTTP/1.1
+Host: localhost
+Custom-Header: \x1F
+Connection: close
+
+""",
+ raw=True,
+ )
+
+ assert resp['status'] == 400, 'value chars below'
+
+
+def test_http_header_field_leading_sp():
+ client.load('empty')
+
+ assert (
+ client.get(
headers={
'Host': 'localhost',
- 'Custom-Header': ' ,',
+ ' Custom-Header': 'blah',
'Connection': 'close',
}
- )
+ )['status']
+ == 400
+ ), 'field leading sp'
- assert resp['status'] == 200, 'value leading sp status'
- assert (
- resp['headers']['Custom-Header'] == ','
- ), 'value leading sp custom header'
- def test_http_header_value_leading_htab(self):
- self.load('custom_header')
+def test_http_header_field_leading_htab():
+ client.load('empty')
- resp = self.get(
+ assert (
+ client.get(
headers={
'Host': 'localhost',
- 'Custom-Header': '\t,',
+ '\tCustom-Header': 'blah',
'Connection': 'close',
}
- )
+ )['status']
+ == 400
+ ), 'field leading htab'
- assert resp['status'] == 200, 'value leading htab status'
- assert (
- resp['headers']['Custom-Header'] == ','
- ), 'value leading htab custom header'
- def test_http_header_value_trailing_sp(self):
- self.load('custom_header')
+def test_http_header_field_trailing_sp():
+ client.load('empty')
- resp = self.get(
+ assert (
+ client.get(
headers={
'Host': 'localhost',
- 'Custom-Header': ', ',
+ 'Custom-Header ': 'blah',
'Connection': 'close',
}
- )
+ )['status']
+ == 400
+ ), 'field trailing sp'
- assert resp['status'] == 200, 'value trailing sp status'
- assert (
- resp['headers']['Custom-Header'] == ','
- ), 'value trailing sp custom header'
- def test_http_header_value_trailing_htab(self):
- self.load('custom_header')
+def test_http_header_field_trailing_htab():
+ client.load('empty')
- resp = self.get(
+ assert (
+ client.get(
headers={
'Host': 'localhost',
- 'Custom-Header': ',\t',
+ 'Custom-Header\t': 'blah',
'Connection': 'close',
}
- )
+ )['status']
+ == 400
+ ), 'field trailing htab'
- assert resp['status'] == 200, 'value trailing htab status'
- assert (
- resp['headers']['Custom-Header'] == ','
- ), 'value trailing htab custom header'
- def test_http_header_value_both_sp(self):
- self.load('custom_header')
+def test_http_header_content_length_big():
+ client.load('empty')
- resp = self.get(
+ assert (
+ client.post(
headers={
'Host': 'localhost',
- 'Custom-Header': ' , ',
+ 'Content-Length': str(2**64),
'Connection': 'close',
- }
- )
+ },
+ body='X' * 1000,
+ )['status']
+ == 400
+ ), 'Content-Length big'
- assert resp['status'] == 200, 'value both sp status'
- assert (
- resp['headers']['Custom-Header'] == ','
- ), 'value both sp custom header'
- def test_http_header_value_both_htab(self):
- self.load('custom_header')
+def test_http_header_content_length_negative():
+ client.load('empty')
- resp = self.get(
+ assert (
+ client.post(
headers={
'Host': 'localhost',
- 'Custom-Header': '\t,\t',
+ 'Content-Length': '-100',
'Connection': 'close',
- }
- )
+ },
+ body='X' * 1000,
+ )['status']
+ == 400
+ ), 'Content-Length negative'
- assert resp['status'] == 200, 'value both htab status'
- assert (
- resp['headers']['Custom-Header'] == ','
- ), 'value both htab custom header'
- def test_http_header_value_chars(self):
- self.load('custom_header')
+def test_http_header_content_length_text():
+ client.load('empty')
- resp = self.get(
+ assert (
+ client.post(
headers={
'Host': 'localhost',
- 'Custom-Header': r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~",
+ 'Content-Length': 'blah',
'Connection': 'close',
- }
- )
+ },
+ body='X' * 1000,
+ )['status']
+ == 400
+ ), 'Content-Length text'
- assert resp['status'] == 200, 'value chars status'
- assert (
- resp['headers']['Custom-Header']
- == r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~"
- ), 'value chars custom header'
- def test_http_header_value_chars_edge(self):
- self.load('custom_header')
+def test_http_header_content_length_multiple_values():
+ client.load('empty')
- resp = self.http(
- b"""GET / HTTP/1.1
-Host: localhost
-Custom-Header: \x20\xFF
-Connection: close
+ assert (
+ client.post(
+ headers={
+ 'Host': 'localhost',
+ 'Content-Length': '41, 42',
+ 'Connection': 'close',
+ },
+ body='X' * 1000,
+ )['status']
+ == 400
+ ), 'Content-Length multiple value'
-""",
- raw=True,
- encoding='latin1',
- )
- assert resp['status'] == 200, 'value chars edge status'
- assert resp['headers']['Custom-Header'] == '\xFF', 'value chars edge'
+def test_http_header_content_length_multiple_fields():
+ client.load('empty')
- def test_http_header_value_chars_below(self):
- self.load('custom_header')
+ assert (
+ client.post(
+ headers={
+ 'Host': 'localhost',
+ 'Content-Length': ['41', '42'],
+ 'Connection': 'close',
+ },
+ body='X' * 1000,
+ )['status']
+ == 400
+ ), 'Content-Length multiple fields'
- resp = self.http(
- b"""GET / HTTP/1.1
-Host: localhost
-Custom-Header: \x1F
-Connection: close
-""",
- raw=True,
- )
+@pytest.mark.skip('not yet')
+def test_http_header_host_absent():
+ client.load('host')
- assert resp['status'] == 400, 'value chars below'
-
- def test_http_header_field_leading_sp(self):
- self.load('empty')
-
- assert (
- self.get(
- headers={
- 'Host': 'localhost',
- ' Custom-Header': 'blah',
- 'Connection': 'close',
- }
- )['status']
- == 400
- ), 'field leading sp'
-
- def test_http_header_field_leading_htab(self):
- self.load('empty')
-
- assert (
- self.get(
- headers={
- 'Host': 'localhost',
- '\tCustom-Header': 'blah',
- 'Connection': 'close',
- }
- )['status']
- == 400
- ), 'field leading htab'
-
- def test_http_header_field_trailing_sp(self):
- self.load('empty')
-
- assert (
- self.get(
- headers={
- 'Host': 'localhost',
- 'Custom-Header ': 'blah',
- 'Connection': 'close',
- }
- )['status']
- == 400
- ), 'field trailing sp'
-
- def test_http_header_field_trailing_htab(self):
- self.load('empty')
-
- assert (
- self.get(
- headers={
- 'Host': 'localhost',
- 'Custom-Header\t': 'blah',
- 'Connection': 'close',
- }
- )['status']
- == 400
- ), 'field trailing htab'
-
- def test_http_header_content_length_big(self):
- self.load('empty')
-
- assert (
- self.post(
- headers={
- 'Host': 'localhost',
- 'Content-Length': str(2**64),
- 'Connection': 'close',
- },
- body='X' * 1000,
- )['status']
- == 400
- ), 'Content-Length big'
-
- def test_http_header_content_length_negative(self):
- self.load('empty')
-
- assert (
- self.post(
- headers={
- 'Host': 'localhost',
- 'Content-Length': '-100',
- 'Connection': 'close',
- },
- body='X' * 1000,
- )['status']
- == 400
- ), 'Content-Length negative'
-
- def test_http_header_content_length_text(self):
- self.load('empty')
-
- assert (
- self.post(
- headers={
- 'Host': 'localhost',
- 'Content-Length': 'blah',
- 'Connection': 'close',
- },
- body='X' * 1000,
- )['status']
- == 400
- ), 'Content-Length text'
-
- def test_http_header_content_length_multiple_values(self):
- self.load('empty')
-
- assert (
- self.post(
- headers={
- 'Host': 'localhost',
- 'Content-Length': '41, 42',
- 'Connection': 'close',
- },
- body='X' * 1000,
- )['status']
- == 400
- ), 'Content-Length multiple value'
-
- def test_http_header_content_length_multiple_fields(self):
- self.load('empty')
-
- assert (
- self.post(
- headers={
- 'Host': 'localhost',
- 'Content-Length': ['41', '42'],
- 'Connection': 'close',
- },
- body='X' * 1000,
- )['status']
- == 400
- ), 'Content-Length multiple fields'
-
- @pytest.mark.skip('not yet')
- def test_http_header_host_absent(self):
- self.load('host')
-
- resp = self.get(headers={'Connection': 'close'})
-
- assert resp['status'] == 400, 'Host absent status'
-
- def test_http_header_host_empty(self):
- self.load('host')
-
- resp = self.get(headers={'Host': '', 'Connection': 'close'})
-
- assert resp['status'] == 200, 'Host empty status'
- assert resp['headers']['X-Server-Name'] != '', 'Host empty SERVER_NAME'
-
- def test_http_header_host_big(self):
- self.load('empty')
-
- assert (
- self.get(headers={'Host': 'X' * 10000, 'Connection': 'close'})[
- 'status'
- ]
- == 431
- ), 'Host big'
-
- def test_http_header_host_port(self):
- self.load('host')
-
- resp = self.get(
- headers={'Host': 'exmaple.com:7080', 'Connection': 'close'}
- )
+ resp = client.get(headers={'Connection': 'close'})
+
+ assert resp['status'] == 400, 'Host absent status'
+
+
+def test_http_header_host_empty():
+ client.load('host')
+
+ resp = client.get(headers={'Host': '', 'Connection': 'close'})
+
+ assert resp['status'] == 200, 'Host empty status'
+ assert resp['headers']['X-Server-Name'] != '', 'Host empty SERVER_NAME'
+
+
+def test_http_header_host_big():
+ client.load('empty')
+
+ assert (
+ client.get(headers={'Host': 'X' * 10000, 'Connection': 'close'})[
+ 'status'
+ ]
+ == 431
+ ), 'Host big'
+
+
+def test_http_header_host_port():
+ client.load('host')
+
+ resp = client.get(
+ headers={'Host': 'exmaple.com:7080', 'Connection': 'close'}
+ )
+
+ assert resp['status'] == 200, 'Host port status'
+ assert (
+ resp['headers']['X-Server-Name'] == 'exmaple.com'
+ ), 'Host port SERVER_NAME'
+ assert (
+ resp['headers']['X-Http-Host'] == 'exmaple.com:7080'
+ ), 'Host port HTTP_HOST'
+
+
+def test_http_header_host_port_empty():
+ client.load('host')
+
+ resp = client.get(headers={'Host': 'exmaple.com:', 'Connection': 'close'})
+
+ assert resp['status'] == 200, 'Host port empty status'
+ assert (
+ resp['headers']['X-Server-Name'] == 'exmaple.com'
+ ), 'Host port empty SERVER_NAME'
+ assert (
+ resp['headers']['X-Http-Host'] == 'exmaple.com:'
+ ), 'Host port empty HTTP_HOST'
+
+
+def test_http_header_host_literal():
+ client.load('host')
+
+ resp = client.get(headers={'Host': '127.0.0.1', 'Connection': 'close'})
+
+ assert resp['status'] == 200, 'Host literal status'
+ assert (
+ resp['headers']['X-Server-Name'] == '127.0.0.1'
+ ), 'Host literal SERVER_NAME'
+
+
+def test_http_header_host_literal_ipv6():
+ client.load('host')
+
+ resp = client.get(headers={'Host': '[::1]:7080', 'Connection': 'close'})
+
+ assert resp['status'] == 200, 'Host literal ipv6 status'
+ assert (
+ resp['headers']['X-Server-Name'] == '[::1]'
+ ), 'Host literal ipv6 SERVER_NAME'
+ assert (
+ resp['headers']['X-Http-Host'] == '[::1]:7080'
+ ), 'Host literal ipv6 HTTP_HOST'
+
+
+def test_http_header_host_trailing_period():
+ client.load('host')
+
+ resp = client.get(headers={'Host': '127.0.0.1.', 'Connection': 'close'})
+
+ assert resp['status'] == 200, 'Host trailing period status'
+ assert (
+ resp['headers']['X-Server-Name'] == '127.0.0.1'
+ ), 'Host trailing period SERVER_NAME'
+ assert (
+ resp['headers']['X-Http-Host'] == '127.0.0.1.'
+ ), 'Host trailing period HTTP_HOST'
- assert resp['status'] == 200, 'Host port status'
- assert (
- resp['headers']['X-Server-Name'] == 'exmaple.com'
- ), 'Host port SERVER_NAME'
- assert (
- resp['headers']['X-Http-Host'] == 'exmaple.com:7080'
- ), 'Host port HTTP_HOST'
-
- def test_http_header_host_port_empty(self):
- self.load('host')
-
- resp = self.get(headers={'Host': 'exmaple.com:', 'Connection': 'close'})
-
- assert resp['status'] == 200, 'Host port empty status'
- assert (
- resp['headers']['X-Server-Name'] == 'exmaple.com'
- ), 'Host port empty SERVER_NAME'
- assert (
- resp['headers']['X-Http-Host'] == 'exmaple.com:'
- ), 'Host port empty HTTP_HOST'
-
- def test_http_header_host_literal(self):
- self.load('host')
-
- resp = self.get(headers={'Host': '127.0.0.1', 'Connection': 'close'})
-
- assert resp['status'] == 200, 'Host literal status'
- assert (
- resp['headers']['X-Server-Name'] == '127.0.0.1'
- ), 'Host literal SERVER_NAME'
-
- def test_http_header_host_literal_ipv6(self):
- self.load('host')
-
- resp = self.get(headers={'Host': '[::1]:7080', 'Connection': 'close'})
-
- assert resp['status'] == 200, 'Host literal ipv6 status'
- assert (
- resp['headers']['X-Server-Name'] == '[::1]'
- ), 'Host literal ipv6 SERVER_NAME'
- assert (
- resp['headers']['X-Http-Host'] == '[::1]:7080'
- ), 'Host literal ipv6 HTTP_HOST'
-
- def test_http_header_host_trailing_period(self):
- self.load('host')
-
- resp = self.get(headers={'Host': '127.0.0.1.', 'Connection': 'close'})
-
- assert resp['status'] == 200, 'Host trailing period status'
- assert (
- resp['headers']['X-Server-Name'] == '127.0.0.1'
- ), 'Host trailing period SERVER_NAME'
- assert (
- resp['headers']['X-Http-Host'] == '127.0.0.1.'
- ), 'Host trailing period HTTP_HOST'
-
- def test_http_header_host_trailing_period_2(self):
- self.load('host')
-
- resp = self.get(headers={'Host': 'EXAMPLE.COM.', 'Connection': 'close'})
-
- assert resp['status'] == 200, 'Host trailing period 2 status'
- assert (
- resp['headers']['X-Server-Name'] == 'example.com'
- ), 'Host trailing period 2 SERVER_NAME'
- assert (
- resp['headers']['X-Http-Host'] == 'EXAMPLE.COM.'
- ), 'Host trailing period 2 HTTP_HOST'
-
- def test_http_header_host_case_insensitive(self):
- self.load('host')
-
- resp = self.get(headers={'Host': 'EXAMPLE.COM', 'Connection': 'close'})
-
- assert resp['status'] == 200, 'Host case insensitive'
- assert (
- resp['headers']['X-Server-Name'] == 'example.com'
- ), 'Host case insensitive SERVER_NAME'
-
- def test_http_header_host_double_dot(self):
- self.load('empty')
-
- assert (
- self.get(headers={'Host': '127.0.0..1', 'Connection': 'close'})[
- 'status'
- ]
- == 400
- ), 'Host double dot'
-
- def test_http_header_host_slash(self):
- self.load('empty')
-
- assert (
- self.get(headers={'Host': '/localhost', 'Connection': 'close'})[
- 'status'
- ]
- == 400
- ), 'Host slash'
-
- def test_http_header_host_multiple_fields(self):
- self.load('empty')
-
- assert (
- self.get(
- headers={
- 'Host': ['localhost', 'example.com'],
- 'Connection': 'close',
- }
- )['status']
- == 400
- ), 'Host multiple fields'
-
- def test_http_discard_unsafe_fields(self):
- self.load('header_fields')
-
- def check_status(header):
- resp = self.get(
- headers={
- 'Host': 'localhost',
- header: 'blah',
- 'Connection': 'close',
- }
- )
-
- assert resp['status'] == 200
- return resp
-
- resp = check_status("!Custom-Header")
- assert 'CUSTOM' not in resp['headers']['All-Headers']
-
- resp = check_status("Custom_Header")
- assert 'CUSTOM' not in resp['headers']['All-Headers']
-
- assert 'success' in self.conf(
- {'http': {'discard_unsafe_fields': False}},
- 'settings',
- )
- resp = check_status("!#$%&'*+.^`|~Custom_Header")
- assert 'CUSTOM' in resp['headers']['All-Headers']
+def test_http_header_host_trailing_period_2():
+ client.load('host')
- assert 'success' in self.conf(
- {'http': {'discard_unsafe_fields': True}},
- 'settings',
+ resp = client.get(headers={'Host': 'EXAMPLE.COM.', 'Connection': 'close'})
+
+ assert resp['status'] == 200, 'Host trailing period 2 status'
+ assert (
+ resp['headers']['X-Server-Name'] == 'example.com'
+ ), 'Host trailing period 2 SERVER_NAME'
+ assert (
+ resp['headers']['X-Http-Host'] == 'EXAMPLE.COM.'
+ ), 'Host trailing period 2 HTTP_HOST'
+
+
+def test_http_header_host_case_insensitive():
+ client.load('host')
+
+ resp = client.get(headers={'Host': 'EXAMPLE.COM', 'Connection': 'close'})
+
+ assert resp['status'] == 200, 'Host case insensitive'
+ assert (
+ resp['headers']['X-Server-Name'] == 'example.com'
+ ), 'Host case insensitive SERVER_NAME'
+
+
+def test_http_header_host_double_dot():
+ client.load('empty')
+
+ assert (
+ client.get(headers={'Host': '127.0.0..1', 'Connection': 'close'})[
+ 'status'
+ ]
+ == 400
+ ), 'Host double dot'
+
+
+def test_http_header_host_slash():
+ client.load('empty')
+
+ assert (
+ client.get(headers={'Host': '/localhost', 'Connection': 'close'})[
+ 'status'
+ ]
+ == 400
+ ), 'Host slash'
+
+
+def test_http_header_host_multiple_fields():
+ client.load('empty')
+
+ assert (
+ client.get(
+ headers={
+ 'Host': ['localhost', 'example.com'],
+ 'Connection': 'close',
+ }
+ )['status']
+ == 400
+ ), 'Host multiple fields'
+
+
+def test_http_discard_unsafe_fields():
+ client.load('header_fields')
+
+ def check_status(header):
+ resp = client.get(
+ headers={
+ 'Host': 'localhost',
+ header: 'blah',
+ 'Connection': 'close',
+ }
)
- resp = check_status("!Custom-Header")
- assert 'CUSTOM' not in resp['headers']['All-Headers']
+ assert resp['status'] == 200
+ return resp
+
+ resp = check_status("!Custom-Header")
+ assert 'CUSTOM' not in resp['headers']['All-Headers']
+
+ resp = check_status("Custom_Header")
+ assert 'CUSTOM' not in resp['headers']['All-Headers']
+
+ assert 'success' in client.conf(
+ {'http': {'discard_unsafe_fields': False}},
+ 'settings',
+ )
+
+ resp = check_status("!#$%&'*+.^`|~Custom_Header")
+ assert 'CUSTOM' in resp['headers']['All-Headers']
+
+ assert 'success' in client.conf(
+ {'http': {'discard_unsafe_fields': True}},
+ 'settings',
+ )
+
+ resp = check_status("!Custom-Header")
+ assert 'CUSTOM' not in resp['headers']['All-Headers']
- resp = check_status("Custom_Header")
- assert 'CUSTOM' not in resp['headers']['All-Headers']
+ resp = check_status("Custom_Header")
+ assert 'CUSTOM' not in resp['headers']['All-Headers']