login: sync def so the 0.5s brute-force sleep runs on the threadpool, not the event loop (+latency regression test)

This commit is contained in:
jozamudi committed 2026-09-16 00:49:22 +00:00
1 parent 9a4b8fb299
commit 673aca827f
2 files changed
+29 -1

No files matched your search

+5 -1
View File
@@ -125,6 +125,7 @@ _SESSION_AGE = 30 * 86400
_PUBLIC = {("/login", "GET"), ("/login", "POST"), ("/api/cdn", "GET")}
_SECURE = os.environ.get("ANIWEB_SECURE") == "1" # set when served over HTTPS
# ponytail: in-memory lockout per username, single process — 5 fails -> 15 min
# ponytail: in-memory lockout per username, single process — 5 fails -> 15 min
_lockout: dict = {}
@@ -193,7 +194,10 @@ def login_page():
@app.post("/login")
async def login(payload: dict = Body(...)):
def login(payload: dict = Body(...)):
# SYNC def on purpose: _lock's 0.5s anti-brute-force sleep must run on
# uvicorn's threadpool — as async def it ran ON the event loop and every
# wrong password stalled every in-flight request (streams included).
u = payload.get("username", "").lower()
if not u:
return JSONResponse({"detail": "username required"}, status_code=400)