From f19f86891571a0d7e81e0d98de12ca223395993d Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Fri, 30 Aug 2019 11:18:36 -0700 Subject: [PATCH] Clear fewer headers on 1xx/204/304 responses MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This function is called on more than just 304 responses; it’s important to permit the Allow header on 204 responses. Also, the relevant RFCs have changed significantly. Fixes #2726. Signed-off-by: Anders Kaseorg --- tornado/test/httpclient_test.py | 2 +- tornado/test/web_test.py | 1 - tornado/web.py | 22 +++++++--------------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/tornado/test/httpclient_test.py b/tornado/test/httpclient_test.py index d1cc14673..11a4ee022 100644 --- a/tornado/test/httpclient_test.py +++ b/tornado/test/httpclient_test.py @@ -109,7 +109,7 @@ class ContentLength304Handler(RequestHandler): self.set_status(304) self.set_header("Content-Length", 42) - def _clear_headers_for_304(self): + def _clear_representation_headers(self): # Tornado strips content-length from 304 responses, but here we # want to simulate servers that include the headers anyway. pass diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 5908710ac..4a06c12d6 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -1175,7 +1175,6 @@ class StaticFileTest(WebTestCase): ) self.assertEqual(response2.code, 304) self.assertTrue("Content-Length" not in response2.headers) - self.assertTrue("Last-Modified" not in response2.headers) def test_static_304_if_none_match(self): response1 = self.get_and_head("/static/robots.txt") diff --git a/tornado/web.py b/tornado/web.py index adbf591e5..9412ab447 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1138,7 +1138,7 @@ class RequestHandler(object): assert not self._write_buffer, ( "Cannot send body with %s" % self._status_code ) - self._clear_headers_for_304() + self._clear_representation_headers() elif "Content-Length" not in self._headers: content_length = sum(len(part) for part in self._write_buffer) self.set_header("Content-Length", content_length) @@ -1803,21 +1803,13 @@ class RequestHandler(object): def _ui_method(self, method: Callable[..., str]) -> Callable[..., str]: return lambda *args, **kwargs: method(self, *args, **kwargs) - def _clear_headers_for_304(self) -> None: - # 304 responses should not contain entity headers (defined in - # http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1) + def _clear_representation_headers(self) -> None: + # 304 responses should not contain representation metadata + # headers (defined in + # https://tools.ietf.org/html/rfc7231#section-3.1) # not explicitly allowed by - # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 - headers = [ - "Allow", - "Content-Encoding", - "Content-Language", - "Content-Length", - "Content-MD5", - "Content-Range", - "Content-Type", - "Last-Modified", - ] + # https://tools.ietf.org/html/rfc7232#section-4.1 + headers = ["Content-Encoding", "Content-Language", "Content-Type"] for h in headers: self.clear_header(h) -- 2.47.2