html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,issue,performed_via_github_app https://github.com/simonw/datasette/issues/1238#issuecomment-855278998,https://api.github.com/repos/simonw/datasette/issues/1238,855278998,MDEyOklzc3VlQ29tbWVudDg1NTI3ODk5OA==,9599,2021-06-05T18:37:16Z,2021-06-05T18:37:16Z,OWNER,"Alternative idea: populate `request.scope` with a new `route_path` which is the base-url-stripped version, which we then use for other routing operations.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",813899472, https://github.com/simonw/datasette/issues/1238#issuecomment-855278540,https://api.github.com/repos/simonw/datasette/issues/1238,855278540,MDEyOklzc3VlQ29tbWVudDg1NTI3ODU0MA==,9599,2021-06-05T18:33:25Z,2021-06-05T18:33:25Z,OWNER,"Got the test to pass by ensuring the tests don't accidentally double-rewrite the path. Ran into a new problem: ``` @pytest.mark.asyncio @pytest.mark.parametrize( ""prefix,expected_path"", [(None, ""/asgi-scope""), (""/prefix/"", ""/prefix/asgi-scope"")] ) async def test_client_path(datasette, prefix, expected_path): original_base_url = datasette._settings[""base_url""] try: if prefix is not None: datasette._settings[""base_url""] = prefix response = await datasette.client.get(""/asgi-scope"") path = response.json()[""path""] > assert path == expected_path E AssertionError: assert '/asgi-scope' == '/prefix/asgi-scope' E - /prefix/asgi-scope E ? ------- E + /asgi-scope ``` That test confirms that messing around with the `base_url` doesn't modify the ASGI scope... but the fix I'm using for this issue DOES modify the ASGI scope. The question raised here is: should the ASGI scope stay unmodified when `base_url` is used? I think it should. It doesn't make sense to obscure the ""real"" path just to get custom pages to work properly.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",813899472, https://github.com/simonw/datasette/issues/1238#issuecomment-855272693,https://api.github.com/repos/simonw/datasette/issues/1238,855272693,MDEyOklzc3VlQ29tbWVudDg1NTI3MjY5Mw==,9599,2021-06-05T17:45:42Z,2021-06-05T17:45:42Z,OWNER,"Applying this fix worked when I manually tested it: ```diff base_url = self.ds.setting(""base_url"") if base_url != ""/"" and path.startswith(base_url): path = ""/"" + path[len(base_url) :] + scope = dict(scope, path=path, raw_path=path.encode(""utf-8"")) request = Request(scope, receive) ``` But... the test I wrote still failed. My hunch is that this is because deep within the test framework requests go through `ds.client` which may be applying its own changes relevant to `base_url`: https://github.com/simonw/datasette/blob/6e9b07be92905011211d8df7a872fb7c1f2737b2/datasette/utils/testing.py#L139","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",813899472, https://github.com/simonw/datasette/issues/1238#issuecomment-855270917,https://api.github.com/repos/simonw/datasette/issues/1238,855270917,MDEyOklzc3VlQ29tbWVudDg1NTI3MDkxNw==,9599,2021-06-05T17:32:29Z,2021-06-05T17:32:29Z,OWNER,"This looks like the cause: https://github.com/simonw/datasette/blob/6e9b07be92905011211d8df7a872fb7c1f2737b2/datasette/app.py#L1087-L1092 Note how `path` is modified... but then we create a new `Request()` that uses the old scope, which has unmodified `scope[""path""]` - and then the code later on looks at `request.scope[""path""]` when deciding if the request matches: https://github.com/simonw/datasette/blob/afed51b1e36cf275c39e71c7cb262d6c5bdbaa31/datasette/app.py#L1154-L1155","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",813899472,