apache httpclient 4.5.1 making only SSL connections to non-ssl sites, and failing

我的未来我决定 提交于 2019-12-11 13:45:40

问题


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

or

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)

and

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)
    ......

and

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

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).

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.

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.


Update: 12-Jan

@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();

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?


More updates:

Actually, if I set the

.setRoutePlanner(routePlanner)

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).

I was setting proxy in HC 4.2 as below:

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

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?


回答1:


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

CloseableHttpClient client = HttpClients.createSystem();

As of version 4.5 HttpClient disables SSLv3 protocol version by default

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();


来源:https://stackoverflow.com/questions/34628340/apache-httpclient-4-5-1-making-only-ssl-connections-to-non-ssl-sites-and-failin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!