Spring WebClient 搭配 Jetty:不使用 CONNECT 的普通 HTTP 代理
当需要普通的转发 HTTP 请求时,使用 Spring 的 Jetty 连接器并让 HTTP/1.1 客户端与代理协议相匹配。
Reactor Netty 的 HTTP 代理处理器即使对普通 HTTP 目标也会建立 CONNECT 隧道。如果目标代理接受普通 HTTP/1.1 转发,Spring WebClient 可以改用另一个受支持的连接器。
对于 Spring 6.2,配合 Jetty 12.0.35 的客户端 API 以及兼容的 Jetty Reactive Streams 集成:
var jetty = new org.eclipse.jetty.client.HttpClient(
new org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP());
jetty.getProxyConfiguration().addProxy(
new org.eclipse.jetty.client.HttpProxy("proxy.example", 8080));
var client = WebClient.builder()
.clientConnector(new JettyClientHttpConnector(jetty))
.build();WebClient 和 JettyClientHttpConnector 是 Spring 的类。请通过应用正常的生命周期管理所提供 Jetty 客户端的启动与关闭。
当目标与客户端代理协议匹配时,Jetty 的 HTTP/1.1 代理可以无需隧道转发普通 HTTP/1.1 请求。其 requiresTunnel 策略对安全目标和协议不兼容的路径使用 CONNECT。
这并不是从普通 HTTPS 隧道中去掉 CONNECT 的办法。请保持目标的 scheme 正确。
在所说明的 Jetty API 中使用 addProxy。getProxies 返回不可修改的列表,因此旧的 getProxies().add(...) 写法不是它当前的修改接口。
对于允许的公共代理路由上的公共 HTTP 目标,HTTP 代理列表 可为 Jetty 的代理主机和端口提供候选。比较连接器时请读取实际的代理响应。认证、目标策略以及目标不可用,仍与选择转发 HTTP 还是 CONNECT 分开考虑。