From f00ef9fb498d52072b31141d894cce3fc4cfbdff Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 2 Dec 2025 10:54:15 +0200 Subject: [PATCH 1/2] [3.14] Try to fix the fix for gh-119452 --- Lib/http/server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/http/server.py b/Lib/http/server.py index 226ca3b16ccbeb..3346a14bc1df5a 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -1288,16 +1288,16 @@ def run_cgi(self): env = env ) if self.command.lower() == "post" and nbytes > 0: - cursize = 0 - data = self.rfile.read(min(nbytes, _MIN_READ_BUF_SIZE)) - while (len(data) < nbytes and len(data) != cursize and + cursize = min(nbytes, _MIN_READ_BUF_SIZE) + data = self.rfile.read(cursize) + while (len(data) == cursize < nbytes and select.select([self.rfile._sock], [], [], 0)[0]): - cursize = len(data) # This is a geometric increase in read size (never more # than doubling our the current length of data per loop # iteration). delta = min(cursize, nbytes - cursize) data += self.rfile.read(delta) + cursize += delta else: data = None # throw away additional data [see bug #427345] From 769972cd0000eaa0b9759fb81b321e6adbccb6aa Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 2 Dec 2025 13:57:37 +0200 Subject: [PATCH 2/2] Simply use non-zero timeout. --- Lib/http/server.py | 10 +++++----- Lib/test/test_httpservers.py | 11 ++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Lib/http/server.py b/Lib/http/server.py index 3346a14bc1df5a..bee8605dfef95e 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -1288,16 +1288,16 @@ def run_cgi(self): env = env ) if self.command.lower() == "post" and nbytes > 0: - cursize = min(nbytes, _MIN_READ_BUF_SIZE) - data = self.rfile.read(cursize) - while (len(data) == cursize < nbytes and - select.select([self.rfile._sock], [], [], 0)[0]): + cursize = 0 + data = self.rfile.read(min(nbytes, _MIN_READ_BUF_SIZE)) + while (len(data) < nbytes and len(data) != cursize and + select.select([self.rfile._sock], [], [], self.timeout)[0]): + cursize = len(data) # This is a geometric increase in read size (never more # than doubling our the current length of data per loop # iteration). delta = min(cursize, nbytes - cursize) data += self.rfile.read(delta) - cursize += delta else: data = None # throw away additional data [see bug #427345] diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 0f003064f3109c..7b58c5ef55b337 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -1132,11 +1132,12 @@ def test_large_content_length(self): self.assertEqual(res.read(), b'%d %d' % (size, size) + self.linesep) def test_large_content_length_truncated(self): - for w in range(18, 65): - size = 1 << w - headers = {'Content-Length' : str(size)} - res = self.request('/cgi-bin/file1.py', 'POST', b'x', headers) - self.assertEqual(res.read(), b'Hello World' + self.linesep) + with support.swap_attr(self.request_handler, 'timeout', 0.001): + for w in range(18, 65): + size = 1 << w + headers = {'Content-Length' : str(size)} + res = self.request('/cgi-bin/file1.py', 'POST', b'x', headers) + self.assertEqual(res.read(), b'Hello World' + self.linesep) def test_invaliduri(self): res = self.request('/cgi-bin/invalid')