Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to using aiohttp-fast-url-dispatcher #103656

Merged
merged 1 commit into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 2 additions & 43 deletions homeassistant/components/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@
from aiohttp.web_exceptions import HTTPMovedPermanently, HTTPRedirection
from aiohttp.web_log import AccessLogger
from aiohttp.web_protocol import RequestHandler
from aiohttp.web_urldispatcher import (
AbstractResource,
UrlDispatcher,
UrlMappingMatchInfo,
)
from aiohttp_fast_url_dispatcher import FastUrlDispatcher, attach_fast_url_dispatcher
from aiohttp_zlib_ng import enable_zlib_ng
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
Expand Down Expand Up @@ -321,7 +317,7 @@ def __init__(
# By default aiohttp does a linear search for routing rules,
# we have a lot of routes, so use a dict lookup with a fallback
# to the linear search.
self.app._router = FastUrlDispatcher()
attach_fast_url_dispatcher(self.app, FastUrlDispatcher())
self.hass = hass
self.ssl_certificate = ssl_certificate
self.ssl_peer_certificate = ssl_peer_certificate
Expand Down Expand Up @@ -587,40 +583,3 @@ async def start_http_server_and_save_config(
]

store.async_delay_save(lambda: conf, SAVE_DELAY)


class FastUrlDispatcher(UrlDispatcher):
"""UrlDispatcher that uses a dict lookup for resolving."""

def __init__(self) -> None:
"""Initialize the dispatcher."""
super().__init__()
self._resource_index: dict[str, list[AbstractResource]] = {}

def register_resource(self, resource: AbstractResource) -> None:
"""Register a resource."""
super().register_resource(resource)
canonical = resource.canonical
if "{" in canonical: # strip at the first { to allow for variables
canonical = canonical.split("{")[0].rstrip("/")
# There may be multiple resources for a canonical path
# so we use a list to avoid falling back to a full linear search
self._resource_index.setdefault(canonical, []).append(resource)

async def resolve(self, request: web.Request) -> UrlMappingMatchInfo:
"""Resolve a request."""
url_parts = request.rel_url.raw_parts
resource_index = self._resource_index

# Walk the url parts looking for candidates
for i in range(len(url_parts), 0, -1):
url_part = "/" + "/".join(url_parts[1:i])
if (resource_candidates := resource_index.get(url_part)) is not None:
for candidate in resource_candidates:
if (
match_dict := (await candidate.resolve(request))[0]
) is not None:
return match_dict

# Finally, fallback to the linear search
return await super().resolve(request)
6 changes: 5 additions & 1 deletion homeassistant/components/http/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@
"integration_type": "system",
"iot_class": "local_push",
"quality_scale": "internal",
"requirements": ["aiohttp_cors==0.7.0", "aiohttp-zlib-ng==0.1.1"]
"requirements": [
"aiohttp_cors==0.7.0",
"aiohttp-fast-url-dispatcher==0.1.0",
"aiohttp-zlib-ng==0.1.1"
]
}
1 change: 1 addition & 0 deletions homeassistant/package_constraints.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
aiodiscover==1.5.1
aiohttp-fast-url-dispatcher==0.1.0
aiohttp-zlib-ng==0.1.1
aiohttp==3.8.5;python_version<'3.12'
aiohttp==3.9.0b0;python_version>='3.12'
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies = [
"aiohttp==3.9.0b0;python_version>='3.12'",
"aiohttp==3.8.5;python_version<'3.12'",
"aiohttp_cors==0.7.0",
"aiohttp-fast-url-dispatcher==0.1.0",
"aiohttp-zlib-ng==0.1.1",
"astral==2.2",
"attrs==23.1.0",
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
aiohttp==3.9.0b0;python_version>='3.12'
aiohttp==3.8.5;python_version<'3.12'
aiohttp_cors==0.7.0
aiohttp-fast-url-dispatcher==0.1.0
aiohttp-zlib-ng==0.1.1
astral==2.2
attrs==23.1.0
Expand Down
3 changes: 3 additions & 0 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ aioharmony==0.2.10
# homeassistant.components.homekit_controller
aiohomekit==3.0.9

# homeassistant.components.http
aiohttp-fast-url-dispatcher==0.1.0

# homeassistant.components.http
aiohttp-zlib-ng==0.1.1

Expand Down
3 changes: 3 additions & 0 deletions requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ aioharmony==0.2.10
# homeassistant.components.homekit_controller
aiohomekit==3.0.9

# homeassistant.components.http
aiohttp-fast-url-dispatcher==0.1.0

# homeassistant.components.http
aiohttp-zlib-ng==0.1.1

Expand Down