Ensure large payloads are compressed in the executor with aiohttp 3.9.0 (#103592)

This commit is contained in:
J. Nick Koston 2023-11-07 12:37:54 -06:00 committed by GitHub
parent d3ed8a6b8b
commit 0d63e2f9b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 4 deletions

View File

@ -41,6 +41,7 @@ from homeassistant.exceptions import (
Unauthorized,
)
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers.aiohttp_compat import enable_compression
from homeassistant.helpers.event import EventStateChangedData
from homeassistant.helpers.json import json_dumps
from homeassistant.helpers.service import async_get_all_descriptions
@ -219,7 +220,7 @@ class APIStatesView(HomeAssistantView):
response = web.Response(
body=f'[{",".join(states)}]', content_type=CONTENT_TYPE_JSON
)
response.enable_compression()
enable_compression(response)
return response

View File

@ -17,6 +17,7 @@ from yarl import URL
from homeassistant.components.http import HomeAssistantView
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.aiohttp_compat import enable_compression
from homeassistant.helpers.typing import UNDEFINED
from .const import X_HASS_SOURCE, X_INGRESS_PATH
@ -191,7 +192,7 @@ class HassIOIngress(HomeAssistantView):
if content_length_int > MIN_COMPRESSED_SIZE and should_compress(
content_type or simple_response.content_type
):
simple_response.enable_compression()
enable_compression(simple_response)
await simple_response.prepare(request)
return simple_response

View File

@ -20,6 +20,7 @@ import voluptuous as vol
from homeassistant import exceptions
from homeassistant.const import CONTENT_TYPE_JSON
from homeassistant.core import Context, HomeAssistant, is_callback
from homeassistant.helpers.aiohttp_compat import enable_compression
from homeassistant.helpers.json import (
find_paths_unserializable_data,
json_bytes,
@ -72,7 +73,7 @@ class HomeAssistantView:
status=int(status_code),
headers=headers,
)
response.enable_compression()
enable_compression(response)
return response
def json_message(

View File

@ -1,7 +1,7 @@
"""Helper to restore old aiohttp behavior."""
from __future__ import annotations
from aiohttp import web_protocol, web_server
from aiohttp import web, web_protocol, web_server
class CancelOnDisconnectRequestHandler(web_protocol.RequestHandler):
@ -23,3 +23,19 @@ def restore_original_aiohttp_cancel_behavior() -> None:
"""
web_protocol.RequestHandler = CancelOnDisconnectRequestHandler # type: ignore[misc]
web_server.RequestHandler = CancelOnDisconnectRequestHandler # type: ignore[misc]
def enable_compression(response: web.Response) -> None:
"""Enable compression on the response."""
#
# Set _zlib_executor_size in the constructor once support for
# aiohttp < 3.9.0 is dropped
#
# We want large zlib payloads to be compressed in the executor
# to avoid blocking the event loop.
#
# 32KiB was chosen based on testing in production.
# aiohttp will generate a warning for payloads larger than 1MiB
#
response._zlib_executor_size = 32768 # pylint: disable=protected-access
response.enable_compression()