这个问题与SO上的另一个问题(HttpClient: how do I obtain the underlying socket from an existing connection?)的措辞相同,但问题实际上是关于通过HTTP(S)隧道化其他协议,因此答案有点不同。
我尝试做的是建立HTTPS连接,然后找出该连接的详细信息。 Java的SSLSocket
课程会给我我需要的东西,但我需要能够掌握Socket
本身才能查询它。
有没有办法到达基础Socket
? httpclient / httpcore已经成为工厂和私有/受保护实现的迷宫,所以很难围绕API来确定如何在配置后实际获取内容。
答案 0 :(得分:1)
HttpClient故意难以获取底层连接对象及其绑定的套接字,主要是为了确保连接状态是一致的,并且连接池中的持久连接可以安全地被另一个事务重用。
但是,可以从响应拦截器获取底层连接。
CloseableHttpClient httpclient = HttpClients.custom()
.addInterceptorLast(new HttpResponseInterceptor() {
@Override
public void process(
final HttpResponse response,
final HttpContext context) throws HttpException, IOException {
HttpClientContext clientContext = HttpClientContext.adapt(context);
ManagedHttpClientConnection connection = clientContext.getConnection(ManagedHttpClientConnection.class);
// Can be null if the response encloses no content
if (connection != null) {
Socket socket = connection.getSocket();
System.out.println(socket);
}
}
})
.build();
try (CloseableHttpResponse response = httpclient.execute(new HttpGet("http://www.google.com/"))) {
System.out.println(response.getStatusLine());
EntityUtils.consume(response.getEntity());
}
答案 1 :(得分:0)
我最终使用了一种不同的技术,但@oleg让我走上正轨。这是我的一次性代码:
HttpClientContext ctx = HttpClientContext.create();
HttpResponse response = getHttpClient().execute(method, ctx);
if(log.isDebugEnabled())
{
ManagedHttpClientConnection connection = ctx.getConnection(ManagedHttpClientConnection.class);
// Can be null if the response encloses no content
if(null != connection)
{
Socket socket = connection.getSocket();
if(socket instanceof SSLSocket)
{
SSLSocket sslSock = (SSLSocket)socket;
log.debug("Connected to " + getEndpointURL()
+ " using " + sslSock.getSession().getProtocol()
+ " and suite " + sslSock.getSession().getCipherSuite());
}
}
}