diff --git a/backend/coreapp/middleware.py b/backend/coreapp/middleware.py index 3c4e139de..84c5edd20 100644 --- a/backend/coreapp/middleware.py +++ b/backend/coreapp/middleware.py @@ -42,31 +42,35 @@ def middleware(request: HttpRequest) -> Response: return middleware -def is_public_request(req: Request) -> bool: - methods_paths = [ - ("GET", "/api/compiler"), - ("GET", "/api/library"), - ("GET", "/api/platform"), - ("GET", "/api/preset"), - ("GET", "/api/scratch-count$"), - ("GET", "/api/scratch/[A-Za-z0-9]+/compile$"), - ("GET", "/api/scratch/[A-Za-z0-9]+/export$"), - ("GET", "/api/scratch/[A-Za-z0-9]+/family$"), - ("GET", "/api/scratch/[A-Za-z0-9]+$"), - ("GET", "/api/scratch$"), - ("GET", "/api/search$"), - ("GET", "/api/stats$"), - ("GET", "/api/users"), +def is_public_get_request(req: Request) -> bool: + public_paths = [ + "/api/compiler", + "/api/library", + "/api/platform", + "/api/preset", + "/api/scratch-count$", + "/api/scratch/[A-Za-z0-9]+/compile$", + "/api/scratch/[A-Za-z0-9]+/export$", + "/api/scratch/[A-Za-z0-9]+/family$", + "/api/scratch/[A-Za-z0-9]+$", + "/api/scratch$", + "/api/search$", + "/api/stats$", + "/api/users", ] - for method, path in methods_paths: - if req.method == method and re.match(path, req.path): + for path in public_paths: + if req.method == "GET" and re.match(path, req.path): return True return False def is_ephemeral_profile_request(req: Request) -> bool: - return req.method == "GET" and req.path == "/api/user" and not req.COOKIES + return ( + req.method in ("GET", "HEAD") + and req.path == "/api/user" + and "sessionid" not in req.COOKIES + ) def set_user_profile( @@ -87,6 +91,7 @@ def middleware(request: Request) -> Response: "YandexRenderResourcesBot", "SentryUptimeBot", "Discord", + "Wget", ] # Avoid creating persistent profiles for SSR or bots @@ -99,6 +104,11 @@ def middleware(request: Request) -> Response: request.profile = Profile() return get_response(request) + # Avoid creating persistent profiles on HEAD or OPTIONS requests + if request.method in ("HEAD", "OPTIONS"): + request.profile = Profile() + return get_response(request) + profile = None # Try user-linked profile @@ -117,7 +127,7 @@ def middleware(request: Request) -> Response: request.user = profile.user # Avoid creating persistent profiles for public endpoints - if not profile and is_public_request(request): + if not profile and is_public_get_request(request): request.profile = Profile() return get_response(request) @@ -176,7 +186,7 @@ def strip_session( ) -> Callable[[Request], Response]: def middleware(request: Request) -> Response: response = get_response(request) - if is_public_request(request): + if is_public_get_request(request): response.cookies.clear() return response