This commit is contained in:
retoor 2025-11-14 01:59:01 +01:00
parent de9cd8d1ba
commit 57c37750ec
2 changed files with 17 additions and 2 deletions

View File

@ -2,9 +2,9 @@ import argparse
import uvicorn import uvicorn
import logging import logging
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from fastapi import FastAPI, Request, HTTPException from fastapi import FastAPI, Request, HTTPException, status
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, JSONResponse from fastapi.responses import HTMLResponse, JSONResponse, Response
from tortoise.contrib.fastapi import register_tortoise from tortoise.contrib.fastapi import register_tortoise
from .settings import settings from .settings import settings
from .routers import ( from .routers import (
@ -131,9 +131,22 @@ async def http_exception_handler(request: Request, exc: HTTPException):
logger.error( logger.error(
f"HTTPException: {exc.status_code} - {exc.detail} for URL: {request.url}" f"HTTPException: {exc.status_code} - {exc.detail} for URL: {request.url}"
) )
headers = exc.headers
# For WebDAV authentication challenges, we must return the headers
# from the exception and an empty body. A JSON body will confuse WebDAV clients.
if request.url.path.startswith("/webdav") and exc.status_code == status.HTTP_401_UNAUTHORIZED:
return Response(status_code=exc.status_code, headers=headers)
# For other WebDAV errors, it's better to return a text body than JSON
if request.url.path.startswith("/webdav"):
return Response(content=exc.detail, status_code=exc.status_code, headers=headers)
return JSONResponse( return JSONResponse(
status_code=exc.status_code, status_code=exc.status_code,
content=ErrorResponse(code=exc.status_code, message=exc.detail).model_dump(), content=ErrorResponse(code=exc.status_code, message=exc.detail).model_dump(),
headers=headers,
) )

View File

@ -76,6 +76,8 @@ async def test_webdav_propfind_root_unauthorized():
) )
assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert "WWW-Authenticate" in response.headers
assert 'Basic realm="MyWebdav WebDAV"' in response.headers["WWW-Authenticate"]
@pytest.mark.asyncio @pytest.mark.asyncio