diff --git a/aiohttp/web_reqrep.py b/aiohttp/web_reqrep.py index 6f3e566c8c6..ea5965cf04e 100644 --- a/aiohttp/web_reqrep.py +++ b/aiohttp/web_reqrep.py @@ -24,7 +24,7 @@ CIMultiDict, MultiDictProxy, MultiDict) -from .protocol import Response as ResponseImpl, HttpVersion10 +from .protocol import Response as ResponseImpl, HttpVersion10, HttpVersion11 from .streams import EOF_MARKER @@ -646,6 +646,10 @@ def start(self, request): self._start_compression(request) if self._chunked: + if request.version != HttpVersion11: + raise RuntimeError("Using chunked encoding is forbidden " + "for HTTP/{0.major}.{0.minor}".format( + request.version)) resp_impl.enable_chunked_encoding() if self._chunk_size: resp_impl.add_chunking_filter(self._chunk_size) diff --git a/docs/web_reference.rst b/docs/web_reference.rst index c8ecee09033..8c877b1ce9c 100644 --- a/docs/web_reference.rst +++ b/docs/web_reference.rst @@ -429,6 +429,11 @@ StreamResponse .. versionadded:: 0.14 + .. warning:: chunked encoding can be enabled for ``HTTP/1.1`` only. + + Setting up both :attr:`content_length` and chunked + encoding is mutually exclusive. + .. seealso:: :attr:`chunked` .. attribute:: headers diff --git a/tests/test_web_response.py b/tests/test_web_response.py index abe1363ad48..e7f820d9a84 100644 --- a/tests/test_web_response.py +++ b/tests/test_web_response.py @@ -18,8 +18,9 @@ def setUp(self): def tearDown(self): self.loop.close() - def make_request(self, method, path, headers=CIMultiDict()): - message = RawRequestMessage(method, path, HttpVersion11, headers, + def make_request(self, method, path, headers=CIMultiDict(), + version=HttpVersion11): + message = RawRequestMessage(method, path, version, headers, False, False) return self.request_from_message(message) @@ -183,6 +184,16 @@ def test_chunk_size(self, ResponseImpl): msg.add_chunking_filter.assert_called_with(8192) self.assertIsNotNone(msg.filter) + def test_chunked_encoding_forbidden_for_http_10(self): + req = self.make_request('GET', '/', version=HttpVersion10) + resp = StreamResponse() + resp.enable_chunked_encoding() + + with self.assertRaisesRegex( + RuntimeError, + "Using chunked encoding is forbidden for HTTP/1.0"): + resp.start(req) + @mock.patch('aiohttp.web_reqrep.ResponseImpl') def test_compression_no_accept(self, ResponseImpl): req = self.make_request('GET', '/')