Deprecated HttpClient, now using apache-httpclient-4.3.x - java

I have code that works fine but its now deprecated. Everything is depricated except BasicCredentialsProvider
SSLSocketFactory sslsf = new SSLSocketFactory("TLS", null, null, keyStore, null, new TrustSelfSignedStrategy(),
new AllowAllHostnameVerifier());
Scheme https = new Scheme("https", 28181, sslsf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(https);
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(schemeRegistry);
connectionManager.setMaxTotal(100);
connectionManager.setDefaultMaxPerRoute(5);
DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager);
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort(), name),
new UsernamePasswordCredentials(username, password));
httpClient.setCredentialsProvider(credsProvider);
httpClient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);
return new HttpContextRequestScopedApacheClientExecutor(httpClient);
I have tried to do it myself. First I replaced SSLSocketFactory with
SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory
(SSLContexts.custom().
loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()).
useTLS().build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
then I tried to use
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionFactory)
.build();
I couldn't fit my port there, so I after searching for quite some time I am still lost on how to do it. And for the rest I have no solution yet. Any help on this would be apriciated.

I think I have managed to do it, it's working so far.
HttpClientBuilder builder = HttpClientBuilder.create();
KeyStore keyStore = initSSL();
SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(SSLContexts.custom().loadTrustMaterial(keyStore, new
TrustSelfSignedStrategy()).useTLS().build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionFactory)
.build();
PoolingHttpClientConnectionManager ccm = new PoolingHttpClientConnectionManager(registry);
ccm.setMaxTotal(100);
ccm.setDefaultMaxPerRoute(5);
builder.setConnectionManager(ccm);
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort(), name),
new UsernamePasswordCredentials(username, password));
builder.setDefaultCredentialsProvider(credsProvider);
RequestConfig.Builder requestBuilder = RequestConfig.custom();
requestBuilder.setSocketTimeout(60000);
builder.setDefaultRequestConfig(requestBuilder.build());
return new HttpContextRequestScopedApacheClientExecutor(builder.build());

Related

Disable SSL on HttpClient with PoolingNHttpClientConnectionManager

I am trying to disable SSL on my CloseableHttpAsyncClient. Below is the code I use:
private synchronized CloseableHttpAsyncClient getCloseableClient() throws Exception {
if (closeableHttpAsyncClient == null) {
logger.info("New Async Client created ");
closeableHttpAsyncClient = HttpAsyncClientBuilder.create()
.setDefaultRequestConfig(createConnConfig())
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
#Override
public boolean isTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
}).build())
// .setKeepAliveStrategy(kepAliveStrategy) TODO
.setConnectionManager(createPoolingConnManager()).build();
closeableHttpAsyncClient.start();
}
return closeableHttpAsyncClient;
}
However when I run the above I still get:
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
What could be wrong here, I assume I have to modify my PoolingNHttpClientConnectionManager as well. However I am not aware of how to do this. Any pointers would be helpful
The problem with your code is that #setConnectionManager call overrides #setSSLContext rendering the SSLContext instance ineffective.
Either let HttpAsyncClientBuilder create a connection manager internally
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, (x509Certificates, s) -> true)
.build();
HttpAsyncClientBuilder.create()
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSSLContext(sslContext)
.build();
Or pass the SSLContext instance to PoolingNHttpClientConnectionManager as a constructor argument.
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, (x509Certificates, s) -> true)
.build();
Registry<SchemeIOSessionStrategy> registry = RegistryBuilder.<SchemeIOSessionStrategy>create()
.register("http", NoopIOSessionStrategy.INSTANCE)
.register("https", new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE))
.build();
DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
HttpAsyncClientBuilder.create()
.setConnectionManager(new PoolingNHttpClientConnectionManager(ioReactor, registry))
.build();

HttpClient set up SSLHostnameVerifier and ConnectionManager at the same time

Registry<ConnectionSocketFactory> reg =RegistryBuilder<ConnectionSocketFactory>create().register("https", new
SSLConnectionSocketFactory(ctx)).register("http", new PlainConnectionSocketFactory())
.build();
PoolingHttpClientConnectionManager cm = newPoolingHttpClientConnectionManager(reg);
client = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(config)
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
I use NoopHostnameVerifier because I do not want to verify SSL, but in my ConnectionManager exists essential logic and have not chances forgot ConnectionManager.
The problem is that if I have ConnectionManager and SSLHostnameVerifier(NoopHostnameVerifier), I get the following error:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
What might be causing this problem?
Here is what worked for me. I found it here.
PoolingHttpClientConnectionManager cm;
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
clientBuilder.setSslcontext(sslContext);
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactory)
.build();
cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
cm = new PoolingHttpClientConnectionManager();
}
You need to use the singleton of NoopHostnameVerifier
So change new NoopHostnameVerifier() to NoopHostnameVerifier.INSTANCE

HttpSolrServer with proxy

