diff --git a/trac/web/api.py b/trac/web/api.py index 383db0a067..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: @@ -1028,7 +1030,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..815fb73c6e 100644 --- a/trac/web/tests/api.py +++ b/trac/web/tests/api.py @@ -440,8 +440,23 @@ 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')) + 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(): 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