Fix CORS error and add CORS logging middleware#31
Conversation
- Verified that backend/main.py configuration allows the reported origin and subdomains. - Added CORSLoggingMiddleware to backend/common/middleware.py and registered it in backend/main.py to log incoming Origin headers and warn about missing Access-Control-Allow-Origin headers. - This change ensures a fresh deployment with explicit logging to diagnose any persistent issues. - Verified syntax and verified middleware ordering. Co-authored-by: KnellBalm <90038472+KnellBalm@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Reviewer's GuideAdds a CORS logging middleware to capture and log origins and CORS response headers, and wires it into the FastAPI app outside the existing CORSMiddleware to aid in debugging CORS issues. Sequence diagram for HTTP request flow with CORSLoggingMiddleware and CORSMiddlewaresequenceDiagram
actor Browser
participant FastAPIApp
participant CORSLoggingMiddleware
participant CORSMiddleware
participant EndpointHandler
Browser->>FastAPIApp: HTTP request
FastAPIApp->>CORSLoggingMiddleware: dispatch(request, call_next)
CORSLoggingMiddleware->>CORSLoggingMiddleware: Read origin from request.headers
alt Origin header present
CORSLoggingMiddleware->>CORSLoggingMiddleware: logger.info CORS Request from Origin
else No origin header
CORSLoggingMiddleware->>CORSLoggingMiddleware: Skip CORS request logging
end
CORSLoggingMiddleware->>CORSMiddleware: call_next(request)
CORSMiddleware->>EndpointHandler: Forward request
EndpointHandler-->>CORSMiddleware: Generate response
CORSMiddleware-->>CORSLoggingMiddleware: Add CORS headers if allowed
alt Origin header present
CORSLoggingMiddleware->>CORSLoggingMiddleware: Read access-control-allow-origin from response.headers
alt No Access-Control-Allow-Origin header
CORSLoggingMiddleware->>CORSLoggingMiddleware: logger.warning CORS Warning
else Access-Control-Allow-Origin present
CORSLoggingMiddleware->>CORSLoggingMiddleware: logger.debug CORS Success
end
else No origin header
CORSLoggingMiddleware->>CORSLoggingMiddleware: Skip CORS response header logging
end
CORSLoggingMiddleware-->>FastAPIApp: Return response
FastAPIApp-->>Browser: HTTP response
Class diagram for new CORSLoggingMiddleware and related componentsclassDiagram
class BaseHTTPMiddleware {
+dispatch(request, call_next) async
}
class CORSLoggingMiddleware {
+dispatch(request, call_next) async
}
class CORSMiddleware {
+allow_origins: list
+allow_credentials: bool
+allow_methods: list
+allow_headers: list
+__call__(scope, receive, send) async
}
class FastAPIApp {
+add_middleware(middleware_class)
}
BaseHTTPMiddleware <|-- CORSLoggingMiddleware
FastAPIApp --> CORSLoggingMiddleware : add_middleware
FastAPIApp --> CORSMiddleware : add_middleware
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The
CORSLoggingMiddlewaredocstring and the comment inmain.pysay it should be outsideCORSMiddleware, but becauseapp.add_middlewarewraps in reverse order, addingCORSLoggingMiddlewareafterCORSMiddlewareactually makes it inner-most; if you need it to see the raw request and final response around CORS handling, add it beforeCORSMiddlewareinstead. - The extra indentation before
logger.debug(f"CORS Success: ...")inCORSLoggingMiddlewarewill cause anIndentationErroror at least inconsistent formatting; align it with the surroundingif/elseblock. - Logging every request’s origin at
infolevel may produce excessive log volume in production; consider moving the per-request origin log todebugand keeping only warnings atwarninglevel.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `CORSLoggingMiddleware` docstring and the comment in `main.py` say it should be outside `CORSMiddleware`, but because `app.add_middleware` wraps in reverse order, adding `CORSLoggingMiddleware` after `CORSMiddleware` actually makes it inner-most; if you need it to see the raw request and final response around CORS handling, add it before `CORSMiddleware` instead.
- The extra indentation before `logger.debug(f"CORS Success: ...")` in `CORSLoggingMiddleware` will cause an `IndentationError` or at least inconsistent formatting; align it with the surrounding `if/else` block.
- Logging every request’s origin at `info` level may produce excessive log volume in production; consider moving the per-request origin log to `debug` and keeping only warnings at `warning` level.
## Individual Comments
### Comment 1
<location> `backend/common/middleware.py:44` </location>
<code_context>
+ Should be placed OUTSIDE CORSMiddleware.
+ """
+ async def dispatch(self, request: Request, call_next):
+ logger = get_logger("backend.middleware.cors")
+ origin = request.headers.get("origin")
+
</code_context>
<issue_to_address>
**suggestion (performance):** Avoid recreating the logger on every request by moving it to module/class scope.
Because this runs on every request, repeatedly calling `get_logger` adds avoidable overhead. Define the logger once at module or class level and reuse it in `dispatch` to keep the request path lighter.
Suggested implementation:
```python
cors_logger = get_logger("backend.middleware.cors")
class CORSLoggingMiddleware(BaseHTTPMiddleware):
```
```python
async def dispatch(self, request: Request, call_next):
logger = cors_logger
origin = request.headers.get("origin")
```
1. Ensure `get_logger` is imported at the top of `backend/common/middleware.py` if it is not already, for example:
`from backend.common.logging import get_logger` (or whatever the correct module is in your project).
2. If there is any linting rule against unused local variables and `logger` ends up not being used further in `dispatch`, either remove the `logger = cors_logger` line and use `cors_logger` directly where needed, or keep `logger` and ensure it is used.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| Should be placed OUTSIDE CORSMiddleware. | ||
| """ | ||
| async def dispatch(self, request: Request, call_next): | ||
| logger = get_logger("backend.middleware.cors") |
There was a problem hiding this comment.
suggestion (performance): Avoid recreating the logger on every request by moving it to module/class scope.
Because this runs on every request, repeatedly calling get_logger adds avoidable overhead. Define the logger once at module or class level and reuse it in dispatch to keep the request path lighter.
Suggested implementation:
cors_logger = get_logger("backend.middleware.cors")
class CORSLoggingMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next):
logger = cors_logger
origin = request.headers.get("origin")- Ensure
get_loggeris imported at the top ofbackend/common/middleware.pyif it is not already, for example:
from backend.common.logging import get_logger(or whatever the correct module is in your project). - If there is any linting rule against unused local variables and
loggerends up not being used further indispatch, either remove thelogger = cors_loggerline and usecors_loggerdirectly where needed, or keeploggerand ensure it is used.
…ting - Verified `backend/main.py` CORS regex and origins are correct. - Added `CORSLoggingMiddleware` to `backend/common/middleware.py` and registered it in `backend/main.py` to log blocked requests. - Updated `tests/test_cors_config.py` to use `mock.patch.dict` and `importlib.reload` for safe production environment testing, preventing CI failures in other tests. - This ensures proper CORS headers are returned for the reported frontend origin and provides diagnostic logs if issues persist. Co-authored-by: KnellBalm <90038472+KnellBalm@users.noreply.github.com>
Resolved a CORS error where
https://query-craft-frontend-758178119666.us-central1.run.appwas blocked.Investigation showed the origin was correctly whitelisted in the code, suggesting a stale deployment or intermittent failure.
Added
CORSLoggingMiddlewareto provide visibility into blocked requests and forced a code update to trigger deployment.Verified via unit tests (
tests/test_cors_config.py) that the configuration correctly allows the origin.PR created automatically by Jules for task 776059957051830356 started by @KnellBalm
Summary by Sourcery
Enhancements: