Skip to content

Commit fb69cf0

Browse files
[PR #11673/e8c5252c backport][3.14] Fix domain matching being lower priority than path matching (#11676)
**This is a backport of PR #11673 as merged into master (e8c5252).** Co-authored-by: Sam Bull <[email protected]>
1 parent 52afe62 commit fb69cf0

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

CHANGES/11673.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed routing to a sub-application added via ``.add_domain()`` not working
2+
if the same path exists on the parent app. -- by :user:`Dreamsorcerer`.

aiohttp/web_urldispatcher.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,21 @@ async def resolve(self, request: Request) -> UrlMappingMatchInfo:
10061006
resource_index = self._resource_index
10071007
allowed_methods: set[str] = set()
10081008

1009+
# MatchedSubAppResource is primarily used to match on domain names
1010+
# (though custom rules could match on other things). This means that
1011+
# the traversal algorithm below can't be applied, and that we likely
1012+
# need to check these first so a sub app that defines the same path
1013+
# as a parent app will get priority if there's a domain match.
1014+
#
1015+
# For most cases we do not expect there to be many of these since
1016+
# currently they are only added by `.add_domain()`.
1017+
for resource in self._matched_sub_app_resources:
1018+
match_dict, allowed = await resource.resolve(request)
1019+
if match_dict is not None:
1020+
return match_dict
1021+
else:
1022+
allowed_methods |= allowed
1023+
10091024
# Walk the url parts looking for candidates. We walk the url backwards
10101025
# to ensure the most explicit match is found first. If there are multiple
10111026
# candidates for a given url part because there are multiple resources
@@ -1023,21 +1038,6 @@ async def resolve(self, request: Request) -> UrlMappingMatchInfo:
10231038
break
10241039
url_part = url_part.rpartition("/")[0] or "/"
10251040

1026-
#
1027-
# We didn't find any candidates, so we'll try the matched sub-app
1028-
# resources which we have to walk in a linear fashion because they
1029-
# have regex/wildcard match rules and we cannot index them.
1030-
#
1031-
# For most cases we do not expect there to be many of these since
1032-
# currently they are only added by `add_domain`
1033-
#
1034-
for resource in self._matched_sub_app_resources:
1035-
match_dict, allowed = await resource.resolve(request)
1036-
if match_dict is not None:
1037-
return match_dict
1038-
else:
1039-
allowed_methods |= allowed
1040-
10411041
if allowed_methods:
10421042
return MatchInfoError(HTTPMethodNotAllowed(request.method, allowed_methods))
10431043

docs/web_reference.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,14 @@ Application and Router
16251625
matches the pattern *domain* then
16261626
further resolving is passed to *subapp*.
16271627

1628+
.. warning::
1629+
1630+
Registering many domains using this method may cause performance
1631+
issues with handler routing. If you have a substantial number of
1632+
applications for different domains, you may want to consider
1633+
using a reverse proxy (such as Nginx) to handle routing to
1634+
different apps, rather that registering them as sub-applications.
1635+
16281636
:param str domain: domain or mask of domain for the resource.
16291637

16301638
:param Application subapp: nested application.

tests/test_web_urldispatcher.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,8 +987,8 @@ async def get(self) -> web.Response:
987987
await r.release()
988988

989989

990-
@pytest.mark.xfail(reason="https://github.com/aio-libs/aiohttp/issues/11665")
991990
async def test_subapp_domain_routing_same_path(aiohttp_client: AiohttpClient) -> None:
991+
"""Regression test for #11665."""
992992
app = web.Application()
993993
sub_app = web.Application()
994994

0 commit comments

Comments
 (0)