Skip to content

fix(channel): improve proxy client compatibility and cache lifecycle - #6157

Merged
Calcium-Ion merged 3 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-proxy-client
Jul 20, 2026
Merged

fix(channel): improve proxy client compatibility and cache lifecycle#6157
Calcium-Ion merged 3 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-proxy-client

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)
优化渠道代理客户端的创建、复用与缓存失效逻辑,补充 HTTP、HTTPS、SOCKS5 和 SOCKS5H 的统一校验及规范化处理。
运行时兼容旧版带 path、query 或 fragment 的代理配置,避免升级后中断现有流量;保存时继续执行严格校验。SOCKS 拨号支持 context 取消和连接超时,并通过并发安全缓存减少重复 Transport 创建及不必要的全量重置。前端同步代理校验规则,避免保存时意外改写代理地址。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)

Summary by CodeRabbit

  • New Features

    • Added support for HTTP, HTTPS, SOCKS5, and SOCKS5H proxy configurations with validation and automatic SOCKS port defaults.
    • Added the thinking_to_content channel setting for converting reasoning content into tagged output.
    • Improved proxy connection reuse and handling across supported requests.
  • Bug Fixes

    • Invalid proxy formats are now rejected consistently.
    • Legacy proxy settings remain compatible at runtime with clear normalization.
    • Channel cloning and deletion now validate settings and report accurate deletion counts.
  • Documentation

    • Expanded proxy configuration requirements, compatibility notes, and timeout details.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The PR adds shared proxy URL parsing and canonical client caching, migrates proxied callers to the shared accessor, narrows cache invalidation to affected channels, validates cloned and updated settings, reports actual batch deletion counts, and documents proxy compatibility rules.

Changes

Proxy handling

Layer / File(s) Summary
Proxy parsing and client cache
common/proxy_url.go, service/http_client.go
Proxy URLs gain strict/runtime parsing, canonical cache keys, shared transport construction, scheme-specific proxy support, and targeted cache invalidation.
Channel lifecycle and deletion accounting
model/channel.go, controller/channel.go
Channel deletion returns actual row counts; channel operations conditionally invalidate proxy clients, detect proxy changes, and validate cloned settings.
Proxy caller migration
controller/..., relay/..., service/...
Proxied controller, relay, AWS, Vertex, Midjourney, and Codex paths use GetHttpClientWithProxy; unrelated cache resets are removed.
Validation, regression coverage, and documentation
controller/channel_test_internal_test.go, docs/channel/other_setting.md
Tests cover proxy validation, clone rejection, cache reset, deletion counts, and audit data; documentation describes supported proxy formats and compatibility behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: seefs001

Poem

I’m a rabbit with a proxy to hop,
Canonical paths make caches stop.
Old suffixes shed their tail,
Fresh clients follow one trail.
Channels count what they delete—
A tidy burrow, neat and fleet!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes around proxy compatibility and cache lifecycle in channel handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
web/default/src/features/channels/lib/channel-form.ts (1)

39-70: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Proxy validation logic looks correct and matches backend contract.

Cross-checked against common/proxy_url.go's parseProxyURL (strict mode): scheme whitelist, required host, "empty or root-only" path, and rejection of query/fragment are all mirrored correctly here.

One minor note: port validity relies on URL's own range enforcement rather than an explicit 1-65535 check (matching backend's strconv.Atoi bounds). This is likely fine in practice since URL rejects out-of-range ports, but worth keeping in mind if browser URL parsing behavior ever diverges.

🤖 Prompt for 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.

In `@web/default/src/features/channels/lib/channel-form.ts` around lines 39 - 70,
Keep the isOptionalProxyURL validation aligned with common/proxy_url.go’s strict
parseProxyURL contract: retain the supported-scheme whitelist, required
hostname, empty-or-root-only path rule, query/fragment rejection, and URL-based
port validation. No code change is required unless browser URL parsing diverges
from the backend’s port-range behavior.
🤖 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 `@controller/channel_test_internal_test.go`:
- Around line 131-142: Import testify/assert and replace non-fatal value checks
with assert in the affected tests: response.Success, response.Data, and
auditData.Operation.Params["count"] in the shown test, plus require.NotSame in
TestDeleteChannelResetsProxyCacheWhenPreReadFails and
require.Contains/require.Equal in
TestCopyChannelRejectsInvalidLegacyProxySettings. Keep require for setup and
error checks, including require.NoError and database reads, and apply the same
value-check change in TestDeleteChannelBatchReportsAndAuditsActualDeletedCount.

---

Nitpick comments:
In `@web/default/src/features/channels/lib/channel-form.ts`:
- Around line 39-70: Keep the isOptionalProxyURL validation aligned with
common/proxy_url.go’s strict parseProxyURL contract: retain the supported-scheme
whitelist, required hostname, empty-or-root-only path rule, query/fragment
rejection, and URL-based port validation. No code change is required unless
browser URL parsing diverges from the backend’s port-range 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 581e6a9f-c948-4206-9ea0-f8224608bbc0

📥 Commits

Reviewing files that changed from the base of the PR and between 7c28993 and 4084e63.

