From 7bb30c1f11f7246baf7bb6a229f6b93572c4cbe3 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Thu, 28 May 2020 10:09:32 -0700 Subject: [PATCH] request.url now respects force_https_urls, closes #781 --- datasette/app.py | 7 +++++++ tests/plugins/my_plugin_2.py | 3 +++ tests/test_api.py | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/datasette/app.py b/datasette/app.py index 40d39ac965..07190c1644 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -786,6 +786,13 @@ async def route_path(self, scope, receive, send, path): base_url = self.ds.config("base_url") if base_url != "/" and path.startswith(base_url): path = "/" + path[len(base_url) :] + # Apply force_https_urls, if set + if ( + self.ds.config("force_https_urls") + and scope["type"] == "http" + and scope.get("scheme") != "https" + ): + scope = dict(scope, scheme="https") return await super().route_path(scope, receive, send, path) async def handle_404(self, scope, receive, send, exception=None): diff --git a/tests/plugins/my_plugin_2.py b/tests/plugins/my_plugin_2.py index fdc6956de1..c9e7c78f1e 100644 --- a/tests/plugins/my_plugin_2.py +++ b/tests/plugins/my_plugin_2.py @@ -46,6 +46,9 @@ def render_cell(value, database): @hookimpl def extra_template_vars(template, database, table, view_name, request, datasette): + # This helps unit tests that want to run assertions against the request object: + datasette._last_request = request + async def query_database(sql): first_db = list(datasette.databases.keys())[0] return (await datasette.execute(first_db, sql)).rows[0][0] diff --git a/tests/test_api.py b/tests/test_api.py index eb80f8e7ef..d7e7c03f5e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1676,6 +1676,10 @@ def test_config_force_https_urls(): "toggle_url" ].startswith("https://") assert response.json["suggested_facets"][0]["toggle_url"].startswith("https://") + # Also confirm that request.url and request.scheme are set correctly + response = client.get("/") + assert client.ds._last_request.url.startswith("https://") + assert client.ds._last_request.scheme == "https" def test_infinity_returned_as_null(app_client):