nakama/moderation/backend-py/middleware.py

74 lines
2.2 KiB
Python
Raw Permalink Normal View History

2025-12-14 23:45:41 +00:00
"""
Middleware for FastAPI application
"""
import time
import logging
from typing import Callable
from fastapi import Request, Response
from fastapi.responses import JSONResponse
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
# Setup logging
logging.basicConfig(
level=logging.INFO,
format='[%(asctime)s] %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
# Rate limiter
limiter = Limiter(key_func=get_remote_address)
async def log_requests(request: Request, call_next: Callable):
"""Log all incoming requests"""
start_time = time.time()
# Log request
logger.info(f"🔍 [DEBUG] Incoming request {{method: '{request.method}', path: '{request.url.path}', ip: '{request.client.host}'}}")
# Process request
response = await call_next(request)
# Calculate duration
duration = int((time.time() - start_time) * 1000)
# Log response
status_emoji = "📝" if 200 <= response.status_code < 300 else "⚠️" if 400 <= response.status_code < 500 else ""
level = "INFO" if 200 <= response.status_code < 300 else "WARN" if 400 <= response.status_code < 500 else "ERROR"
logger.log(
getattr(logging, level),
f"{status_emoji} [{level}] Request completed {{method: '{request.method}', path: '{request.url.path}', status: {response.status_code}, duration: '{duration}ms'}}"
)
return response
async def security_headers(request: Request, call_next: Callable):
"""Add security headers"""
response = await call_next(request)
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-XSS-Protection'] = '1; mode=block'
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
return response
def setup_middleware(app):
"""Setup all middleware"""
# Request logging
app.middleware("http")(log_requests)
# Security headers
app.middleware("http")(security_headers)
# Rate limiting
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)