Skip to content

Commit 4c8d68e

Browse files
authored
Merge pull request #475 from Pylons/bugfix/close-connection-chunked-cl
When Transfer-Encoding is set, and Content-Length, close connection
2 parents 1a66990 + 886793e commit 4c8d68e

3 files changed

Lines changed: 26 additions & 0 deletions

File tree

CHANGES.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
Unreleased
2+
----------
3+
4+
Bugfix
5+
~~~~~~
6+
7+
- When encountering a request that has both Content-Length set and
8+
Transfer-Encoding of chunked we now close the connection after it is
9+
completed to comply with the requirements of RFC9112. See
10+
https://github.com/Pylons/waitress/pull/475 and
11+
https://github.com/Pylons/waitress/issues/464
12+
113
3.0.2 (2024-11-16)
214
------------------
315

src/waitress/parser.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,13 @@ def parse_header(self, header_plus):
307307
self.chunked = True
308308
buf = OverflowableBuffer(self.adj.inbuf_overflow)
309309
self.body_rcv = ChunkedReceiver(buf)
310+
311+
# RFC9112 states that we need to close the connection if the
312+
# Transfer-Encoding is set, AND a Content-Length is provided.
313+
cl = headers.pop("CONTENT_LENGTH", None)
314+
if cl is not None:
315+
self.connection_close = True
316+
310317
elif encodings: # pragma: nocover
311318
raise TransferEncodingNotImplemented(
312319
"Transfer-Encoding requested is not supported."

tests/test_parser.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ def test_parse_header_11_te_chunked(self):
236236
self.parser.parse_header(data)
237237
self.assertEqual(self.parser.body_rcv.__class__.__name__, "ChunkedReceiver")
238238

239+
def test_parse_header_11_te_chunked_with_cl_close_connection(self):
240+
# NB: test that capitalization of header value is unimportant
241+
data = b"GET /foobar HTTP/1.1\r\ntransfer-encoding: chunked\r\ncontent-length: 10\r\n"
242+
self.parser.parse_header(data)
243+
self.assertEqual(self.parser.body_rcv.__class__.__name__, "ChunkedReceiver")
244+
self.assertEqual(self.parser.connection_close, True)
245+
239246
def test_parse_header_transfer_encoding_invalid(self):
240247
data = b"GET /foobar HTTP/1.1\r\ntransfer-encoding: gzip\r\n"
241248

0 commit comments

Comments
 (0)