001package dk.netarkivet.common.utils; 002 003import org.apache.http.config.Registry; 004import org.apache.http.config.RegistryBuilder; 005import org.apache.http.conn.socket.ConnectionSocketFactory; 006import org.apache.http.conn.ssl.DefaultHostnameVerifier; 007import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 008import org.apache.http.impl.client.CloseableHttpClient; 009import org.apache.http.impl.client.HttpClientBuilder; 010import org.apache.http.impl.client.HttpClients; 011import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 012 013import dk.netarkivet.common.CommonSettings; 014 015/** Class for providing configured HTTPS clients to execute requests over SSL. */ 016public class HttpsClientBuilder { 017 private final HttpClientBuilder clientBuilder; 018 private final BasicTwoWaySSLProvider sslProvider; 019 020 /** 021 * Constructor that sets up the whole SSL connection when called. 022 * Simply use {@link #getHttpsClient()} to get a configured client. 023 * 024 * @param privateKeyFile The path to the private key file to use for authentication. 025 */ 026 public HttpsClientBuilder(String privateKeyFile) { 027 clientBuilder = HttpClients.custom(); 028 sslProvider = new BasicTwoWaySSLProvider(privateKeyFile); 029 030 setupConnection(); 031 } 032 033 /** 034 * Sets up the SSL socket and the connection manager and configures the client builder to use them. 035 */ 036 private void setupConnection() { 037 SSLConnectionSocketFactory sslsf = 038 new SSLConnectionSocketFactory(sslProvider.getSSLContext(), new DefaultHostnameVerifier()); 039 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create() 040 .register("https", sslsf) //register http also? 041 .build(); 042 PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry); 043 configureMaxConnections(cm); 044 clientBuilder.setConnectionManager(cm); 045 } 046 047 /** 048 * Configure the connection managers max connections from settings. 049 * @param cm Connection manager to configure. 050 */ 051 private void configureMaxConnections(PoolingHttpClientConnectionManager cm) { 052 cm.setMaxTotal(Settings.getInt(CommonSettings.MAX_TOTAL_CONNECTIONS)); 053 cm.setDefaultMaxPerRoute(Settings.getInt(CommonSettings.MAX_CONNECTIONS_PER_ROUTE)); 054 } 055 056 /** 057 * Build and deliver the client. 058 * @return An HTTPS client to carry out requests over SSL. 059 */ 060 public CloseableHttpClient getHttpsClient() { 061 return clientBuilder.build(); 062 } 063}