com.helger.httpclient.HttpClientFactory Maven / Gradle / Ivy
/**
* Copyright (C) 2016 Philip Helger (www.helger.com)
* philip[at]helger[dot]com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.helger.httpclient;
import java.nio.charset.CodingErrorAction;
import java.security.GeneralSecurityException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpHost;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.RequestAcceptEncoding;
import org.apache.http.client.protocol.RequestAddCookies;
import org.apache.http.client.protocol.ResponseContentEncoding;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLInitializationException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import com.helger.commons.annotation.OverrideOnDemand;
import com.helger.commons.charset.CCharset;
/**
* A factory for creating {@link CloseableHttpClient} that is e.g. to be used in
* the {@link HttpClientManager}.
*
* @author Philip Helger
*/
@Immutable
public class HttpClientFactory
{
private final SSLContext m_aDefaultSSLContext;
public HttpClientFactory ()
{
this (null);
}
public HttpClientFactory (@Nullable final SSLContext aDefaultSSLContext)
{
m_aDefaultSSLContext = aDefaultSSLContext;
}
/**
* Create a custom SSLContext to use for the SSL Socket factory.
*
* @return null
if no custom context is present.
* @throws GeneralSecurityException
* In case key management problems occur.
*/
@Nullable
@OverrideOnDemand
public SSLContext createSSLContext () throws GeneralSecurityException
{
return m_aDefaultSSLContext;
}
@Nullable
public LayeredConnectionSocketFactory createSSLFactory ()
{
LayeredConnectionSocketFactory aSSLFactory = null;
// First try with a custom SSL context
try
{
final SSLContext aSSLContext = createSSLContext ();
if (aSSLContext != null)
try
{
aSSLFactory = new SSLConnectionSocketFactory (aSSLContext,
new String [] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier ());
}
catch (final SSLInitializationException ex)
{
// Fall through
}
}
catch (final GeneralSecurityException ex)
{
// Fall through
}
if (aSSLFactory == null)
{
// No custom SSL context present - use system defaults
try
{
aSSLFactory = SSLConnectionSocketFactory.getSystemSocketFactory ();
}
catch (final SSLInitializationException ex)
{
try
{
aSSLFactory = SSLConnectionSocketFactory.getSocketFactory ();
}
catch (final SSLInitializationException ex2)
{
// Fall through
}
}
}
return aSSLFactory;
}
@Nonnull
public ConnectionConfig createConnectionConfig ()
{
return ConnectionConfig.custom ()
.setMalformedInputAction (CodingErrorAction.IGNORE)
.setUnmappableInputAction (CodingErrorAction.IGNORE)
.setCharset (CCharset.CHARSET_UTF_8_OBJ)
.build ();
}
@Nonnull
public HttpClientConnectionManager createConnectionManager ()
{
final LayeredConnectionSocketFactory aSSLFactory = createSSLFactory ();
if (aSSLFactory == null)
throw new IllegalStateException ("Failed to create SSL SocketFactory");
final Registry sfr = RegistryBuilder. create ()
.register ("http",
PlainConnectionSocketFactory.getSocketFactory ())
.register ("https", aSSLFactory)
.build ();
final PoolingHttpClientConnectionManager aConnMgr = new PoolingHttpClientConnectionManager (sfr);
aConnMgr.setDefaultMaxPerRoute (100);
aConnMgr.setMaxTotal (200);
aConnMgr.setValidateAfterInactivity (1000);
final ConnectionConfig aConnectionConfig = createConnectionConfig ();
aConnMgr.setDefaultConnectionConfig (aConnectionConfig);
return aConnMgr;
}
@Nonnull
public RequestConfig createRequestConfig ()
{
return RequestConfig.custom ()
.setCookieSpec (CookieSpecs.DEFAULT)
.setSocketTimeout (10000)
.setConnectTimeout (5000)
.setConnectionRequestTimeout (5000)
.setCircularRedirectsAllowed (false)
.setRedirectsEnabled (true)
.build ();
}
@Nullable
public HttpHost createProxyHost ()
{
return null;
}
@Nonnull
public HttpClientBuilder createHttpClientBuilder ()
{
final HttpClientConnectionManager aConnMgr = createConnectionManager ();
final RequestConfig aRequestConfig = createRequestConfig ();
final HttpHost aProxy = createProxyHost ();
final HttpClientBuilder aHCB = HttpClients.custom ()
.setConnectionManager (aConnMgr)
.setDefaultRequestConfig (aRequestConfig)
.setProxy (aProxy);
// Allow gzip,compress
aHCB.addInterceptorLast (new RequestAcceptEncoding ());
// Add cookies
aHCB.addInterceptorLast (new RequestAddCookies ());
// Un-gzip or uncompress
aHCB.addInterceptorLast (new ResponseContentEncoding ());
return aHCB;
}
@Nonnull
public CloseableHttpClient createHttpClient ()
{
final HttpClientBuilder aBuilder = createHttpClientBuilder ();
return aBuilder.build ();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy