mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Re-implemented redirect on 404 with trailing slash, refs #272
All of the tests now pass
This commit is contained in:
parent
d2daa1b9f7
commit
5bd510b01a
3 changed files with 23 additions and 13 deletions
|
|
@ -36,7 +36,7 @@ from .utils import (
|
|||
sqlite_timelimit,
|
||||
to_css_class,
|
||||
)
|
||||
from .utils.asgi import asgi_static, asgi_send_html, asgi_send_json
|
||||
from .utils.asgi import asgi_static, asgi_send_html, asgi_send_json, asgi_send_redirect
|
||||
from .tracer import capture_traces, trace
|
||||
from .plugins import pm, DEFAULT_PLUGINS
|
||||
from .version import __version__
|
||||
|
|
@ -652,6 +652,17 @@ class Datasette:
|
|||
outer_self = self
|
||||
|
||||
class DatasetteRouter(AsgiRouter):
|
||||
async def handle_404(self, scope, receive, send):
|
||||
# If URL has a trailing slash, redirect to URL without it
|
||||
path = scope.get("raw_path", scope["path"].encode("utf8"))
|
||||
if path.endswith(b"/"):
|
||||
path = path.rstrip(b"/")
|
||||
if scope["query_string"]:
|
||||
path += b"?" + scope["query_string"]
|
||||
await asgi_send_redirect(send, path.decode("latin1"))
|
||||
else:
|
||||
await super().handle_404(scope, receive, send)
|
||||
|
||||
async def handle_500(self, scope, receive, send, exception):
|
||||
title = None
|
||||
help = None
|
||||
|
|
@ -693,17 +704,6 @@ class Datasette:
|
|||
)
|
||||
|
||||
app = DatasetteRouter(routes)
|
||||
# On 404 with a trailing slash redirect to path without that slash:
|
||||
# pylint: disable=unused-variable
|
||||
# TODO: re-enable this
|
||||
# @app.middleware("response")
|
||||
# def redirect_on_404_with_trailing_slash(request, original_response):
|
||||
# if original_response.status == 404 and request.path.endswith("/"):
|
||||
# path = request.path.rstrip("/")
|
||||
# if request.query_string:
|
||||
# path = "{}?{}".format(path, request.query_string)
|
||||
# return response.redirect(path)
|
||||
|
||||
# First time server starts up, calculate table counts for immutable databases
|
||||
# TODO: re-enable this mechanism
|
||||
# @app.listener("before_server_start")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import json
|
||||
from mimetypes import guess_type
|
||||
from sanic.views import HTTPMethodView
|
||||
from sanic.request import Request as SanicRequest
|
||||
from pathlib import Path
|
||||
import re
|
||||
import aiofiles
|
||||
|
|
@ -166,6 +167,16 @@ async def asgi_send_html(send, html, status=200, headers=None):
|
|||
)
|
||||
|
||||
|
||||
async def asgi_send_redirect(send, location, status=302):
|
||||
await asgi_send(
|
||||
send,
|
||||
"",
|
||||
status=status,
|
||||
headers={"Location": location},
|
||||
content_type="text/html",
|
||||
)
|
||||
|
||||
|
||||
async def asgi_send(send, content, status, headers, content_type="text/plain"):
|
||||
await asgi_start(send, status, headers, content_type)
|
||||
await send({"type": "http.response.body", "body": content.encode("utf8")})
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import jinja2
|
|||
import pint
|
||||
from sanic import response
|
||||
from sanic.exceptions import NotFound
|
||||
from sanic.request import Request as SanicRequest
|
||||
|
||||
from html import escape
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue