mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
add aurweb.asgi.id_redirect_middleware
A new middleware which redirects requests going to '/route?id=some_id' to '/route/some_id'. In the FastAPI application, we'll prefer using restful layouts where possible where resource-based ids are parameters of the request uri: '/route/{resource_id}'. Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
e534704a98
commit
dc4cc9b604
2 changed files with 32 additions and 0 deletions
|
@ -2,6 +2,8 @@ import asyncio
|
||||||
import http
|
import http
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
|
from urllib.parse import quote_plus
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Request
|
from fastapi import FastAPI, HTTPException, Request
|
||||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
@ -120,3 +122,23 @@ async def check_terms_of_service(request: Request, call_next: typing.Callable):
|
||||||
task = asyncio.create_task(call_next(request))
|
task = asyncio.create_task(call_next(request))
|
||||||
await asyncio.wait({task}, return_when=asyncio.FIRST_COMPLETED)
|
await asyncio.wait({task}, return_when=asyncio.FIRST_COMPLETED)
|
||||||
return task.result()
|
return task.result()
|
||||||
|
|
||||||
|
|
||||||
|
@app.middleware("http")
|
||||||
|
async def id_redirect_middleware(request: Request, call_next: typing.Callable):
|
||||||
|
id = request.query_params.get("id")
|
||||||
|
|
||||||
|
if id is not None:
|
||||||
|
# Preserve query string.
|
||||||
|
qs = []
|
||||||
|
for k, v in request.query_params.items():
|
||||||
|
if k != "id":
|
||||||
|
qs.append(f"{k}={quote_plus(str(v))}")
|
||||||
|
qs = str() if not qs else '?' + '&'.join(qs)
|
||||||
|
|
||||||
|
path = request.url.path.rstrip('/')
|
||||||
|
return RedirectResponse(f"{path}/{id}{qs}")
|
||||||
|
|
||||||
|
task = asyncio.create_task(call_next(request))
|
||||||
|
await asyncio.wait({task}, return_when=asyncio.FIRST_COMPLETED)
|
||||||
|
return task.result()
|
||||||
|
|
|
@ -148,3 +148,13 @@ def test_nonce_csp():
|
||||||
if not (nonce_verified := (script.get("nonce") == nonce)):
|
if not (nonce_verified := (script.get("nonce") == nonce)):
|
||||||
break
|
break
|
||||||
assert nonce_verified is True
|
assert nonce_verified is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_id_redirect():
|
||||||
|
with client as request:
|
||||||
|
response = request.get("/", params={
|
||||||
|
"id": "test", # This param will be rewritten into Location.
|
||||||
|
"key": "value", # Test that this param persists.
|
||||||
|
"key2": "value2" # And this one.
|
||||||
|
}, allow_redirects=False)
|
||||||
|
assert response.headers.get("location") == "/test?key=value&key2=value2"
|
||||||
|
|
Loading…
Add table
Reference in a new issue