On Tue, 2013-11-19 at 14:22 +0530, srihari na wrote:
> We have migrated from http client 3.1 to http client 4.2.5. In http client
> 4.2.5 version, we are facing problems with SSL(https) calls.
>
> Our implementation has one HTTP client instance. In 3.1 version, we are not
> registering(Protocol.register) the ssl protocol and passing the scheme
> information in HostConfiguration.setHost method. It was working fine when
> we use the the single client, single connection manager connecting to
> various endpoints with different certificates.
>
>
> In latest version, we have replaced the hostConfig with HttpHost. And there
> is no possibility to pass the ssl protocol as parameter in HttpHost. So we
> are registering the protocol and passing the protocol name in HttpHost. We
> are registering like below
>
> Scheme secureSSL = new Scheme("https", 443, authSSL);
> HttpSingletonHolder.client.getConnectionManager().getSchemeRegistry().register(secureSSL);
>
> As we have only one client, when ever we are registering the protocol with
> new certificate then all requests to other endpoint(which are going with
> old certificate before registering of new certificate) are going with new
> certificate. Hence all requests are failing with certificate error.
>
> We tried to register the scheme with "certificate name" instead of "https"
> and passing the certificate name in HttpHost.
> Scheme secureSSL = new Scheme("certificatename", 443, authSSL);
>
> I want to confirm, Is this a right approach and is there any consequences
> for this approach or is there any better approach to handle.
>
Srihari
You have several options to do the same with HttpClient 4.x. I will be
using the 4.3 APIs in my examples. While something similar can be done
with 4.2 APIs I would recommend upgrading to 4.3 nonetheless.
(1) Use execution context parameter to initialize connection sockets
with custom SSL settings.
---
SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(
SSLContexts.createSystemDefault()) {
@Override
public Socket createSocket(
final HttpContext context) throws IOException {
try {
// Obtain custom parameter
Object param = context.getAttribute("my.ssl.param");
// Create custom SSL context based on the parameter
SSLContext sslcontext = SSLContexts.custom().build();
return sslcontext.getSocketFactory().createSocket();
} catch (NoSuchAlgorithmException e) {
throw new SSLException(e);
} catch (KeyManagementException e) {
throw new SSLException(e);
}
}
};
CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(ssf)
.build();
HttpClientContext context = HttpClientContext.create();
context.setAttribute("my.ssl.param", "blah");
CloseableHttpResponse closeableHttpResponse = client.execute(
new HttpGet("/"), context);
closeableHttpResponse.close();
---
If you have a stable relation between the target hostname and the SSL
context to be used, you would not even need a custom parameter.
(2) Use 'http.socket-factory-registry' execution context attribute to
override the connection socket factory used by the connection manager.
This attribute is still considered for internal use only but it may
become public in a future release.
---
CloseableHttpClient client = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(
SSLContexts.custom().build());
context.setAttribute("http.socket-factory-registry", ssf);
CloseableHttpResponse closeableHttpResponse = client.execute(new
HttpGet("/"), context);
closeableHttpResponse.close();
---
Hope this helps
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]