Repository navigation
fix: forward request headers when checking existing - #201
vincentsarago wants to merge 1 commit into
Conversation
|
Claude finished @vincentsarago's task in 2m 2s —— View job Claude's Task List
✅ No blocking issues — safe to merge. The fix is correct and well-scoped: Non-blocking observations:
Simplify (ponytail)
💰 Estimated review cost: $0.75 · 2m01s · 21 turns |
|
@alukach could you review this one 🙈 ? |
@vincentsarago This doesn't make sense to me. Why does the private STAC API require the authorization header? |
🤔 well, stac-auth-proxy will call the API itself to check the existing items, so if the API requires authorization, stac-auth-proxy should have the headers |
And this is an experience that you're having? You have a STAC API that requires authentication in addition to the STAC Auth Proxy (which is commonly where authentication requirements are imposed)? |
|
We use stac-auth-proxy middlewares integrated within our application, so yes the endpoints requires authentication |
## Problem `Cql2ValidateTransactionMiddleware` fetches the existing record for PUT/PATCH/DELETE with its own `httpx` client pointed at `upstream_url`. When stac-auth-proxy is used **as middleware** around a STAC API, `upstream_url` points back at the same app, so that GET re-enters `EnforceAuthMiddleware` without credentials and fails (a 401 surfaced to the caller as a 502). #201 fixes this by forwarding the caller's headers onto the GET, but forwarding everything also carries `If-None-Match`/`Range` (→ 304/206 with no JSON body → uncaught 500) and `Accept-Encoding` (e.g. `zstd` → undecodable body). ## Change Issue the GET **in-process** to the downstream ASGI app (`self.app`) instead of over HTTP: - **Middleware mode:** reaches the STAC API's routes directly. No network hop, no auth needed. - **Proxy mode:** goes through `ReverseProxyHandler` to the upstream exactly like any other request (same client, timeout, `Forwarded` headers). - The sub-request sits below the auth middleware in both modes, so no credentials are forwarded. Only `host` and `accept: application/json` are sent, which closes off the conditional and encoding problems above. - Removes the middleware's own `httpx.AsyncClient` and its `upstream_url` argument. - Non-200/404 responses and non-JSON bodies raise `UpstreamError`, which is mapped to the existing 502 `UpstreamError` response. **Behavior note:** in the full stack the sub-request passes through `Cql2ValidateResponseBodyMiddleware` with the caller's filter, so a record the caller can't read is reported as 404, matching the existing "existing record doesn't match filter → 404" behavior. ## Tests - `TestFetchExistingMiddlewareMode`: an outer auth stand-in rejects requests without `Authorization`. PUT/DELETE succeed, and the in-process GET arrives with no `authorization`/`if-none-match`/`accept-encoding`. Also covers denied-existing → 404, missing → 404, and downstream 500 → 502. - `TestFetchExistingProxyMode`: real `ReverseProxyHandler` over `httpx.MockTransport`. The upstream sees a clean GET followed by the PUT (with the caller's auth). An upstream 503 on the GET → 502 and the PUT is never forwarded. - Full suite: 489 passed, 92% coverage. Supersedes #201. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Closed in favor of #214 |
disclaimer: This PR was mostly done by Claude but I reviewed all the steps
I hit an issue when trying to create/update/delete collections (using PUT requests) where I got 502 errors 👇