Avoid compressing binary images on ingress (#96581)
parent
a27e126c86
commit
62c5194bc8
|
@ -177,7 +177,8 @@ class HassIOView(HomeAssistantView):
|
|||
)
|
||||
response.content_type = client.content_type
|
||||
|
||||
response.enable_compression()
|
||||
if should_compress(response.content_type):
|
||||
response.enable_compression()
|
||||
await response.prepare(request)
|
||||
async for data in client.content.iter_chunked(8192):
|
||||
await response.write(data)
|
||||
|
@ -213,3 +214,10 @@ def _get_timeout(path: str) -> ClientTimeout:
|
|||
if NO_TIMEOUT.match(path):
|
||||
return ClientTimeout(connect=10, total=None)
|
||||
return ClientTimeout(connect=10, total=300)
|
||||
|
||||
|
||||
def should_compress(content_type: str) -> bool:
|
||||
"""Return if we should compress a response."""
|
||||
if content_type.startswith("image/"):
|
||||
return "svg" in content_type
|
||||
return not content_type.startswith(("video/", "audio/", "font/"))
|
||||
|
|
|
@ -20,6 +20,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|||
from homeassistant.helpers.typing import UNDEFINED
|
||||
|
||||
from .const import X_HASS_SOURCE, X_INGRESS_PATH
|
||||
from .http import should_compress
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -182,7 +183,9 @@ class HassIOIngress(HomeAssistantView):
|
|||
content_type=result.content_type,
|
||||
body=body,
|
||||
)
|
||||
if content_length_int > MIN_COMPRESSED_SIZE:
|
||||
if content_length_int > MIN_COMPRESSED_SIZE and should_compress(
|
||||
simple_response.content_type
|
||||
):
|
||||
simple_response.enable_compression()
|
||||
await simple_response.prepare(request)
|
||||
return simple_response
|
||||
|
@ -192,7 +195,8 @@ class HassIOIngress(HomeAssistantView):
|
|||
response.content_type = result.content_type
|
||||
|
||||
try:
|
||||
response.enable_compression()
|
||||
if should_compress(response.content_type):
|
||||
response.enable_compression()
|
||||
await response.prepare(request)
|
||||
async for data in result.content.iter_chunked(8192):
|
||||
await response.write(data)
|
||||
|
|
|
@ -396,6 +396,68 @@ async def test_ingress_request_get_compressed(
|
|||
assert aioclient_mock.mock_calls[-1][3][X_FORWARDED_PROTO]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"content_type",
|
||||
[
|
||||
"image/png",
|
||||
"image/jpeg",
|
||||
"font/woff2",
|
||||
"video/mp4",
|
||||
],
|
||||
)
|
||||
async def test_ingress_request_not_compressed(
|
||||
hassio_noauth_client, content_type: str, aioclient_mock: AiohttpClientMocker
|
||||
) -> None:
|
||||
"""Test ingress does not compress images."""
|
||||
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": content_type},
|
||||
)
|
||||
|
||||
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"] == content_type
|
||||
assert "Content-Encoding" not in resp.headers
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"content_type",
|
||||
[
|
||||
"image/svg+xml",
|
||||
"text/html",
|
||||
"application/javascript",
|
||||
"text/plain",
|
||||
],
|
||||
)
|
||||
async def test_ingress_request_compressed(
|
||||
hassio_noauth_client, content_type: str, aioclient_mock: AiohttpClientMocker
|
||||
) -> None:
|
||||
"""Test ingress compresses text."""
|
||||
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": content_type},
|
||||
)
|
||||
|
||||
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"] == content_type
|
||||
assert resp.headers["Content-Encoding"] == "deflate"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"build_type",
|
||||
[
|
||||
|
|
Loading…
Reference in New Issue