Skip to content

Commit

Permalink
Remove Transfer-Encoding for empty body response per RFC 9112 section…
Browse files Browse the repository at this point in the history
… 6.3
  • Loading branch information
bdraco committed Oct 27, 2023
1 parent 32a1bae commit b6978c2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
26 changes: 25 additions & 1 deletion aiohttp/web_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,31 @@ async def _prepare_headers(self) -> None:
if self._compression:
await self._start_compression(request)

if self._chunked:
if self.status in (204, 304) or 100 >= self.status < 200:
#
# Remove transfer-encoding since there is no body
# and this can confuse some clients (e.g. older aiohttp)
#
# https://datatracker.ietf.org/doc/html/rfc9112#section-6.3
#
# Any response to a HEAD request and any response with
# a 1xx (Informational), 204 (No Content), or 304
# (Not Modified) status code is always terminated by
# the first empty line after the header fields,
# regardless of the header fields present in the message,
# and thus cannot contain a message body or trailer section.
#
if hdrs.TRANSFER_ENCODING in headers:
del headers[hdrs.TRANSFER_ENCODING]
# HTTP 1.0: https://tools.ietf.org/html/rfc1945#section-10.4
# 0 is not a valid value for Content-Length header for HTTP/1.0
if hdrs.CONTENT_LENGTH in headers:
del headers[hdrs.CONTENT_LENGTH]
# HTTP 1.1: https://tools.ietf.org/html/rfc7230#section-3.3.2
# 0 is a valid value for Content-Length header for HTTP/1.1
if version >= HttpVersion11:
headers[hdrs.CONTENT_LENGTH] = "0"
elif self._chunked:
if version != HttpVersion11:
raise RuntimeError(
"Using chunked encoding is forbidden "
Expand Down
16 changes: 16 additions & 0 deletions tests/test_web_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,22 @@ async def write_headers(status_line, headers):
assert resp.content_length is None


async def test_rm_transfer_encoding_rfc_9112_6_3() -> None:
"""Remove transfer encoding for RFC 9112 sec 6.3."""
writer = mock.Mock()

async def write_headers(status_line, headers):
assert hdrs.CONTENT_LENGTH not in headers
assert hdrs.TRANSFER_ENCODING not in headers

writer.write_headers.side_effect = write_headers
req = make_request("GET", "/", version=HttpVersion11, writer=writer)
resp = Response(body=BytesPayload(b"answer"))
resp.enable_compression(ContentCoding.gzip)
await resp.prepare(req)
assert resp.content_length is None


async def test_content_length_on_chunked() -> None:
req = make_request("GET", "/")
resp = Response(body=b"answer")
Expand Down

0 comments on commit b6978c2

Please sign in to comment.