Discussion:
Trying to use HttpClient in lieu of HttpsUrlConnection
Murat Cetin
2018-02-13 01:48:41 UTC
Permalink
Hi,

I am having issues with the keep-alive in HttpsUrlConnection in some legacy
code and considering the HttpClient as an alternative.

My question is, essentially, I have a URLCursor class definition as follows:

public URLCursor(String[] urls, ClientMetadata clientMetadata) {
this.urls = urls;
this.urlIdx = 0;
this.clientMetadata = clientMetadata;
// Custom trust manager to ignore certification
TrustManager[] customTrustManager = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[]
certs, String authType) {
}
public void checkServerTrusted(X509Certificate[]
certs, String authType) {
}
}
};
// Custom host verifier to accept all hosts.
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};

// Setup custom SSL trust manager that ignores SSL certificate
validation =
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, customTrustManager, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
System.err.println("Error: Failed to establish https with
no cert verification");
}
}

I have a subsequent next() method that essentially creates a new URL, opens
a http connection using url.openConnection(), gets a BufferedReader from
the input stream and then reads lines out of this stream

How can I achieve the same using HttpClient, especially the constructor
logic that ignores the certification?

thanks,
Murat
​
Bindul Bhowmik
2018-02-13 03:17:56 UTC
Permalink
Post by Murat Cetin
Hi,
I am having issues with the keep-alive in HttpsUrlConnection in some legacy
code and considering the HttpClient as an alternative.
public URLCursor(String[] urls, ClientMetadata clientMetadata) {
this.urls = urls;
this.urlIdx = 0;
this.clientMetadata = clientMetadata;
// Custom trust manager to ignore certification
TrustManager[] customTrustManager = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[]
certs, String authType) {
}
public void checkServerTrusted(X509Certificate[]
certs, String authType) {
}
}
};
// Custom host verifier to accept all hosts.
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Setup custom SSL trust manager that ignores SSL certificate
validation =
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, customTrustManager, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
System.err.println("Error: Failed to establish https with
no cert verification");
}
}
I have a subsequent next() method that essentially creates a new URL, opens
a http connection using url.openConnection(), gets a BufferedReader from
the input stream and then reads lines out of this stream
How can I achieve the same using HttpClient, especially the constructor
logic that ignores the certification?
Murat,

From what I see, what you are doing is disabling hostname and SSL
certificate verification. You can achieve both using a
NoopHostnameVerifier and a TrustAllStrategy for certificates.

You can initialize your HttpClient something like:

SSLContext sslContext = SSLContexts.custom().loadTrustMaterial( new
TrustAllStrategy() ).build();
CloseableHttpClient httpClient =
HttpClients.custom().setSSLHostnameVerifier(
NoopHostnameVerifier.INSTANCE ).setSSLContext( sslContext ).build();

Depending on your use case, unless you are running requests across
multiple threads, you should be able to share the http client instance
created for all your requests.

Disclaimer: it is not a good idea to have any of those verifications
turned off in production.

Bindul
Post by Murat Cetin
thanks,
Murat
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-***@hc.apache.org
For additional commands, e-mail: httpclient-users-***@hc.apache.org
Christopher Schultz
2018-04-13 18:53:58 UTC
Permalink
Bindul,
Post by Bindul Bhowmik
Post by Murat Cetin
Hi,
I am having issues with the keep-alive in HttpsUrlConnection in some legacy
code and considering the HttpClient as an alternative.
public URLCursor(String[] urls, ClientMetadata clientMetadata) {
this.urls = urls;
this.urlIdx = 0;
this.clientMetadata = clientMetadata;
// Custom trust manager to ignore certification
TrustManager[] customTrustManager = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[]
certs, String authType) {
}
public void checkServerTrusted(X509Certificate[]
certs, String authType) {
}
}
};
// Custom host verifier to accept all hosts.
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Setup custom SSL trust manager that ignores SSL certificate
validation =
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, customTrustManager, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
System.err.println("Error: Failed to establish https with
no cert verification");
}
}
I have a subsequent next() method that essentially creates a new URL, opens
a http connection using url.openConnection(), gets a BufferedReader from
the input stream and then reads lines out of this stream
How can I achieve the same using HttpClient, especially the constructor
logic that ignores the certification?
Murat,
Post by Murat Cetin
From what I see, what you are doing is disabling hostname and SSL
certificate verification. You can achieve both using a
NoopHostnameVerifier and a TrustAllStrategy for certificates.
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial( new
TrustAllStrategy() ).build();
CloseableHttpClient httpClient =
HttpClients.custom().setSSLHostnameVerifier(
NoopHostnameVerifier.INSTANCE ).setSSLContext( sslContext ).build();
+1

Also, Murat, you should remove the static calls to HttpsURLConnection
because you don't want to override the whole JVM's TLS configuration.
That's a serious potential security problem given how you have
configured the SSLContext.
Post by Bindul Bhowmik
Depending on your use case, unless you are running requests across
multiple threads, you should be able to share the http client instance
created for all your requests.
Disclaimer: it is not a good idea to have any of those verifications
turned off in production.
+1

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-***@hc.apache.org
For additional commands, e-mail: httpclient-users-***@hc.apache.org
Loading...