使用Apache HttpClient通过代理时,如何指定GET而非CONNECT请求方法?
代理连接请求方法的指定方案
可以指定代理的连接请求方法,要避免CONNECT并让代理能检查流量,你需要切换到普通代理转发模式(而非隧道模式),让客户端直接向代理发送GET/POST等请求(携带完整目标URL),代理再与目标站点建立连接,从而实现流量检查。
针对你的Apache HttpClient 4.x代码,提供两种可行修改方案:
方案一:直接向代理发送完整URL请求
保持代理配置不变,构造请求时使用完整的HTTPS URL,并将请求目标设为代理:
HttpHost proxy = new HttpHost(proxyHost, proxyPort); HttpClientBuilder clientBuilder = HttpClientBuilder.create(); clientBuilder .setConnectionManager(connectionManager) .setDefaultRequestConfig(config); CloseableHttpClient client = clientBuilder.build(); // 使用完整HTTPS URL构造请求,目标主机指定为代理 HttpGet request = new HttpGet("https://xyz.com/your/path"); CloseableHttpResponse response = client.execute(proxy, request);
此时客户端向代理发送的请求格式为:
GET https://xyz.com/your/path HTTP/1.1 Host: xyz.com User-Agent: Apache-HttpClient/4.5.13 (Java/19.0.1) ...
代理收到后会自行与目标站点建立HTTPS连接并转发请求,全程可检查流量内容。
方案二:自定义路由规划器禁用隧道模式
如果你想保留原有"目标主机+相对路径"的请求写法,可以通过自定义路由规划器强制禁用CONNECT隧道:
HttpHost proxy = new HttpHost(proxyHost, proxyPort); // 自定义路由规划器,强制使用普通代理路由而非隧道 DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy) { @Override protected HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpClientContext context) throws HttpException { // 最后一个参数false表示不使用隧道 return new HttpRoute(target, null, proxy, false); } }; HttpClientBuilder clientBuilder = HttpClientBuilder.create(); clientBuilder .setConnectionManager(connectionManager) .setRoutePlanner(routePlanner) .setDefaultRequestConfig(config); CloseableHttpClient client = clientBuilder.build(); // 正常使用目标主机和相对路径发送请求 HttpHost target = new HttpHost("xyz.com", 443, "https"); HttpGet request = new HttpGet("/your/path"); CloseableHttpResponse response = client.execute(target, request);
补充说明
- 两种方案都会避免发送
CONNECT请求,改用常规HTTP方法与代理通信 - 需确保你的代理支持这种转发模式(多数标准HTTP代理均支持)
- 模式切换后,代理会作为中间人终止客户端连接,自行与目标站点建立TLS连接,满足你检查流量的需求
内容的提问来源于stack exchange,提问作者gd125
相关产品推荐
相关产品推荐

