我使用http代理通过CloseableHttpClient连接https网站。首先发送CONNECT请求,因为它必须进行隧道连接。将发送响应标头,我需要检索它们。结果将存储在一个变量中,稍后使用。
在HttpClient 4.2上,我可以使用HttpResponseInterceptor实现它:
final DefaultHttpClient httpClient = new DefaultHttpClient();
//configure proxy
httpclient.addResponseInterceptor(new HttpResponseInterceptor() {
public void process(HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
final Header[] headers = httpResponse.getAllHeaders();
//store headers
}
});
但当我使用HttpClient 4.5时,我的响应拦截器从未在CONNECT请求上调用过。它直接跳转到GET或POST请求:
final CloseableHttpClient httpClient = HttpClients.custom()
.setProxy(new HttpHost(proxyHost, proxyPort, "http"))
.addInterceptorFirst(new HttpResponseInterceptor() {
public void process(HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
final Header[] headers = httpResponse.getAllHeaders();
//store headers
}
}).build();
方法setInterceptorLast()
和setHttpProcessor()
的结果相同。提前感谢:(
您将需要一个自定义HttpClientBuilder
类,以便能够将自定义协议拦截器添加到用于执行CONNECT
方法的HTTP协议处理器中。
HttpClient 4.5它不漂亮,但它会完成任务:
HttpClientBuilder builder = new HttpClientBuilder() {
@Override
protected ClientExecChain createMainExec(
HttpRequestExecutor requestExec,
HttpClientConnectionManager connManager,
ConnectionReuseStrategy reuseStrategy,
ConnectionKeepAliveStrategy keepAliveStrategy,
HttpProcessor proxyHttpProcessor,
AuthenticationStrategy targetAuthStrategy,
AuthenticationStrategy proxyAuthStrategy,
UserTokenHandler userTokenHandler) {
final ImmutableHttpProcessor myProxyHttpProcessor = new ImmutableHttpProcessor(
Arrays.asList(new RequestTargetHost()),
Arrays.asList(new HttpResponseInterceptor() {
@Override
public void process(
HttpResponse response,
HttpContext context) throws HttpException, IOException {
}
})
);
return super.createMainExec(requestExec, connManager, reuseStrategy, keepAliveStrategy,
myProxyHttpProcessor, targetAuthStrategy, proxyAuthStrategy, userTokenHandler);
}
};
HttpClient 5.0 classic:
CloseableHttpClient httpClient = HttpClientBuilder.create()
.replaceExecInterceptor(ChainElement.CONNECT.name(),
new ConnectExec(
DefaultConnectionReuseStrategy.INSTANCE,
new DefaultHttpProcessor(new RequestTargetHost()),
DefaultAuthenticationStrategy.INSTANCE))
.build();