apache httpclient 4.5.1 n’effectuant que des connexions SSL vers des sites non-ssl et échouant

Actuellement, j’utilise httpclient 4.2.5 sur jdk / tomcat v6 et son bon fonctionnement. Dans une tentative de mise à niveau, je suis passé à httpclient 4.5.1 sur jdk / tomcat v8 et j’ai maintenant différentes erreurs comme ci-dessous:

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 

ou

 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) 

et

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

et

 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 

J’ai cherché et trouvé que la première erreur (arrêt incorrect du pair SSL) était liée aux différences de protocoles dans les 2 jdks, mais l’utilisation de “-Dhttps.protocols = TLSv1, SSLv3”, comme suggéré, n’a pas aidé. Mais je pense que le rest des erreurs est dû au fait que le httpclient tente d’établir une connexion ssl à un site supposé http (l’URL que j’ai donnée à cette adresse est uniquement http – pas “https” n’importe où).

Ensuite, j’ai essayé d’utiliser un socketConnectionRegistry personnalisé, comme

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

et l’utiliser pour créer un gestionnaire de connexions de pooling et l’utiliser pour créer un client personnalisé, mais les erreurs demeurent.

Fait intéressant, l’ancienne version 4.2.5 fonctionne bien sur jdk / tomcat v6 et peut se connecter sans erreur à ces sites. Pas sûr où j’ai fait quelque chose de mal ..

Toute aide / pointeur serait génial.

Merci.


Mise à jour: 12 janvier

@Oleg Je n’ai pas encore essayé le protocole alternatif que vous avez donné ci-dessus, mais j’essaie toujours de connecter le nouveau httpclient 4.5.1 au site proxy sur http lui-même, ce qui est toujours dépassé. J’ai créé deux projets d’éclipse distincts, l’un avec HC 4.2.5 (sur jdk-6) et l’autre avec HC 4.5.1 (sur jdk-8), et a montré que l’ancienne HC pouvait se connecter facilement à un proxy et à une cible et obtenir la cible. html, mais HC plus récent expire sur la connexion proxy .. J’ai également trouvé si je définir le proxy sur HC 4.5 lors de la construction du client (par exemple

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

alors il se connecte parfaitement, et apporte le HTML, mais quand j’utilise un RoutePlanner personnalisé et que je définis un proxy via celui-ci, alors le problème ci-dessus (timeout). Voici le planificateur d’itinéraire personnalisé:

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

et je configure l’hôte proxy avant de faire la requête (proxy différent avant chaque requête, round-robin à travers un ensemble de proxys). Il échoue dans ce cas.

Pouvez-vous voir ce qui se fait de manière erronée? Merci.


Plus de mises à jour:

En fait, si je mets le

 .setRoutePlanner(routePlanner) 

Lors de la construction du HC personnalisé, il ignore tout ensemble de proxy via .setProxy (…) ou via RequestConfig, car il n’y a pas de proxy défini dans routePlanner (semble avoir un sens). Ainsi, il se connecte directement à la cible et obtient la page. Mais si je configure le proxy dans routePlanner, ou supprime le planificateur dans la construction HC et définit le proxy via reqConfig ou .setProxy, il tente de se connecter au proxy, puis échoue à nouveau (timeout).

Je mettais proxy dans HC 4.2 comme ci-dessous:

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

Je suis totalement perdu maintenant. Est-ce la bonne façon de définir le proxy dans HC 4.2? Comment vérifier si HC 4.2 utilisait le proxy défini ci-dessus ou comment définir correctement le proxy dans 4.5?

HttpClient ne prend pas la propriété ‘https.protocols’ (ou toute autre pour cette question), sauf instruction explicite de le faire

 CloseableHttpClient client = HttpClients.createSystem(); 

A partir de la version 4.5, HttpClient désactive la version du protocole SSLv3 par défaut

On peut toutefois configurer explicitement des versions de protocole SSL sockets en charge en utilisant une fabrique de connexions SSL personnalisée

 SSLContext sslcontext = SSLContexts.createSystemDefault(); SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory( sslcontext, new Ssortingng[] { "TLSv1", "SSLv3" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); Registry socketFactoryRegistry = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", sslConnectionSocketFactory) .build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry); CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(cm) .build();