Last active
November 30, 2015 10:02
-
-
Save fernandomora/fa0a0fe381a39dc9b3a5 to your computer and use it in GitHub Desktop.
Http client that supports SSL protocol with "unrecognized_name" warning http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7127374 http://stackoverflow.com/questions/7615645/ssl-handshake-alert-unrecognized-name-error-since-upgrade-to-java-1-7-0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(buildTrustAllSSLContext(), NoopHostnameVerifier.INSTANCE); | |
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslsf).build(); | |
HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(new DefaultHttpClientConnectionOperator(socketFactoryRegistry, null, null), null, -1, TimeUnit.MILLISECONDS); | |
HttpClientBuilder clientBuilder = HttpClients.custom(); | |
clientBuilder.setConnectionManager(cm); | |
class SniHttpClientConnectionOperator extends DefaultHttpClientConnectionOperator { | |
class SniSSLSocketFactory extends SSLConnectionSocketFactory { | |
public static final String ENABLE_SNI = "__enable_sni__"; | |
/* | |
* Implement any constructor you need for your particular application - | |
* SSLConnectionSocketFactory has many variants | |
*/ | |
public SniSSLSocketFactory(final SSLContext sslContext, final HostnameVerifier verifier) { | |
super(sslContext, verifier); | |
} | |
@Override | |
public Socket createLayeredSocket( | |
final Socket socket, | |
final String target, | |
final int port, | |
final HttpContext context) throws IOException { | |
Boolean enableSniValue = (Boolean) context.getAttribute(ENABLE_SNI); | |
boolean enableSni = enableSniValue == null || enableSniValue; | |
return super.createLayeredSocket(socket, enableSni ? target : "", port, context); | |
} | |
} | |
public SniHttpClientConnectionOperator(Lookup<ConnectionSocketFactory> socketFactoryRegistry) { | |
super(socketFactoryRegistry, null, null); | |
} | |
@Override | |
public void connect( | |
final ManagedHttpClientConnection conn, | |
final HttpHost host, | |
final InetSocketAddress localAddress, | |
final int connectTimeout, | |
final SocketConfig socketConfig, | |
final HttpContext context) throws IOException { | |
try { | |
super.connect(conn, host, localAddress, connectTimeout, socketConfig, context); | |
} catch (SSLProtocolException e) { | |
Boolean enableSniValue = (Boolean) context.getAttribute(SniSSLSocketFactory.ENABLE_SNI); | |
boolean enableSni = enableSniValue == null || enableSniValue; | |
if (enableSni && e.getMessage() != null && e.getMessage().equals("handshake alert: unrecognized_name")) { | |
traza.warn("Server received saw wrong SNI host, retrying without SNI"); | |
context.setAttribute(SniSSLSocketFactory.ENABLE_SNI, false); | |
super.connect(conn, host, localAddress, connectTimeout, socketConfig, context); | |
} else { | |
throw e; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment