fix: follow redirects for download in genai passthrough - #5579
Merged
akshaydeo merged 3 commits intoJul 27, 2026
Conversation
Contributor
📝 WalkthroughWalkthroughChangesGemini passthrough redirect handling
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Client
participant GeminiPassthrough
participant ProviderUtils
participant UpstreamServer
Client->>GeminiPassthrough: Send passthrough request
GeminiPassthrough->>ProviderUtils: Follow redirects for GET :download
ProviderUtils->>UpstreamServer: Request download endpoint
UpstreamServer-->>ProviderUtils: 302 redirect
ProviderUtils->>UpstreamServer: Request redirect target with API key
UpstreamServer-->>ProviderUtils: Return video bytes
ProviderUtils-->>GeminiPassthrough: Return response
GeminiPassthrough-->>Client: Forward response
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
TejasGhatte
marked this pull request as ready for review
July 27, 2026 11:42
|
tejas ghatte seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
18 tasks
Collaborator
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
17 tasks
Contributor
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@core/providers/gemini/gemini.go`:
- Around line 4092-4098: Update the redirect handling in the download branch
around MakeRequestWithContextFollowRedirects so forwarded x-goog-api-key headers
cannot reach untrusted hosts. Constrain redirects to the expected Google
download origin, or remove the API key before any cross-host redirect, while
preserving trusted download redirect behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: f605d09b-d388-4479-9d90-35213877a841
📒 Files selected for processing (2)
core/providers/gemini/gemini.gocore/providers/gemini/passthrough_test.go
akshaydeo
previously approved these changes
Jul 27, 2026
Contributor
Merge activity
|
akshaydeo
changed the base branch from
07-27-fix_includeserversidetoolinvocations_field_in_genai_api
to
graphite-base/5579
July 27, 2026 12:24
akshaydeo
dismissed stale reviews from coderabbitai[bot] and themself
July 27, 2026 12:24
The base branch was changed.
akshaydeo
deleted the
07-27-fix_follow_redirects_for_download_in_genai_passthrough
branch
July 27, 2026 12:25
akhsaul
pushed a commit
to akhsaul/bifrost
that referenced
this pull request
Aug 27, 2026
## Summary
When a client requests a Gemini file download via `GET /files/{id}:download`, Google's API responds with a `302` redirect to `/download/v1beta/...`. The redirect target requires the API key, but since Bifrost is the only party holding it, the redirect was previously not followed — resulting in a `403` from Google. This PR fixes that by transparently following redirects (up to 5 hops) for `:download` GET requests while leaving all other passthrough calls unaffected.
## Changes
- For `GET` requests whose path contains `:download`, the Gemini passthrough now calls `MakeRequestWithContextFollowRedirects` instead of `MakeRequestWithContext`, ensuring the API key is forwarded to the redirect target.
- All other requests (e.g. resumable upload `308` responses with no `Location` header) continue to use the non-redirect-following path, preventing breakage of those flows.
- Added `passthrough_test.go` covering three cases: the download redirect is followed and bytes are returned, a resumable upload `308` is forwarded as-is, and ordinary calls are unaffected.
## Type of change
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI
## Affected areas
- [ ] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs
## How to test
```sh
go test ./core/providers/gemini/...
```
The new tests spin up a local HTTP server that mimics Google's redirect behaviour. Expected outcomes:
- `download follows the redirect and returns the bytes` — status `200`, body contains the file bytes, and the API key is present on the redirect hop.
- `resumable upload 308 is forwarded, not followed` — status `308`, no error.
- `ordinary calls are unaffected` — status `404`, no redirect handling triggered.
## Screenshots/Recordings
N/A
## Breaking changes
- [ ] Yes
- [x] No
## Related issues
N/A
## Security considerations
The API key is intentionally forwarded to the redirect target (`/download/v1beta/...`), which is a first-party Google endpoint. The redirect-following logic is scoped strictly to `:download` GET requests to prevent the key from being forwarded to arbitrary third-party redirect destinations.
## Checklist
- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
occcat
pushed a commit
to occcat/bifrost
that referenced
this pull request
Sep 2, 2026
## Summary
When a client requests a Gemini file download via `GET /files/{id}:download`, Google's API responds with a `302` redirect to `/download/v1beta/...`. The redirect target requires the API key, but since Bifrost is the only party holding it, the redirect was previously not followed — resulting in a `403` from Google. This PR fixes that by transparently following redirects (up to 5 hops) for `:download` GET requests while leaving all other passthrough calls unaffected.
## Changes
- For `GET` requests whose path contains `:download`, the Gemini passthrough now calls `MakeRequestWithContextFollowRedirects` instead of `MakeRequestWithContext`, ensuring the API key is forwarded to the redirect target.
- All other requests (e.g. resumable upload `308` responses with no `Location` header) continue to use the non-redirect-following path, preventing breakage of those flows.
- Added `passthrough_test.go` covering three cases: the download redirect is followed and bytes are returned, a resumable upload `308` is forwarded as-is, and ordinary calls are unaffected.
## Type of change
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI
## Affected areas
- [ ] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs
## How to test
```sh
go test ./core/providers/gemini/...
```
The new tests spin up a local HTTP server that mimics Google's redirect behaviour. Expected outcomes:
- `download follows the redirect and returns the bytes` — status `200`, body contains the file bytes, and the API key is present on the redirect hop.
- `resumable upload 308 is forwarded, not followed` — status `308`, no error.
- `ordinary calls are unaffected` — status `404`, no redirect handling triggered.
## Screenshots/Recordings
N/A
## Breaking changes
- [ ] Yes
- [x] No
## Related issues
N/A
## Security considerations
The API key is intentionally forwarded to the redirect target (`/download/v1beta/...`), which is a first-party Google endpoint. The redirect-following logic is scoped strictly to `:download` GET requests to prevent the key from being forwarded to arbitrary third-party redirect destinations.
## Checklist
- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.

Summary
When a client requests a Gemini file download via
GET /files/{id}:download, Google's API responds with a302redirect to/download/v1beta/.... The redirect target requires the API key, but since Bifrost is the only party holding it, the redirect was previously not followed — resulting in a403from Google. This PR fixes that by transparently following redirects (up to 5 hops) for:downloadGET requests while leaving all other passthrough calls unaffected.Changes
GETrequests whose path contains:download, the Gemini passthrough now callsMakeRequestWithContextFollowRedirectsinstead ofMakeRequestWithContext, ensuring the API key is forwarded to the redirect target.308responses with noLocationheader) continue to use the non-redirect-following path, preventing breakage of those flows.passthrough_test.gocovering three cases: the download redirect is followed and bytes are returned, a resumable upload308is forwarded as-is, and ordinary calls are unaffected.Type of change
Affected areas
How to test
go test ./core/providers/gemini/...The new tests spin up a local HTTP server that mimics Google's redirect behaviour. Expected outcomes:
download follows the redirect and returns the bytes— status200, body contains the file bytes, and the API key is present on the redirect hop.resumable upload 308 is forwarded, not followed— status308, no error.ordinary calls are unaffected— status404, no redirect handling triggered.Screenshots/Recordings
N/A
Breaking changes
Related issues
N/A
Security considerations
The API key is intentionally forwarded to the redirect target (
/download/v1beta/...), which is a first-party Google endpoint. The redirect-following logic is scoped strictly to:downloadGET requests to prevent the key from being forwarded to arbitrary third-party redirect destinations.Checklist
docs/contributing/README.mdand followed the guidelines