Skip to content

Instantly share code, notes, and snippets.

@clayg
Created February 6, 2025 20:43
Show Gist options
  • Save clayg/174d8e427c4263230b3cdf6591f3365f to your computer and use it in GitHub Desktop.
Save clayg/174d8e427c4263230b3cdf6591f3365f to your computer and use it in GitHub Desktop.
Test httptools non-ascii header parsing
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 86584c3..74ad0a8 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -16,6 +16,32 @@ Connection: close
'''.replace(b'\n', b'\r\n')
+RESPONSE1_HEAD_NON_ASCII_KEY = b'''HTTP/1.1 200 OK
+Date: Mon, 23 May 2005 22:38:34 GMT
+Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
+Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
+ETag: "3f80f-1b6-3e1cb03b"
+Content-Type: text/html; charset=UTF-8
+Content-Length: 130
+Accept-Ranges: bytes
+X-M\xe9tadata: some-value
+Connection: close
+
+'''.replace(b'\n', b'\r\n')
+
+RESPONSE1_HEAD_NON_ASCII_VAL = b'''HTTP/1.1 200 OK
+Date: Mon, 23 May 2005 22:38:34 GMT
+Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
+Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
+ETag: "3f80f-1b6-3e1cb03b"
+Content-Type: text/html; charset=UTF-8
+Content-Length: 130
+Accept-Ranges: bytes
+X-Meadata: som\xe9-value
+Connection: close
+
+'''.replace(b'\n', b'\r\n')
+
RESPONSE1_SPACES_IN_HEAD = b'''HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7
@@ -121,6 +147,42 @@ class TestResponseParser(unittest.TestCase):
'Expected HTTP/'):
p.feed_data(b'12123123')
+ def test_parser_response_non_ascii(self):
+ m = mock.Mock()
+
+ headers = {}
+ m.on_header.side_effect = headers.__setitem__
+ p = httptools.HttpResponseParser(m)
+
+ # no non-ascii header keys
+ with self.assertRaisesRegex(
+ httptools.HttpParserError,
+ "Invalid header token",
+ ):
+ p.feed_data(memoryview(RESPONSE1_HEAD_NON_ASCII_KEY))
+
+ # no non-ascii header values
+ with self.assertRaisesRegex(
+ httptools.HttpParserError,
+ "Invalid header token",
+ ):
+ p.feed_data(memoryview(RESPONSE1_HEAD_NON_ASCII_VAL))
+
+ # dangerous leniencies doesn't help
+ p.set_dangerous_leniencies(lenient_headers=True)
+
+ with self.assertRaisesRegex(
+ httptools.HttpParserError,
+ "Invalid header token",
+ ):
+ p.feed_data(memoryview(RESPONSE1_HEAD_NON_ASCII_KEY))
+
+ with self.assertRaisesRegex(
+ httptools.HttpParserError,
+ "Invalid header token",
+ ):
+ p.feed_data(memoryview(RESPONSE1_HEAD_NON_ASCII_VAL))
+
def test_parser_response_leninent_headers_1(self):
m = mock.Mock()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment