feat: add custom query parameter rules for proxy requests#409
feat: add custom query parameter rules for proxy requests#409maodeyu180 wants to merge 2 commits intotbphp:mainfrom
Conversation
Allow per-group URL query parameter manipulation (set/remove) before forwarding to upstream, mirroring the existing custom header rules. This solves the issue where clients append unsupported query params (e.g. ?beta=true) that upstream providers reject.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds query-parameter rule support across the stack: model, service, handler, proxy execution, utilities, frontend form and i18n, enabling per-group rules to set or remove URL query parameters during request forwarding. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Frontend as Frontend<br/>(Vue)
participant Handler as HTTP Handler<br/>(group_handler.go)
participant Service as Service<br/>(group_service.go)
participant Manager as Manager<br/>(group_manager.go)
participant Proxy as Proxy<br/>(server.go)
participant Upstream as Upstream<br/>Server
User->>Frontend: Fill group form with query_param_rules
Frontend->>Frontend: Validate keys (trim, uniqueness)
Frontend->>Handler: POST/PUT with query_param_rules
Handler->>Service: CreateGroup/UpdateGroup with QueryParamRules
Service->>Service: normalizeQueryParamRules() (trim, validate action, dedupe)
Service->>Manager: Persist Group with QueryParamRules JSON
Manager->>Manager: Unmarshal JSON -> QueryParamRuleList
Handler->>Frontend: Return GroupResponse (query_param_rules)
User->>Proxy: Send proxied request
Proxy->>Proxy: Build HeaderVariableContext
Proxy->>Proxy: ApplyQueryParamRules(req, QueryParamRuleList, ctx)
Proxy->>Upstream: Forward request with modified query params
Upstream-->>Proxy: Response
Proxy-->>User: Return response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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: 3
🧹 Nitpick comments (1)
internal/proxy/server.go (1)
185-194: Reuse a single variable context for both rule applications.This avoids duplicate context construction and keeps both rule phases using the exact same captured context instance.
♻️ Proposed refactor
- // Apply custom header rules - if len(group.HeaderRuleList) > 0 { - headerCtx := utils.NewHeaderVariableContextFromGin(c, group, apiKey) - utils.ApplyHeaderRules(req, group.HeaderRuleList, headerCtx) - } - - // Apply custom query parameter rules - if len(group.QueryParamRuleList) > 0 { - queryCtx := utils.NewHeaderVariableContextFromGin(c, group, apiKey) - utils.ApplyQueryParamRules(req, group.QueryParamRuleList, queryCtx) - } + // Apply custom header/query rules + if len(group.HeaderRuleList) > 0 || len(group.QueryParamRuleList) > 0 { + ruleCtx := utils.NewHeaderVariableContextFromGin(c, group, apiKey) + if len(group.HeaderRuleList) > 0 { + utils.ApplyHeaderRules(req, group.HeaderRuleList, ruleCtx) + } + if len(group.QueryParamRuleList) > 0 { + utils.ApplyQueryParamRules(req, group.QueryParamRuleList, ruleCtx) + } + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/proxy/server.go` around lines 185 - 194, Both rule phases create separate contexts; instead, create one variable context once and reuse it for both header and query rule applications: call utils.NewHeaderVariableContextFromGin(c, group, apiKey) into a single local (e.g., headerCtx or varCtx) and pass that same instance to utils.ApplyHeaderRules(req, group.HeaderRuleList, varCtx) and utils.ApplyQueryParamRules(req, group.QueryParamRuleList, varCtx) so both HeaderRuleList and QueryParamRuleList use the exact same captured context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/services/group_service.go`:
- Around line 967-976: Validate each rule.Action inside the loop that builds
normalized query-param rules: after trimming and skipping empty keys but before
appending to normalized, check that rule.Action is one of the supported values
used by ApplyQueryParamRules() (e.g., "set" or "remove"); if not, return a
validation error (use NewI18nError with app_errors.ErrValidation and an
appropriate message key like "validation.invalid_query_param_action" and include
the offending key/action in the details) so unsupported actions are rejected
instead of persisted.
In `@internal/utils/query_param_utils.go`:
- Around line 20-22: The query-param handling currently calls
ResolveHeaderVariables(rule.Value, ctx) and can expand secret header variables
(e.g. ${API_KEY}) into the URL via q.Set, exposing secrets; change this to use a
query-specific resolver that does not resolve header secrets or explicitly
detect and reject header-secret tokens in rule.Value for query params (i.e.,
replace the ResolveHeaderVariables call in the "set" case with a non-secret
resolver or validation that scans rule.Value for HeaderVariableContext tokens
like ${API_KEY} and returns an error), and ensure q.Set only receives resolved
values that cannot include header secrets.
In `@web/src/components/keys/GroupFormModal.vue`:
- Around line 432-438: addQueryParamRule currently pushes a rule with action
"remove", causing the value field to be hidden and new rows to behave like
deletions; update the push in addQueryParamRule to set action: "set" (matching
header-rule behavior) so new query_param_rules entries default to
adding/overriding and the value field is shown (refer to addQueryParamRule and
formData.query_param_rules).
---
Nitpick comments:
In `@internal/proxy/server.go`:
- Around line 185-194: Both rule phases create separate contexts; instead,
create one variable context once and reuse it for both header and query rule
applications: call utils.NewHeaderVariableContextFromGin(c, group, apiKey) into
a single local (e.g., headerCtx or varCtx) and pass that same instance to
utils.ApplyHeaderRules(req, group.HeaderRuleList, varCtx) and
utils.ApplyQueryParamRules(req, group.QueryParamRuleList, varCtx) so both
HeaderRuleList and QueryParamRuleList use the exact same captured context.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e4e325f8-6eb9-4f2a-89c3-e620908a24d3
📒 Files selected for processing (14)
internal/handler/group_handler.gointernal/i18n/locales/en-US.gointernal/i18n/locales/ja-JP.gointernal/i18n/locales/zh-CN.gointernal/models/types.gointernal/proxy/server.gointernal/services/group_manager.gointernal/services/group_service.gointernal/utils/query_param_utils.goweb/src/components/keys/GroupFormModal.vueweb/src/locales/en-US.tsweb/src/locales/ja-JP.tsweb/src/locales/zh-CN.tsweb/src/types/models.ts
Allow per-group URL query parameter manipulation (set/remove) before forwarding to upstream, mirroring the existing custom header rules. This solves the issue where clients append unsupported query params (e.g. ?beta=true) that upstream providers reject.
关联 Issue / Related Issue
Closes #
变更内容 / Change Content
新增"自定义 URL 查询参数"功能,支持在代理请求转发至上游前,对 URL 查询参数进行添加、覆盖或移除操作。设计上完全参照现有的"自定义请求头"功能。
背景: 部分客户端 SDK(如 Anthropic)会在请求 URL 上拼接
?beta=true等参数,但某些上游服务不支持这类参数,导致请求失败。改动范围:
后端
internal/models/types.go— 新增QueryParamRule模型,Group增加QueryParamRules/QueryParamRuleList字段internal/utils/query_param_utils.go— 新增ApplyQueryParamRules()工具函数internal/services/group_service.go— 新增normalizeQueryParamRules()校验与去重internal/handler/group_handler.go— 创建/更新/响应结构体中增加query_param_rulesinternal/services/group_manager.go— 缓存加载时解析QueryParamRuleListinternal/proxy/server.go— 在ModifyRequest之后应用查询参数规则internal/i18n/locales/{en-US,zh-CN,ja-JP}.go— 新增校验/错误提示国际化文案前端
web/src/types/models.ts— 新增QueryParamRule类型web/src/locales/{en-US,zh-CN,ja-JP}.ts— 新增 UI 国际化文案web/src/components/keys/GroupFormModal.vue— 高级配置中新增查询参数规则编辑 UI数据库: 新增
query_param_rulesJSON 列,由 GORM AutoMigrate 自动创建,无需手动迁移。自查清单 / Checklist
Summary by CodeRabbit
New Features
Localization