From 9a9139809d87a80ae5730c141b5d8828e107711b Mon Sep 17 00:00:00 2001 From: jomae Date: Tue, 25 Jun 2024 11:21:26 +0000 Subject: [PATCH 1/2] 1.6.1dev: fix `Request.send` not set `Content-Length` header for a `bytes` instance (closes #13761) git-svn-id: http://trac.edgewall.org/intertrac/log:/branches/1.6-stable@17831 af82e41b-90c4-0310-8c96-b1721e28e2e2 --- trac/web/api.py | 2 +- trac/web/tests/api.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/trac/web/api.py b/trac/web/api.py index 383db0a067..95a060ce03 100644 --- a/trac/web/api.py +++ b/trac/web/api.py @@ -1028,7 +1028,7 @@ def _send(self, content, content_type='text/html', status=200, self.send_header('Cache-Control', 'must-revalidate') self.send_header('Expires', 'Fri, 01 Jan 1999 00:00:00 GMT') self.send_header('Content-Type', content_type + ';charset=utf-8') - if isinstance(content, str): + if isinstance(content, bytes): self.send_header('Content-Length', len(content)) self.end_headers(exc_info) diff --git a/trac/web/tests/api.py b/trac/web/tests/api.py index 01010e120d..589dd8650a 100644 --- a/trac/web/tests/api.py +++ b/trac/web/tests/api.py @@ -443,6 +443,17 @@ def test_write_unicode(self): with self.assertRaises(ValueError): req.write((b'F', 'öo')) + def test_send_bytes(self): + req = _make_req(_make_environ(method='GET')) + with self.assertRaises(RequestDone): + req.send(b'\xef\xbb\xbf') + self.assertEqual('3', req.headers_sent.get('Content-Length')) + + def test_send_unicode(self): + req = _make_req(_make_environ(method='GET')) + with self.assertRaises(ValueError): + req.send(u'\ufeff') + def test_send_iterable(self): def iterable(): yield b'line1,' From 8b78522e18562f944a0c219fe3b4feeb66020754 Mon Sep 17 00:00:00 2001 From: jomae Date: Tue, 25 Jun 2024 11:36:05 +0000 Subject: [PATCH 2/2] 1.6.1dev: `Request.write` raises a `ValueError` for an empty `str` instance now (closes #13762) git-svn-id: http://trac.edgewall.org/intertrac/log:/branches/1.6-stable@17832 af82e41b-90c4-0310-8c96-b1721e28e2e2 --- trac/web/api.py | 2 ++ trac/web/tests/api.py | 4 ++++ trac/web/tests/main.py | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/trac/web/api.py b/trac/web/api.py index 95a060ce03..7f8b59bdcb 100644 --- a/trac/web/api.py +++ b/trac/web/api.py @@ -982,6 +982,8 @@ def write(self, data): there are multiple calls to `write`, to the cumulative length of the *data* arguments. """ + if isinstance(data, str): + raise ValueError("Can't send str content") if not self._write: self.end_headers() try: diff --git a/trac/web/tests/api.py b/trac/web/tests/api.py index 589dd8650a..815fb73c6e 100644 --- a/trac/web/tests/api.py +++ b/trac/web/tests/api.py @@ -440,8 +440,12 @@ def test_write_unicode(self): # anyway we're not supposed to send unicode, so we get a ValueError with self.assertRaises(ValueError): req.write('Föö') + with self.assertRaises(ValueError): + req.write('') with self.assertRaises(ValueError): req.write((b'F', 'öo')) + with self.assertRaises(ValueError): + req.write(('Föo'.encode('utf-8'), '')) def test_send_bytes(self): req = _make_req(_make_environ(method='GET')) diff --git a/trac/web/tests/main.py b/trac/web/tests/main.py index 1dfdd81641..d1cfbb3386 100644 --- a/trac/web/tests/main.py +++ b/trac/web/tests/main.py @@ -90,7 +90,7 @@ def match_request(self, req): def process_request(self, req): self.calls += 1 req.authname - req.send('') + req.send(b'') cls.authenticators['success1'] = SuccessfulAuthenticator1 cls.authenticators['success2'] = SuccessfulAuthenticator2