Subclass aiohttp requests to use json helper (#90214)

* Subclass aiohttp requests to use json helper

* Subclass aiohttp requests to use json helper

* remove unneeded

* revert for new pr

* override loads is never used so drop it

* override loads is never used so drop it
This commit is contained in:
J. Nick Koston 2023-03-24 09:37:43 -10:00 committed by GitHub
parent 0bb0b4bfc5
commit 72b09bfee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,7 @@
"""Support to serve the Home Assistant API as WSGI application.""" """Support to serve the Home Assistant API as WSGI application."""
from __future__ import annotations from __future__ import annotations
import asyncio
import datetime import datetime
from ipaddress import IPv4Network, IPv6Network, ip_network from ipaddress import IPv4Network, IPv6Network, ip_network
import logging import logging
@ -10,9 +11,13 @@ from tempfile import NamedTemporaryFile
from typing import Any, Final, TypedDict, cast from typing import Any, Final, TypedDict, cast
from aiohttp import web from aiohttp import web
from aiohttp.typedefs import StrOrURL from aiohttp.abc import AbstractStreamWriter
from aiohttp.http_parser import RawRequestMessage
from aiohttp.streams import StreamReader
from aiohttp.typedefs import JSONDecoder, StrOrURL
from aiohttp.web_exceptions import HTTPMovedPermanently, HTTPRedirection from aiohttp.web_exceptions import HTTPMovedPermanently, HTTPRedirection
from aiohttp.web_log import AccessLogger from aiohttp.web_log import AccessLogger
from aiohttp.web_protocol import RequestHandler
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.asymmetric import rsa
@ -31,6 +36,7 @@ from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
from homeassistant.setup import async_start_setup, async_when_setup_or_start from homeassistant.setup import async_start_setup, async_when_setup_or_start
from homeassistant.util import ssl as ssl_util from homeassistant.util import ssl as ssl_util
from homeassistant.util.json import json_loads
from .auth import async_setup_auth from .auth import async_setup_auth
from .ban import setup_bans from .ban import setup_bans
@ -240,6 +246,40 @@ class HomeAssistantAccessLogger(AccessLogger):
super().log(request, response, time) super().log(request, response, time)
class HomeAssistantRequest(web.Request):
"""Home Assistant request object."""
async def json(self, *, loads: JSONDecoder = json_loads) -> Any:
"""Return body as JSON."""
# json_loads is a wrapper around orjson.loads that handles
# bytes and str. We can pass the bytes directly to json_loads.
return json_loads(await self.read())
class HomeAssistantApplication(web.Application):
"""Home Assistant application."""
def _make_request(
self,
message: RawRequestMessage,
payload: StreamReader,
protocol: RequestHandler,
writer: AbstractStreamWriter,
task: asyncio.Task[None],
_cls: type[web.Request] = HomeAssistantRequest,
) -> web.Request:
"""Create request instance."""
return _cls(
message,
payload,
protocol,
writer,
task,
loop=self._loop,
client_max_size=self._client_max_size,
)
class HomeAssistantHTTP: class HomeAssistantHTTP:
"""HTTP server for Home Assistant.""" """HTTP server for Home Assistant."""
@ -255,7 +295,7 @@ class HomeAssistantHTTP:
ssl_profile: str, ssl_profile: str,
) -> None: ) -> None:
"""Initialize the HTTP Home Assistant server.""" """Initialize the HTTP Home Assistant server."""
self.app = web.Application( self.app = HomeAssistantApplication(
middlewares=[], middlewares=[],
client_max_size=MAX_CLIENT_SIZE, client_max_size=MAX_CLIENT_SIZE,
handler_args={ handler_args={