# 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