From 430fa1c0a76c9b5bb736baf6a6cec509e2ac987b Mon Sep 17 00:00:00 2001 From: Delta Regeer Date: Sun, 4 Feb 2024 21:30:01 -0700 Subject: [PATCH 1/3] Don't strip value when inserting into WSGI environ --- src/waitress/task.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/waitress/task.py b/src/waitress/task.py index f24fbe00..558aac77 100644 --- a/src/waitress/task.py +++ b/src/waitress/task.py @@ -557,7 +557,6 @@ def get_environment(self): } for key, value in dict(request.headers).items(): - value = value.strip() mykey = rename_headers.get(key, None) if mykey is None: mykey = "HTTP_" + key From b5d1fb5f2d898e12422271a7c6040fcf28955238 Mon Sep 17 00:00:00 2001 From: Delta Regeer Date: Sun, 4 Feb 2024 21:35:03 -0700 Subject: [PATCH 2/3] Add tests to make sure we don't strip non-RFC7230 whitespace from header values --- tests/test_parser.py | 5 +++++ tests/test_task.py | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_parser.py b/tests/test_parser.py index e5f14b48..5fdb04a2 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -384,6 +384,11 @@ def test_parse_header_invalid_chars(self): else: # pragma: nocover self.assertTrue(False) + def test_parse_header_other_whitespace(self): + data = b"GET /foobar HTTP/1.1\r\nfoo: \xa0something\x85\r\n" + self.parser.parse_header(data) + self.assertEqual(self.parser.headers["FOO"], "\xa0something\x85") + def test_parse_header_empty(self): data = b"GET /foobar HTTP/1.1\r\nfoo: bar\r\nempty:\r\n" self.parser.parse_header(data) diff --git a/tests/test_task.py b/tests/test_task.py index c7cb6f68..7fba191f 100644 --- a/tests/test_task.py +++ b/tests/test_task.py @@ -776,7 +776,7 @@ def test_get_environment_values(self): request.headers = { "CONTENT_TYPE": "abc", "CONTENT_LENGTH": "10", - "X_FOO": "BAR", + "X_FOO": "\xa0BAR\x85", "CONNECTION": "close", } request.query = "abc" @@ -830,7 +830,8 @@ def test_get_environment_values(self): self.assertEqual(environ["REMOTE_PORT"], "39830") self.assertEqual(environ["CONTENT_TYPE"], "abc") self.assertEqual(environ["CONTENT_LENGTH"], "10") - self.assertEqual(environ["HTTP_X_FOO"], "BAR") + # Make sure we don't strip non RFC compliant whitespace + self.assertEqual(environ["HTTP_X_FOO"], "\xa0BAR\x85") self.assertEqual(environ["wsgi.version"], (1, 0)) self.assertEqual(environ["wsgi.url_scheme"], "http") self.assertEqual(environ["wsgi.errors"], sys.stderr) From 1697cb9905884d567bd52e8604db487493a16759 Mon Sep 17 00:00:00 2001 From: Delta Regeer Date: Sun, 4 Feb 2024 21:40:11 -0700 Subject: [PATCH 3/3] Update CHANGES.txt and update version --- CHANGES.txt | 7 +++++++ setup.cfg | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index e320b30d..b92e2d98 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,10 @@ +3.0.1 (unreleased) +------------------ + +- No longer strip the header values before passing them to the WSGI environ. + See https://github.com/Pylons/waitress/pull/434 and + https://github.com/Pylons/waitress/issues/432 + 3.0.0 (2024-02-04) ------------------ diff --git a/setup.cfg b/setup.cfg index ed377a93..78f1e6ab 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = waitress -version = 3.0.0 +version = 3.0.1 description = Waitress WSGI server long_description = file: README.rst, CHANGES.txt long_description_content_type = text/x-rst