Try to avoid re-parsing the content-type in hassio ingress if possible (#103477)

Co-authored-by: Stefan Agner <stefan@agner.ch>
Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
J. Nick Koston 2023-11-06 13:48:47 -06:00 committed by GitHub
parent 570b4ccb4b
commit 408e977b17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 2 deletions

View File

@ -169,6 +169,11 @@ class HassIOIngress(HomeAssistantView):
headers = _response_header(result)
content_length_int = 0
content_length = result.headers.get(hdrs.CONTENT_LENGTH, UNDEFINED)
# Avoid parsing content_type in simple cases for better performance
if maybe_content_type := result.headers.get(hdrs.CONTENT_TYPE):
content_type = (maybe_content_type.partition(";"))[0].strip()
else:
content_type = result.content_type
# Simple request
if result.status in (204, 304) or (
content_length is not UNDEFINED
@ -180,11 +185,11 @@ class HassIOIngress(HomeAssistantView):
simple_response = web.Response(
headers=headers,
status=result.status,
content_type=result.content_type,
content_type=content_type,
body=body,
)
if content_length_int > MIN_COMPRESSED_SIZE and should_compress(
simple_response.content_type
content_type or simple_response.content_type
):
simple_response.enable_compression()
await simple_response.prepare(request)

View File

@ -427,6 +427,30 @@ async def test_ingress_request_not_compressed(
assert "Content-Encoding" not in resp.headers
async def test_ingress_request_with_charset_in_content_type(
hassio_noauth_client, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test ingress passes content type."""
body = b"this_is_long_enough_to_be_compressed" * 100
aioclient_mock.get(
"http://127.0.0.1/ingress/core/x.any",
data=body,
headers={
"Content-Length": len(body),
"Content-Type": "text/html; charset=utf-8",
},
)
resp = await hassio_noauth_client.get(
"/api/hassio_ingress/core/x.any",
headers={"X-Test-Header": "beer", "Accept-Encoding": "gzip, deflate"},
)
# Check we got right response
assert resp.status == HTTPStatus.OK
assert resp.headers["Content-Type"] == "text/html"
@pytest.mark.parametrize(
"content_type",
[