From d6d764bcc970e1e50486153588eda8a92cf5b5e4 Mon Sep 17 00:00:00 2001 From: Zanie Date: Wed, 20 Dec 2023 20:44:39 -0600 Subject: [PATCH] Avoid closing connections when `HEAD` requests have a content length --- src/waitress/task.py | 15 ++++++++------- tests/test_task.py | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/waitress/task.py b/src/waitress/task.py index 956c0c0f..42cc6581 100644 --- a/src/waitress/task.py +++ b/src/waitress/task.py @@ -474,17 +474,18 @@ def start_response(status, headers, exc_info=None): cl = self.content_length if cl is not None: - if self.content_bytes_written != cl: + if self.content_bytes_written != cl and self.request.command != "HEAD": # close the connection so the client isn't sitting around # waiting for more data when there are too few bytes # to service content-length + # unless it's a HEAD request in which case we don't expect + # to return any bytes regardless of the content length self.close_on_finish = True - if self.request.command != "HEAD": - self.logger.warning( - "application returned too few bytes (%s) " - "for specified Content-Length (%s) via app_iter" - % (self.content_bytes_written, cl), - ) + self.logger.warning( + "application returned too few bytes (%s) " + "for specified Content-Length (%s) via app_iter" + % (self.content_bytes_written, cl), + ) finally: if can_close_app_iter and hasattr(app_iter, "close"): app_iter.close() diff --git a/tests/test_task.py b/tests/test_task.py index 47868e15..c7cb6f68 100644 --- a/tests/test_task.py +++ b/tests/test_task.py @@ -590,7 +590,7 @@ def app(environ, start_response): self.assertEqual(inst.close_on_finish, True) self.assertEqual(len(inst.logger.logged), 1) - def test_execute_app_do_not_warn_on_head(self): + def test_execute_app_head_with_content_length(self): def app(environ, start_response): start_response("200 OK", [("Content-Length", "3")]) return [b""] @@ -600,7 +600,7 @@ def app(environ, start_response): inst.channel.server.application = app inst.logger = DummyLogger() inst.execute() - self.assertEqual(inst.close_on_finish, True) + self.assertEqual(inst.close_on_finish, False) self.assertEqual(len(inst.logger.logged), 0) def test_execute_app_without_body_204_logged(self):