Repository navigation
新增独立的代理设置 / Add an independent proxy setting - #6483
Closed
HardBrick21 wants to merge 2 commits into
Closed
HardBrick21 wants to merge 2 commits into
HardBrick21 wants to merge 2 commits into
Conversation
Google Translate, OpenAI and other engines cannot be reached directly in some networks. The plugin had no proxy configuration of its own and relied entirely on the IDE-wide HTTP proxy. Adds an opt-in global proxy (HTTP or SOCKS5) to the Translation settings. When disabled - the default - requests keep going through HttpRequests and therefore the IDE proxy, so existing behavior is unchanged. When enabled, the plugin opens connections itself through the configured proxy. com.intellij.util.io.RequestBuilder turns out to be subclassable with a single abstract `connect`, and HttpRequests.Request is a public interface, so the proxied path extends the platform builder rather than replacing the type. Call sites and the platform's setHeadersViaTuner() are left untouched. Defaults mirror HttpRequests$RequestBuilderImpl (10s connect, 60s read, gzip on, redirect limit 10) so that the proxied and platform paths behave the same. The Edge TTS WebSocket, which does not go through Http, honors the proxy too. Connection-level failures now hint at the proxy settings when one is configured. Co-Authored-By: Claude Code <noreply@anthropic.com>
The host field feeds straight into InetSocketAddress, so a value like "http://127.0.0.1" is resolved as a hostname, yields an unresolved address and fails later with an error that gives no hint about the proxy configuration. The proxy protocol is picked by the type combo box, not by a URL scheme. Documents this in three places: a KDoc note on ProxySettings.host and toProxyOrNull(), a placeholder on the host field showing "127.0.0.1", and a comment under the field in the settings panel. Co-Authored-By: Claude Code <noreply@anthropic.com>
Owner
|
非常感谢你提交这个 PR,也谢谢你花时间实现插件的 HTTP 独立代理配置。独立代理支持确实是项目后续需要的能力,我很感激你主动推进这件事。 不过,我觉得我需要和你同步一下项目路线:下一个大版本计划引入新的 HTTP 请求库,并在新的 HTTP 层里统一支持代理配置。这个 PR 目前重新实现了 IntelliJ 平台的 HTTP 请求逻辑,和后续架构会有较大重叠;如果现在合并,等新版本迁移时可能会产生大量冲突,也会增加后续维护成本。因此我暂时先不合并并关闭这个 PR,但这并不是否定这个需求或你的工作。再次感谢你的贡献和理解。 |
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.
这个改动做了什么
为翻译请求新增一个可选的插件级代理,让翻译走自己的代理,而不必依赖 IDE 的全局 HTTP 代理。
在部分网络环境下,谷歌翻译、OpenAI、DeepL 无法直连。此前插件完全没有代理配置——所有请求
都经由
com.intellij.util.io.HttpRequests,而它只认 IDE 代理(
Settings → Appearance & Behavior → System Settings → HTTP Proxy)。用户无法让翻译引擎单独使用某个代理。
行为
HttpRequests,即沿用 IDE 代理。SOCKS5,不支持认证。
Settings → Tools → Translation → Proxy。HttpConfigurable、JVM 系统属性、全局ProxySelector均不作修改,因此不影响 IDE 自身与其他插件的请求。
为什么必须另建连接
RequestBuilder只暴露了useProxy(boolean),没有任何接收代理地址的入口。反汇编HttpRequests$RequestImpl可确认其唯一分支是:myUseProxy为真 →IdeUiService.openHttpConnection(url)(即 IDE 代理),否则url.openConnection(Proxy.NO_PROXY)。而
com.intellij.util.io.RequestBuilder是public abstract、只有一个抽象方法connect(RequestProcessor<T>),HttpRequests.Request是 public interface。因此走代理的路径只需继承平台 builder:
ProxiedRequestBuilder : RequestBuilder()记录各项配置,只重写connect,在其中执行URL.openConnection(proxy)。ProxiedRequest : HttpRequests.Request委托给该连接。这样所有调用点都无需改动,包括
MicrosoftHttp用到的平台扩展setHeadersViaTuner()——若改为替换 builder 类型,这个内部 API 就需要重新实现。
与既有路径的行为对齐
已通过反射读取
HttpRequests$RequestBuilderImpl的私有默认值并逐一对齐,否则同一个请求会因为"是否配置了代理"而表现出不同行为:
myRedirectLimitmyConnectTimeoutmyTimeout(读)myGzipmyThrowStatusCodeException其他改动
HttpRequests的 5 处(BingTranslator、MicrosoftHttp、OpenAiHttp、GoogleTTSPlayer、WordBookService)改为走统一工厂。Http.send的重定向重建原先直接构造平台 builder,会导致重定向后的请求绕过代理;现同样走工厂。
setProxy()。追加"请检查代理设置"。状态码错误不追加——那不是代理的问题。
测试
65 个测试通过(63 个既有 + 新增)。新增 3 个测试类:
ProxySettingsTest— 合法性边界、Proxy构造、XML 序列化往返。HttpProxyTest— 用本地假代理证明 GET 与 POST 确实经由代理发出(目标主机为example.invalid,永不解析,直连不可能成功),并验证默认请求 gzip 的行为与平台一致。ExceptionsTest— 代理提示只追加到连接类失败。代理传输本身也用与插件完全相同的 JDK 调用路径(
URL.openConnection(proxy))做了端到端验证:JDK 17 上 SOCKS5 走 HTTPS 可用,因此保留 SOCKS5,未降级为仅支持 HTTP。
自动化测试未覆盖的部分
建议用
runIde手工验证:saveToFile的进度与取消语义。备注
[Unreleased]条目。