Using the HttpSolrServer to connect to a Solr instance. Trying to run this through a proxy but currently the configuration doesn't look to be getting applied, it continues using the baseUrl. This is the code:
DefaultHttpClient httpClient = new DefaultHttpClient();
ModifiableSolrParams params = new ModifiableSolrParams();
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 128);
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 32);
params.set(HttpClientUtil.PROP_FOLLOW_REDIRECTS, false);
params.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, this.connectionTimeout);
httpClient.getCredentialsProvider().setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(proxyUsername, proxyPassword)
);
HttpHost proxy = new HttpHost(proxyUrl, proxyPort, proxyProtocol);
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
HttpSolrServer solrServer = new HttpSolrServer(baseUrl, httpClient);
Have also tried:
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(this.connectionTimeout)
.setConnectionRequestTimeout(this.connectionTimeout)
.setSocketTimeout(this.connectionTimeout)
.build();
HttpClientBuilder httpClientBuilder = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setMaxConnTotal(128)
.setMaxConnPerRoute(32)
.disableRedirectHandling();
HttpHost proxy = new HttpHost(proxyUrl, proxyPort, proxyProtocol);
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxyUrl, proxyPort, AuthScope.ANY_REALM, "basic"),
new UsernamePasswordCredentials(proxyUsername, proxyPassword));
httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider)
.setTargetAuthenticationStrategy(new ProxyAuthenticationStrategy())
.setRoutePlanner(routePlanner);
CloseableHttpClient httpClient = httpClientBuilder.build();
HttpSolrServer solrServer = new HttpSolrServer(baseUrl, httpClient);
Versions
SolrJ 4.7.2
HttpClient 4.3.1

http client 4.3 not sending credentials

I am trying to send a get request using apache http client 4.3 (to a client using self sign cert), however I get back the error "Requires Authentication" everytime. In a web browser it works just fine so the username / password / url is correct. Is this not the way to pass username/password using http client 4.3?
public static String sendJsonHttpGetRequest(
String host,
String path,
String username,
String password,
int socketTimeout,
int connectionTimeout,
int connectionRequestTimeout
) throws Exception
{
String responseBody = null;
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy(){
#Override
public boolean isTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws java.security.cert.CertificateException
{
return true;
}
});
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultCredentialsProvider(credsProvider).build();
URIBuilder uriB = new URIBuilder().setScheme("https").setHost(host).setPath(path);
HttpGet _http = new HttpGet( uriB.build() );
RequestConfig _requestConfig = RequestConfig.custom().
setSocketTimeout(socketTimeout).
setConnectTimeout(connectionTimeout).
setConnectionRequestTimeout(connectionRequestTimeout).build();
_http.addHeader("Content-Type", "application/json");
_http.addHeader("Accept","application/json, text/xml;q=9, /;q=8");
_http.setConfig(_requestConfig);
// ###########################
ResponseHandler<String> response = new BasicResponseHandler();
responseBody = httpclient.execute(_http, response);
return responseBody;
}
turns out now with http 4+ you have to provide it in two locations for it to work,
second is
authCache.put(host, basicAuth);
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
HttpClientContext _context = HttpClientContext.create();
_context.setAuthCache(authCache);
_context.setCredentialsProvider(credentialsProvider);
responseBody = httpclient.execute(_http, response, _context);
I don't use this library myself, but have you tried the HttpClient class?
HttpClient client = new HttpClient();
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
GetMethod method = new GetMethod(uri);
client.executeMethod(method);
You still have to build the uri and set timeouts, but it could be an option.

Android HttpClient hangs simultaneous requests until I execute request to another host

I have a problem using DefaultHttpClient.
If I execute some requests simultaneously to the same server (> 2) it will hang them (no responses will be received). All next requests will hang too.
Here is the code.
public class ConnectionService {
// Should be called once with application context
public static void initWithContext(Context ctx) {
// Creating custom multithread connection manager to handle multiple simultaneous requests
HttpParams params = new BasicHttpParams();
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
ConnManagerParams.setMaxTotalConnections(params, 200);
ConnPerRoute cpr = new ConnPerRoute() {
#Override
public int getMaxForRoute(HttpRoute httpRoute) {
return 50;
}
};
ConnManagerParams.setMaxConnectionsPerRoute(params, cpr);
httpClient = new DefaultHttpClient(cm, params);
httpClient.setCookieStore(new PersistentCookieStore(ctx));
}
static private DefaultHttpClient httpClient = null;
private JsonExecutorInterface requestExecutorForRelativePathAndParams(String path, WebParams params) throws UnsupportedEncodingException {
HttpPost postRequest = new HttpPost(rootUrl.toString() + path);
if(params != null) {
postRequest.setEntity(params.getFormEntity());
}
JsonExecutorProxy executor = new JsonExecutorProxy();
executor.setRequest(postRequest);
executor.setErrorsHandlerDelegate(this);
return executor;
}
}
This is most likely due to how you are constructing the ThreadSafeClientConnManager you are using. If you change the order slightly you should get a better result.
HttpParams params = new BasicHttpParams();
// The params are read in the ctor of the pool constructed by
// ThreadSafeClientConnManager, and need to be set before constructing it.
ConnManagerParams.setMaxTotalConnections(params, 200);
ConnPerRoute cpr = new ConnPerRoute() {
#Override
public int getMaxForRoute(HttpRoute httpRoute) {
return 50;
}
};
ConnManagerParams.setMaxConnectionsPerRoute(params, cpr);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);

Categories

Resources