64 lines
2.2 KiB
Python
64 lines
2.2 KiB
Python
# middleware/path_rewrite_middleware.py
|
|
"""
|
|
Path Rewrite Middleware
|
|
|
|
Rewrites request paths for path-based vendor routing.
|
|
This allows /vendor/VENDORCODE/shop/products to be routed as /shop/products
|
|
|
|
MUST run AFTER vendor_context_middleware and BEFORE context_middleware.
|
|
"""
|
|
import logging
|
|
from fastapi import Request
|
|
from starlette.datastructures import URL
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def path_rewrite_middleware(request: Request, call_next):
|
|
"""
|
|
Middleware to rewrite request paths for vendor context.
|
|
|
|
If vendor_context_middleware set request.state.clean_path, this middleware
|
|
will rewrite the request path to use the clean path instead.
|
|
|
|
This allows FastAPI route matching to work correctly with path-based routing.
|
|
|
|
Example:
|
|
Original: /vendor/WIZAMART/shop/products
|
|
Clean path: /shop/products
|
|
After rewrite: Request is routed as if path was /shop/products
|
|
|
|
MUST run after vendor_context_middleware (which sets clean_path)
|
|
MUST run before context_middleware (which needs to see the clean path)
|
|
"""
|
|
|
|
# Check if vendor_context_middleware set a clean_path
|
|
if hasattr(request.state, 'clean_path'):
|
|
clean_path = request.state.clean_path
|
|
original_path = request.url.path
|
|
|
|
# Only rewrite if clean_path is different from original path
|
|
if clean_path != original_path:
|
|
logger.debug(
|
|
f"[PATH_REWRITE] Rewriting path",
|
|
extra={
|
|
"original_path": original_path,
|
|
"clean_path": clean_path,
|
|
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
|
}
|
|
)
|
|
|
|
# Rewrite the path by modifying the request's scope
|
|
# This affects how FastAPI's router will see the path
|
|
request.scope['path'] = clean_path
|
|
|
|
# Also update request._url to reflect the change
|
|
# This ensures request.url.path returns the rewritten path
|
|
old_url = request.url
|
|
new_url = old_url.replace(path=clean_path)
|
|
request._url = new_url
|
|
|
|
# Continue to next middleware/handler
|
|
response = await call_next(request)
|
|
return response
|