fix: apply channel header overrides to async video task requests - #3158
fix: apply channel header overrides to async video task requests#3158kukisama wants to merge 5376 commits into
Conversation
- Add support for custom OAuth providers, including creation, retrieval, updating, and deletion. - Introduce new model and controller for managing custom OAuth providers. - Enhance existing OAuth logic to accommodate custom providers. - Update API routes for custom OAuth provider management. - Include i18n support for custom OAuth-related messages.
…th user creation and binding - Improve error handling in DeleteCustomOAuthProvider to log and return errors when fetching binding counts. - Refactor user creation and OAuth binding logic to use transactions for atomic operations, ensuring data integrity. - Add unique constraints to UserOAuthBinding model to prevent duplicate bindings. - Enhance GitHub OAuth provider error logging for non-200 responses. - Update AccountManagement component to provide clearer error messages on API failures.
…ers for optional fields - Change fields in UpdateCustomOAuthProviderRequest struct to use pointers for optional values, allowing for better handling of nil cases. - Update UpdateCustomOAuthProvider function to check for nil before assigning optional fields, ensuring existing values are preserved when not provided.
…al file types for LF normalization and binary detection
Mitigate XSS vulnerabilities in the playground where AI-generated content is rendered without sanitization, allowing potential script injection via prompt injection attacks. MarkdownRenderer.jsx: - Replace dangerouslySetInnerHTML with a sandboxed iframe for HTML preview - Use sandbox="allow-same-origin" to block script execution while allowing CSS rendering and iframe height auto-sizing - Add SandboxedHtmlPreview component with automatic height adjustment CodeViewer.jsx: - Add escapeHtml() utility to encode HTML entities before rendering - Rewrite highlightJson() to process tokens iteratively, escaping each token and structural text before wrapping in syntax highlighting spans - Escape non-JSON and very-large content paths that previously bypassed sanitization - Update linkRegex to correctly match URLs containing & entities These changes only affect the playground (AI output rendering). Admin- configured content (home page, about page, footer, notices) remains unaffected as they use separate code paths and are within the trusted admin boundary.
🔒 fix(security): sanitize AI-generated HTML to prevent XSS in playground
feat: add claude-opus-4-6
…idation - Add configurable per-user token creation limit (max_user_tokens) - Sanitize search input patterns to prevent expensive queries - Add per-user search rate limiting (by user ID) - Add pagination to search endpoint with strict page size cap - Skip empty search fields instead of matching nothing - Hide internal errors from API responses - Fix Interface2String float64 formatting causing config parse failures - Add float-string fallback in config system for int/uint fields
fix: harden token search with pagination, rate limiting and input validation
- Change ESCAPE character from '\' to '!' for compatibility with MySQL/PostgreSQL/SQLite - Adjust sanitization logic to escape '!' and '_' correctly, improving input validation for search queries
…d improved rate limiting
…d-path Feature/param override wildcard path
…7ca33dbb4dc9610a fix: fetch model add header passthrough rule key check
feats: repair the thinking of claude to openrouter convert
…7ac8c1e4b5b3e537 feat: kling cost quota support use FinalUnitDeduction as totalToken
fix: If top_p is not provided, Claude's logic will set to 1
…retry fix(relay): skip retries for bad response body errors
…tter clarity and functionality
Keep the model pricing editor wording aligned with the new price-based UI while exposing cache, image, and audio pricing in the marketplace so users can see the full configured pricing model.
WalkthroughResolves and applies header overrides derived from channel configuration and task private data across the video proxy, task API request path, Sora task adaptor, and task polling, including special handling for the Host header and Authorization resolution for OpenAI/Sora flows. Changes
Sequence DiagramsequenceDiagram
autonumber
actor Client
participant VidProxy as Video Proxy Controller
participant Relay as Relay/Controller
participant Channel as Channel Config
participant TaskAPI as Task API Request Flow
participant Sora as Sora Task Adaptor
participant Upstream as Upstream Service
Client->>VidProxy: Send OpenAI/Sora video request
VidProxy->>Relay: Build relayInfo (apiKey, headersOverride)
Relay->>Channel: Request ResolveHeaderOverride(relayInfo)
Channel-->>Relay: header_override (map) / error
alt resolved headers
Relay->>VidProxy: store in task.PrivateData.ResolvedHeaders
VidProxy->>Upstream: apply header_override (set headers, update Host if present)
else resolution error
Relay-->>VidProxy: log warning (non-fatal)
end
Note over TaskAPI,Sora: Task API / FetchTask flow
TaskAPI->>TaskAPI: Setup request headers (default)
TaskAPI->>Channel: processHeaderOverride(relayInfo)
Channel-->>TaskAPI: header_override
TaskAPI->>Upstream: apply header_override (override headers, Host)
TaskAPI->>Sora: send FetchTask with body["header_override"] (if present)
Sora->>Sora: extract header_override, trim/substitute {api_key}, skip passthrough/client headers
Sora->>Upstream: set headers on outgoing request (update Host if overridden)
Upstream-->>Client: proxied response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@controller/video_proxy.go`:
- Around line 109-128: The code sets Authorization and builds RelayInfo.ApiKey
only from channel.Key, which ignores a per-task key; compute an effectiveKey
(use task.PrivateData.Key if present else channel.Key), use effectiveKey for the
Authorization header (req.Header.Set("Authorization", "Bearer "+effectiveKey))
and pass it into relaychannel.ResolveHeaderOverride via
relaycommon.RelayInfo.ChannelMeta.ApiKey so {api_key} expands correctly; keep
the rest of the ResolveHeaderOverride usage and Host header handling the same.
In `@service/task_polling.go`:
- Around line 362-366: The polling path calls adaptor.FetchTask with
ch.GetHeaderOverride(), which returns only the template/rule map; resolve and
persist the concrete headers at submit time and reuse them during polling: add a
field on the Task (e.g., ResolvedHeaderOverride or HeaderOverrideSnapshot), set
that snapshot in the submit flow where templates like {client_header:*} and
passthrough rules are evaluated, and change the polling call (the FetchTask
invocation that uses task.GetUpstreamTaskID() / task.Action) to pass the
persisted snapshot (falling back to ch.GetHeaderOverride() only if the snapshot
is nil) so forwarded gateway headers are available during status/content
fetches.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 34e51888-4c70-45b2-af13-f5395e5494c4
📒 Files selected for processing (4)
controller/video_proxy.gorelay/channel/api_request.gorelay/channel/task/sora/adaptor.goservice/task_polling.go
There was a problem hiding this comment.
♻️ Duplicate comments (1)
controller/video_proxy.go (1)
117-125:⚠️ Potential issue | 🟠 MajorPass the effective key in
RelayInfo.ApiKeywhen re-resolving overrides.The fallback path still builds
RelayInfowithoutApiKey, butprocessHeaderOverrideexpands{api_key}frominfo.ApiKey. That means older tasks withoutResolvedHeaderscan still send literal{api_key}values in override headers and fail behind gateways.Suggested fix
if len(headerOverride) == 0 { var resolveErr error headerOverride, resolveErr = relaychannel.ResolveHeaderOverride(&relaycommon.RelayInfo{ + ApiKey: effectiveKey, ChannelMeta: &relaycommon.ChannelMeta{ ApiKey: effectiveKey, HeadersOverride: channel.GetHeaderOverride(), }, }, c)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@controller/video_proxy.go` around lines 117 - 125, The fallback path that calls relaychannel.ResolveHeaderOverride builds a relaycommon.RelayInfo without setting ChannelMeta.ApiKey, so processHeaderOverride can expand a literal "{api_key}" incorrectly; update the RelayInfo construction in the branch where headerOverride is empty to set ChannelMeta.ApiKey = effectiveKey (i.e., pass effectiveKey into RelayInfo.ApiKey) when calling relaychannel.ResolveHeaderOverride so that task.PrivateData.ResolvedHeaders are re-resolved with the correct ApiKey.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@controller/video_proxy.go`:
- Around line 117-125: The fallback path that calls
relaychannel.ResolveHeaderOverride builds a relaycommon.RelayInfo without
setting ChannelMeta.ApiKey, so processHeaderOverride can expand a literal
"{api_key}" incorrectly; update the RelayInfo construction in the branch where
headerOverride is empty to set ChannelMeta.ApiKey = effectiveKey (i.e., pass
effectiveKey into RelayInfo.ApiKey) when calling
relaychannel.ResolveHeaderOverride so that task.PrivateData.ResolvedHeaders are
re-resolved with the correct ApiKey.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fdf0d9c6-9c4b-4894-bcd2-bff5c8bdecec
📒 Files selected for processing (4)
controller/relay.gocontroller/video_proxy.gomodel/task.goservice/task_polling.go
🚧 Files skipped from review as they are similar to previous changes (1)
- service/task_polling.go
|
This is already covered in the fallback path. RelayInfo embeds ChannelMeta, so the effective key assigned to ChannelMeta.ApiKey is what ResolveHeaderOverride reads as info.ApiKey. That means older tasks without a stored header snapshot still resolve the api_key placeholder with the effective key during live fallback resolution. |
Problem
Channel configuration already supports
HeaderOverride, but async video task requests do not consistently apply these headers.This causes Sora2 task submission, polling, and content download to behave differently from regular relay requests, especially when the upstream is behind Microsoft APIM or another gateway that requires additional request headers.
Solution
This PR applies channel header overrides to the Sora2 async video task flow:
HeaderOverridein the shared task submit request pathHeaderOverridein Sora task polling requestsHeaderOverridein Sora/OpenAI video content proxy requestsCompatibility
HeaderOverrideis not configuredAuthorization: Bearer <key>behavior is preservedScope
This PR is intentionally scoped to the Sora2 async video task flow.
Summary by CodeRabbit