github
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/1590#issuecomment-1010533133 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1010533133 | IC_kwDOBm6k_c48O4MN | 9599 | 2022-01-12T01:19:19Z | 2022-01-12T01:19:19Z | OWNER | Thanks for the steps to reproduce - I have your bug running on my laptop now. I've been mostly testing this stuff using the hosted copy of Datasette here, which doesn't exhibit the bug: https://datasette-apache-proxy-demo.fly.dev/prefix/fixtures?sql=select+sqlite_version%28%29 Something interesting definitely going on here! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1010537058 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1010537058 | IC_kwDOBm6k_c48O5Ji | 9599 | 2022-01-12T01:26:34Z | 2022-01-12T01:26:34Z | OWNER | I'm using the https://datasette.io/plugins/datasette-debug-asgi plugin to investigate. On my laptop using Daphne I get this: http://127.0.0.1:8032/datasettes/-/asgi-scope ``` {'actor': None, 'asgi': {'version': '3.0'}, 'client': ['127.0.0.1', 53767], 'csrftoken': <function asgi_csrf_decorator.<locals>._asgi_csrf_decorator.<locals>.app_wrapped_with_csrf.<locals>.get_csrftoken at 0x1122aeef0>, 'headers': [(b'host', b'127.0.0.1:8032'), (b'user-agent', b'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko' b'/20100101 Firefox/95.0'), (b'accept', b'text/html,application/xhtml+xml,application/xml;q=0.9,image/' b'avif,image/webp,*/*;q=0.8'), (b'accept-language', b'en-US,en;q=0.5'), (b'accept-encoding', b'gzip, deflate'), (b'dnt', b'1'), (b'connection', b'keep-alive'), (b'cookie', b'_ga=GA1.1.742283954.1628542653'), (b'upgrade-insecure-requests', b'1'), (b'sec-fetch-dest', b'document'), (b'sec-fetch-mode', b'navigate'), (b'sec-fetch-site', b'none'), (b'sec-fetch-user', b'?1')], 'http_version': '1.1', 'method': 'GET', 'path': '/datasettes/-/asgi-scope', 'path_remaining': '', 'query_string': b'', 'raw_path': b'/datasettes/-/asgi-scope', 'root_path': '', 'route_path': '/-/asgi-scope', 'scheme': 'http', 'server': ['127.0.0.1', 8032], 'type': 'http', 'url_route': {'kwargs': {}}} ``` On the demo running on Fly (which I just redeployed with that plugin) I get this: https://datasette-apache-proxy-demo.fly.dev/prefix/-/asgi-scope ``` {'actor': None, 'asgi': {'spec_version': '2.1', 'version': '3.0'}, 'client': ('86.109.12.167', 0), 'csrftoken': <function asgi_csrf_decorator.<locals>._asgi_csrf_decorator.<locals>.app_wrapped_with_csrf.<locals>.get_csrftoken at 0x7f4c0413bca0>, 'headers': [(b'host', b'datasette-apache-proxy-demo.fly.dev'), … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1010538016 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1010538016 | IC_kwDOBm6k_c48O5Yg | 9599 | 2022-01-12T01:28:19Z | 2022-01-12T01:28:19Z | OWNER | The Daphne one has this key: `'route_path': '/-/asgi-scope',` Maybe Datasette's routing code needs to look out for that, if it's available, and use it to reconstruct the requested path? The code in question is here: https://github.com/simonw/datasette/blob/8c401ee0f054de2f568c3a8302c9223555146407/datasette/app.py#L1143-L1149 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1010538188 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1010538188 | IC_kwDOBm6k_c48O5bM | 9599 | 2022-01-12T01:28:41Z | 2022-01-12T01:30:43Z | OWNER | Oh wait! It looks like `route_path` is something I invented there. Yup, I added it in https://github.com/simonw/datasette/commit/a63412152518581c6a3d4e142b937e27dabdbfdb - commit message says: > - new `route_path` key in `request.scope` storing the path that was used for routing with the `base_url` prefix stripped So actually part of the mystery here is: why does the Fly hosted one NOT have that key? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1010540923 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1010540923 | IC_kwDOBm6k_c48O6F7 | 9599 | 2022-01-12T01:33:49Z | 2022-01-12T01:33:49Z | OWNER | Looking closer at the code quoted above, it doesn't modify `path` or `raw_path` at all - ALL it does is add the `route_path` to the scope. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1012583091 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1012583091 | IC_kwDOBm6k_c48Wsqz | 9599 | 2022-01-13T22:41:15Z | 2022-01-13T22:41:15Z | OWNER | Seeing as this area of the code has produced so many bugs in the past, I think part of the fix may be to write comprehensive documentation about how routing works for the internals documentation. Doing so might help me figure this bug out! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1012653966 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1012653966 | IC_kwDOBm6k_c48W9-O | 9599 | 2022-01-14T00:59:07Z | 2022-01-14T00:59:07Z | OWNER | Since this is a special case bug for when using Datasette as a library I wonder if a good fix here would be to support something like this: ```python application = URLRouter([ re_path(r"^datasettes/.*", asgi_cors(datasette_.app(remove_path_prefix="datasettes/"), allow_all=True)), ]) ``` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1012656790 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1012656790 | IC_kwDOBm6k_c48W-qW | 9599 | 2022-01-14T01:05:34Z | 2022-01-14T01:05:34Z | OWNER | I think this prefixed string mechanism is supposed to prevent the `base_url` prefix from being applied twice: https://github.com/simonw/datasette/blob/3664ddd400062123e99500d28b160c7944408c1a/datasette/url_builder.py#L9-L16 But with a bit of extra logging all of the inputs to that are NOT prefixed strings: ``` Urls.path called with: /datasettes/fixtures/compound_three_primary_keys?_sort=content (PrefixedUrlString = False) returning /datasettes/datasettes/fixtures/compound_three_primary_keys?_sort=content ``` So it looks like `urls.path(...)` is indeed the code responsible for doubling up that `/datasettes/` prefix. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 | |
https://github.com/simonw/datasette/issues/1590#issuecomment-1012661522 | https://api.github.com/repos/simonw/datasette/issues/1590 | 1012661522 | IC_kwDOBm6k_c48W_0S | 9599 | 2022-01-14T01:16:08Z | 2022-01-14T01:16:34Z | OWNER | OK, I'm going to recommend a workaround for this instead. Here's `asgi.py` updated to strip the prefix before passing the request on to Datasette: ```python import pathlib from asgi_cors import asgi_cors from channels.routing import URLRouter from django.urls import re_path from datasette.app import Datasette def rewrite_path(app, prefix_to_strip): async def rewrite_path_app(scope, receive, send): if ( scope["type"] == "http" and "path" in scope and scope["path"].startswith(prefix_to_strip) ): scope["path"] = scope["path"][len(prefix_to_strip) :] if "raw_path" in scope: scope["raw_path"] = scope["raw_path"][len(prefix_to_strip) :] await app(scope, receive, send) return rewrite_path_app datasette_ = Datasette( files=["fixtures.db"], settings={"base_url": "/datasettes/", "plugins": {}}, ) application = URLRouter( [ re_path( r"^datasettes/.*", asgi_cors(rewrite_path(datasette_.app(), "/datasettes"), allow_all=True), ), ] ) ``` This works on my laptop - please re-open the ticket if it doesn't work for you! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
1099723916 |