📒 Files selected for processing (26)
  • common/proxy_url.go
  • controller/channel-billing.go
  • controller/channel.go
  • controller/channel_test_internal_test.go
  • controller/channel_upstream_update.go
  • controller/codex_usage.go
  • docs/channel/other_setting.md
  • model/channel.go
  • relay/channel/api_request.go
  • relay/channel/aws/relay-aws.go
  • relay/channel/coze/relay-coze.go
  • relay/channel/vertex/service_account.go
  • relay/mjproxy_handler.go
  • service/codex_credential_refresh.go
  • service/codex_credential_refresh_task.go
  • service/http_client.go
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/default/src/features/channels/constants.ts
  • web/default/src/features/channels/lib/channel-form.ts
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh-TW.json
  • web/default/src/i18n/locales/zh.json
💤 Files with no reviewable changes (3)
  • controller/channel_upstream_update.go
  • service/codex_credential_refresh.go
  • service/codex_credential_refresh_task.go

Comment thread controller/channel_test_internal_test.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controller/channel_upstream_update.go (1)

320-320: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Use the shared proxy client accessor to benefit from connection pooling.

Using service.NewProxyHttpClient circumvents the concurrent safe proxy cache introduced in this PR. This instantiates a new http.Client (and potentially a new underlying http.Transport) for every model fetch request, which fails to reuse connections and may lead to socket exhaustion over time.

Please switch to the cached accessor to utilize the new cache mechanism.

⚡ Proposed fix
-	client, err := service.NewProxyHttpClient(channel.GetSetting().Proxy)
+	client, err := service.GetHttpClientWithProxy(channel.GetSetting().Proxy)
🤖 Prompt for 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.

In `@controller/channel_upstream_update.go` at line 320, Replace the direct
service.NewProxyHttpClient call in the channel upstream update flow with the
shared cached proxy client accessor, passing channel.GetSetting().Proxy so model
fetch requests reuse pooled connections and transports.
🤖 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.

Outside diff comments:
In `@controller/channel_upstream_update.go`:
- Line 320: Replace the direct service.NewProxyHttpClient call in the channel
upstream update flow with the shared cached proxy client accessor, passing
channel.GetSetting().Proxy so model fetch requests reuse pooled connections and
transports.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 995ef0ed-9954-4eb2-a77e-4b36789abf8e

📥 Commits

Reviewing files that changed from the base of the PR and between 62a0e92 and 3f26d43.

📒 Files selected for processing (3)
  • controller/channel.go
  • controller/channel_upstream_update.go
  • model/channel.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • model/channel.go
  • controller/channel.go

@Calcium-Ion
Calcium-Ion merged commit e13d403 into QuantumNous:main Jul 20, 2026
1 check passed
JacksonsY added a commit to JacksonsY/new-api that referenced this pull request Jul 22, 2026
同步上游 10 个提交(至 1721144),重点整合:

- QuantumNous#6329 鉴权重构:dashboard 会话全面改为无状态 token(access/refresh
  + 版本栅栏 + 会话管理),gin session 全部移除。fork 侧适配:
  - turnstile 一次性消费改为按 token 键控内存缓存(兼容发码+注册两步流)
  - TRUSTED_PROXY_CIDRS 作为 TRUSTED_PROXIES 的兼容别名保留
  - UserBase/ToBaseUser 保留 ParentId(子号计费),补 AuthVersion/CacheSchema
  - OAuth 绑定改 flow_token 流,保留 GitHub 账号年龄门禁(消费 flow 后校验)
  - RecordUserIP 反欺诈埋点移入 setupLoginAtAuthVersion
  - 子号/代理鉴权门(SubPermission/RejectSubAccount/AgentAuth)原样保留
  - profile 嫁接上游 LoginSessionsCard(会话管理 UI),绑定卡接入
    popup+postMessage 新绑定机制
  - 2FA/OAuth/微信登录后 redirect 目标经 handleLoginSuccess 传递恢复
- web/default → web/ 扁平化 + 删除 classic 主题:fork 全部前端定制
  (agent/supplier/detector/sub-account 等 180+ 文件)迁移至新路径,
  保留 fork 的 i18n 按需加载、每表分页记忆、主题调校与设计系统
- QuantumNous#6157 渠道代理客户端重构(别名缓存+失效清理),保留 fork 全局代理
  与 RELAY_DISABLE_HTTP2;QuantumNous#6074 suno CAS 防重复退款;QuantumNous#6163 playground
  自动分组;QuantumNous#6224 无限额度密钥显示已用量;QuantumNous#6032 realtime GA 去 beta 头
- 语言文件三方合并:fork ~6280 键 + 上游新增 55 键鉴权文案
- fork 刻意删除的组件与 workflows 维持删除(上次合并曾误恢复)

验证:go build/test 全绿,前端 tsgo 类型检查与 rsbuild 构建通过。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
zhaodechao2008 pushed a commit to zhaodechao2008/new-api that referenced this pull request Jul 27, 2026
…uantumNous#6157)

* fix(channel): improve proxy client compatibility and cache lifecycle

* test(controller): use non-fatal assertions for channel tests
lizhongyi1209 pushed a commit to lizhongyi1209/new-api that referenced this pull request Jul 28, 2026
…uantumNous#6157)

* fix(channel): improve proxy client compatibility and cache lifecycle

* test(controller): use non-fatal assertions for channel tests
330079598 pushed a commit to 330079598/new-api that referenced this pull request Aug 19, 2026
…uantumNous#6157)

* fix(channel): improve proxy client compatibility and cache lifecycle

* test(controller): use non-fatal assertions for channel tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants