apache httpclient 4.5.1 仅与非 SSL 站点建立 SSL 连接,并且失败 [英] apache httpclient 4.5.1 making only SSL connections to non-ssl sites, and failing

查看:30
本文介绍了apache httpclient 4.5.1 仅与非 SSL 站点建立 SSL 连接,并且失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我在 jdk/tomcat v6 上使用 httpclient 4.2.5,它运行良好.. 为了升级,我在 jdk/tomcat v8 上移动到 httpclient 4.5.1,现在得到不同的错误,如下所示:

Currently I'm using httpclient 4.2.5 on jdk/tomcat v6, and it's running good.. In an attempt to upgrade, I moved to httpclient 4.5.1 on jdk/tomcat v8, and now getting different errors as below:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:992)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:388)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at com.temp.MyHttpClient.makeHttpRequest(MyHttpClient.java:275)
    .......
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:505)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
    ... 25 more

java.lang.Exception: Unrecognized SSL message, plaintext connection?
    ....
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    at sun.security.ssl.InputRecord.handleUnknownRecord(InputRecord.java:710)
    at sun.security.ssl.InputRecord.read(InputRecord.java:527)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:388)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)

java.lang.Exception: Searching source item B00OFLNE1C threw an error: Connection reset
    .....
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:209)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:388)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    ......

java.lang.Exception: Connect to 189.219.54.22:10000 [/189.219.54.22] failed: Connection timed out: connect
    ...
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to 189.219.54.22:10000 [/189.219.54.22] failed: Connection timed out: connect
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:388)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    ......
    ... 4 more
Caused by: java.net.ConnectException: Connection timed out: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:74)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    ... 19 more

我搜索并发现第一个错误(SSL 对等体错误关闭)表明与 2 个 jdks 中的协议差异有关,但是按照建议使用-Dhttps.protocols=TLSv1,SSLv3"并没有帮助.但我认为其余的错误是由于 httpclient 试图与一个所谓的 http 站点建立 ssl 连接(我提供给它的 url 也只有 http - 任何地方都没有https").

I searched and found the first error (SSL peer shut down incorrectly) was indicated to be related to protocols differences in the 2 jdks, but using "-Dhttps.protocols=TLSv1,SSLv3", as suggested, didn't help. But I think rest of the errors are due to the httpclient trying to make a ssl connection to a supposedly http site (the url I gave to it also have http only - no 'https' anywhere).

然后我尝试使用自定义的socketConnectionRegistry,如

Then I tried to use a custom socketConnectionRegistry, as

ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
        LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
        Registry<ConnectionSocketFactory> sockConnRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", plainsf)
            .register("https", sslsf)
        .build();

并使用它来构建池连接管理器并使用它来构建自定义客户端,但错误仍然存​​在.

and use it to build a pooling connection manager and use that to build a custom client, but still the errors remain.

有趣的是,它的旧版本 4.2.5 在 jdk/tomcat v6 上运行良好,并且可以毫无错误地连接到这些站点.不知道我哪里做错了.

Interestingly, the older version of it, 4.2.5 is running good on jdk/tomcat v6, and can connect to these sites without any error. Not sure where I did something wrong.

更新:1 月 12 日

@Oleg 我还没有尝试过你上面给出的替代协议,但仍然试图让新的 httpclient 4.5.1 连接到 http 本身的代理站点,这总是超时.我创建了两个单独的 Eclipse 项目,一个使用 HC 4.2.5(在 jdk-6 上),另一个使用 HC 4.5.1(在 jdk-8 上),发现旧的 HC 可以轻松连接到代理和目标并获取目标html,但较新的 HC 在代理连接上超时..我还发现是否在构建客户端时在 HC 4.5 上设置了代理(即

@Oleg I have not yet tried the protocol alternate you gave above, but still trying to get the new httpclient 4.5.1 connect to proxy site on http itself, which is always timing out. I created two separate eclipse projects, one with HC 4.2.5 (on jdk-6) and another with HC 4.5.1 (on jdk-8), and found the older HC can connect to a proxy and target easily and gets the target html, but newer HC times out on proxy connection.. Also I found if I set the proxy on HC 4.5 while building the client (i.e.

CloseableHttpClient httpClient = HttpClients.custom()
    .setRoutePlanner(routePlanner)
    ......
    .setProxy(proxy)
    .build();

然后它完美连接,并带来了html,但是当我使用自定义 RoutePlanner 并通过它设置代理时,就会出现上述问题(超时).这是自定义路线规划器:

then it connects perfectly, and brings the html, but when I use a custom RoutePlanner and set proxy via it, then the above problem (timeout). Here is the custom route planner:

static class ProxyRoutePlanner implements HttpRoutePlanner {
    public HttpHost proxy = null;
    @Override
    public HttpRoute determineRoute(HttpHost target,
            HttpRequest request, HttpContext context)
            throws HttpException {
        if (null == proxy)
            return new HttpRoute(target);
        return new HttpRoute(target, null, proxy, "https".equalsIgnoreCase(target.getSchemeName()));
    }
}

并且我在发出请求之前设置了代理主机(在每个请求之前使用不同的代理,通过一组代理进行循环).在这种情况下它失败了.

and I set the proxy host before making the request (different proxy before each request, round-robin looping thru a set of proxies). It fails in this case.

你能看出正在以错误的方式做什么吗?

Can you see what's being done in any wrong manner?

更多更新:

实际上,如果我设置

.setRoutePlanner(routePlanner)

在构建自定义 HC 时,它会忽略通过 .setProxy(...) 或通过 RequestConfig 设置的任何代理,因为在 routePlanner 中没有设置代理(似乎有道理).因此它直接连接到目标并获取页面.但是如果我在 routePlanner 中设置代理,或者在 HC 构建中删除计划器并通过 reqConfig 或 .setProxy 设置代理,它会尝试连接到代理,然后再次失败(超时).

while building the custom HC, then it ignores any proxy set via .setProxy(...) or via RequestConfig, since there is no proxy set in the routePlanner (seems to make sense). Thus it connects directly to target and gets the page. But if i set the proxy in routePlanner, or remove the planner in HC building and set proxy via reqConfig or .setProxy, it tries to connect to proxy, and then fails again (timeout).

我在 HC 4.2 中设置代理如下:

I was setting proxy in HC 4.2 as below:

HttpHost proxy = new HttpHost(proxyHost, proxyPort, proxyProtocol);
    httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

我现在完全迷失了.. 在 HC 4.2 中设置代理是否正确?如何验证HC 4.2是否使用如上设置的代理,或者如何在4.5中正确设置代理?

I'm totally lost now.. Is it the right way to set proxy in HC 4.2? How to verify if HC 4.2 was using proxy set as above, or how to set proxy correctly in 4.5?

推荐答案

HttpClient 不接受https.protocols"属性(或任何其他与此相关的属性),除非明确指示这样做

HttpClient does not take 'https.protocols' property (or any other for this matter) unless explicitly instructed to do so

CloseableHttpClient client = HttpClients.createSystem();

自 4.5 版起,HttpClient 默认禁用 SSLv3 协议版本

As of version 4.5 HttpClient disables SSLv3 protocol version by default

然而,可以使用自定义 SSL 连接工厂明确设置支持的 SSL 协议版本

One can however explicitly set up supported SSL protocol versions using a custom SSL connection factory

SSLContext sslcontext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
        sslcontext, new String[] { "TLSv1", "SSLv3" }, null,
        SSLConnectionSocketFactory.getDefaultHostnameVerifier());

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.INSTANCE)
        .register("https", sslConnectionSocketFactory)
        .build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient httpClient = HttpClients.custom()
        .setConnectionManager(cm)
        .build();

这篇关于apache httpclient 4.5.1 仅与非 SSL 站点建立 SSL 连接,并且失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