You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 👇
re-running ingest_data.py against an already-seeded database hits a 502 Bad Gateway on the PUT (update) fallback. That's in the external stac-auth-proxy dependency, not this repo — Cql2ValidateTransactionMiddleware._fetch_existing (Cql2ValidateTransactionMiddleware.py:123-129) does an internal GET to fetch the existing record for update-validation but never forwards the caller's Authorization header, so it 401s against a private endpoint and that gets mapped to a 502. Worth a heads-up since your ingest script is idempotent-by-design (POST-then-PUT-on-409) and will hit this on every re-run
The fix is correct and well-scoped: EnforceAuthMiddleware runs before Cql2ValidateTransactionMiddleware in the middleware stack (app.py — last-added-runs-first), so the caller is already authenticated by the time this middleware's internal _fetch_existing GET fires. Forwarding the caller's Authorization/Cookie headers to that internal call is therefore appropriate, not a privilege-escalation concern. The header-stripping list (host, content-length, content-type, transfer-encoding) correctly prevents the original bodied PUT/PATCH's Content-Length/Content-Type from leaking onto the bodyless internal GET, which the regression test (test_does_not_forward_incoming_content_length) confirms.
Non-blocking observations:
Cql2ValidateTransactionMiddleware.py:25-27 — _forward_headers builds a dict via {k: v for k, v in headers.items() ...}. Starlette's Headers.items() can yield repeated keys for multi-valued headers (e.g. multiple Forwarded/X-Forwarded-For from an upstream proxy); the dict comprehension silently keeps only the last occurrence. Unlikely to matter for the Authorization/Cookie case this PR targets, so not blocking.
Cql2ValidateTransactionMiddleware.py:133-139 — _fetch_existing's headers parameter is typed Optional[Headers] = None with a ... if headers else None fallback, but both call sites (_handle_update, _handle_delete) always pass a real Headers object now — the None path is unreachable in practice.
Simplify (ponytail)
Cql2ValidateTransactionMiddleware.py:133-139 — drop the now-dead Optional[...] = None default and the if headers else None ternary on _fetch_existing; make headers: Headers required and pass it straight to _forward_headers, since every real caller already supplies it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 👇