From 1b27643d7bd192e1d2cc52e36ada0021c3f76bb8 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Sat, 5 Jun 2021 11:54:07 -0700 Subject: [PATCH] Better implementation for #1238 using new route_path scope key --- datasette/app.py | 17 ++++++++++------- datasette/utils/testing.py | 1 + tests/test_html.py | 1 + 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index 018a8d5b3b..c0e8ad011b 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -1089,6 +1089,7 @@ async def route_path(self, scope, receive, send, path): base_url = self.ds.setting("base_url") if base_url != "/" and path.startswith(base_url): path = "/" + path[len(base_url) :] + scope = dict(scope, route_path=path) request = Request(scope, receive) # Populate request_messages if ds_messages cookie is present try: @@ -1143,9 +1144,8 @@ async def handle_404(self, request, send, exception=None): await asgi_send_redirect(send, path.decode("latin1")) else: # Is there a pages/* template matching this path? - template_path = ( - os.path.join("pages", *request.scope["path"].split("/")) + ".html" - ) + route_path = request.scope.get("route_path", request.scope["path"]) + template_path = os.path.join("pages", *route_path.split("/")) + ".html" try: template = self.ds.jinja_env.select_template([template_path]) except TemplateNotFound: @@ -1153,7 +1153,7 @@ async def handle_404(self, request, send, exception=None): if template is None: # Try for a pages/blah/{name}.html template match for regex, wildcard_template in self.page_routes: - match = regex.match(request.scope["path"]) + match = regex.match(route_path) if match is not None: context.update(match.groupdict()) template = wildcard_template @@ -1356,8 +1356,8 @@ def __init__(self, ds): self.ds = ds self.app = ds.app() - def _fix(self, path): - if not isinstance(path, PrefixedUrlString): + def _fix(self, path, avoid_path_rewrites=False): + if not isinstance(path, PrefixedUrlString) and not avoid_path_rewrites: path = self.ds.urls.path(path) if path.startswith("/"): path = f"http://localhost{path}" @@ -1392,5 +1392,8 @@ async def delete(self, path, **kwargs): return await client.delete(self._fix(path), **kwargs) async def request(self, method, path, **kwargs): + avoid_path_rewrites = kwargs.pop("avoid_path_rewrites", None) async with httpx.AsyncClient(app=self.app) as client: - return await client.request(method, self._fix(path), **kwargs) + return await client.request( + method, self._fix(path, avoid_path_rewrites), **kwargs + ) diff --git a/datasette/utils/testing.py b/datasette/utils/testing.py index 57b19ea54e..a169a83ddd 100644 --- a/datasette/utils/testing.py +++ b/datasette/utils/testing.py @@ -140,6 +140,7 @@ async def _request( method, path, allow_redirects=allow_redirects, + avoid_path_rewrites=True, cookies=cookies, headers=headers, content=post_body, diff --git a/tests/test_html.py b/tests/test_html.py index 31bb666749..f1d4bd70d1 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -1523,6 +1523,7 @@ def test_base_url_config(app_client_base_url_prefix, path): and href not in { "https://datasette.io/", + "https://github.com/simonw/datasette", "https://github.com/simonw/datasette/blob/main/LICENSE", "https://github.com/simonw/datasette/blob/main/tests/fixtures.py", "/login-as-root", # Only used for the latest.datasette.io demo