fix: UploadFile ForwardRef + WebSocket 403 — root cause fixed
1. plugin_error_handler.py: Remove _UploadFile alias, import UploadFile directly
so FastAPI can resolve ForwardRef('UploadFile') in the wrapper's namespace.
Also import WebSocket for ForwardRef resolution.
2. main.py: Skip WebSocket routes in wrap_plugin_route — WebSocket endpoints
must not be wrapped (different protocol, no JSONResponse on error)
This commit is contained in:
@@ -2,7 +2,8 @@
|
|||||||
import logging
|
import logging
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
from fastapi import UploadFile as _UploadFile # noqa: F401 — needed for ForwardRef resolution
|
from fastapi import UploadFile # noqa: F401 — needed for ForwardRef resolution
|
||||||
|
from fastapi import WebSocket # noqa: F401 — needed for ForwardRef resolution of WebSocket params
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
+6
-1
@@ -11,6 +11,7 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
from fastapi.responses import FileResponse, JSONResponse
|
from fastapi.responses import FileResponse, JSONResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from starlette.middleware.base import BaseHTTPMiddleware
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
|
from starlette.routing import WebSocketRoute
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@@ -434,8 +435,12 @@ def create_app() -> FastAPI:
|
|||||||
try:
|
try:
|
||||||
router_module = importlib.import_module(route_def.module)
|
router_module = importlib.import_module(route_def.module)
|
||||||
router = getattr(router_module, route_def.router_attr)
|
router = getattr(router_module, route_def.router_attr)
|
||||||
# Wrap each route handler with plugin error isolation
|
# Wrap each HTTP route handler with plugin error isolation
|
||||||
|
# Skip WebSocket routes — the wrapper breaks WS parameter
|
||||||
|
# resolution and returns JSONResponse instead of WS close.
|
||||||
for route in router.routes:
|
for route in router.routes:
|
||||||
|
if isinstance(route, WebSocketRoute):
|
||||||
|
continue
|
||||||
if hasattr(route, 'endpoint'):
|
if hasattr(route, 'endpoint'):
|
||||||
route.endpoint = wrap_plugin_route(route.endpoint)
|
route.endpoint = wrap_plugin_route(route.endpoint)
|
||||||
# Add active-plugin check as a router-level dependency
|
# Add active-plugin check as a router-level dependency
|
||||||
|
|||||||
Reference in New Issue
Block a user