2626import com .spectralogic .ds3client .utils .DateFormatter ;
2727import com .spectralogic .ds3client .utils .SSLSetupException ;
2828import com .spectralogic .ds3client .utils .Signature ;
29-
3029import org .apache .http .HttpHost ;
3130import org .apache .http .HttpRequest ;
3231import org .apache .http .HttpStatus ;
3332import org .apache .http .client .config .RequestConfig ;
3433import org .apache .http .client .methods .CloseableHttpResponse ;
3534import org .apache .http .client .protocol .HttpClientContext ;
36- import org .apache .http .conn .ssl .*;
35+ import org .apache .http .conn .ssl .AllowAllHostnameVerifier ;
36+ import org .apache .http .conn .ssl .SSLConnectionSocketFactory ;
37+ import org .apache .http .conn .ssl .SSLContexts ;
38+ import org .apache .http .conn .ssl .TrustStrategy ;
3739import org .apache .http .entity .ContentType ;
3840import org .apache .http .impl .client .CloseableHttpClient ;
3941import org .apache .http .impl .client .HttpClients ;
42+ import org .apache .http .impl .conn .PoolingHttpClientConnectionManager ;
4043import org .apache .http .message .BasicHttpEntityEnclosingRequest ;
4144import org .apache .http .message .BasicHttpRequest ;
4245import org .slf4j .Logger ;
4649import java .io .Closeable ;
4750import java .io .IOException ;
4851import java .io .InputStream ;
49- import java .lang .AssertionError ;
5052import java .net .MalformedURLException ;
5153import java .net .URI ;
5254import java .net .URL ;
53- import java .security .*;
55+ import java .security .KeyManagementException ;
56+ import java .security .KeyStoreException ;
57+ import java .security .NoSuchAlgorithmException ;
58+ import java .security .SignatureException ;
5459import java .security .cert .CertificateException ;
5560import java .security .cert .X509Certificate ;
5661import java .util .Collection ;
@@ -67,25 +72,44 @@ public class NetworkClientImpl implements NetworkClient {
6772 final static private String CONTENT_SHA512 = "Content-SHA512" ;
6873 final static private String CONTENT_CRC32 = "Content-CRC32" ;
6974 final static private String CONTENT_CRC32C = "Content-CRC32C" ;
75+ final static private int MAX_CONNECTION_PER_ROUTE = 50 ;
76+ final static private int MAX_CONNECTION_TOTAL = 100 ;
7077
7178 final private ConnectionDetails connectionDetails ;
7279
7380 final private CloseableHttpClient client ;
81+ final private HttpHost host ;
7482
7583 public NetworkClientImpl (final ConnectionDetails connectionDetails ) {
7684 if (connectionDetails == null ) throw new AssertionError ("ConnectionDetails cannot be null" );
77- this .connectionDetails = connectionDetails ;
78- this .client = createDefaultClient (connectionDetails );
85+ try {
86+ this .connectionDetails = connectionDetails ;
87+ this .host = buildHost (connectionDetails );
88+ this .client = createDefaultClient (connectionDetails , host );
89+ } catch (final MalformedURLException e ) {
90+ throw new RuntimeException (e );
91+ }
7992 }
8093
94+
8195 public NetworkClientImpl (final ConnectionDetails connectionDetails , final CloseableHttpClient client ) {
8296 if (connectionDetails == null ) throw new AssertionError ("ConnectionDetails cannot be null" );
8397 if (client == null ) throw new AssertionError ("CloseableHttpClient cannot be null" );
84- this .connectionDetails = connectionDetails ;
85- this .client = client ;
98+ try {
99+ this .connectionDetails = connectionDetails ;
100+ this .host = buildHost (connectionDetails );
101+ this .client = client ;
102+ } catch (final MalformedURLException e ) {
103+ throw new RuntimeException (e );
104+ }
86105 }
87106
88- private static CloseableHttpClient createDefaultClient (final ConnectionDetails connectionDetails ) {
107+
108+ private static CloseableHttpClient createDefaultClient (final ConnectionDetails connectionDetails , final HttpHost host ) {
109+ final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager ();
110+ connectionManager .setDefaultMaxPerRoute (MAX_CONNECTION_PER_ROUTE );
111+ connectionManager .setMaxTotal (MAX_CONNECTION_TOTAL );
112+
89113 if (connectionDetails .isHttps () && !connectionDetails .isCertificateVerification ()) {
90114 try {
91115
@@ -97,15 +121,29 @@ public boolean isTrusted(final X509Certificate[] chain, final String authType) t
97121 }).useTLS ().build ();
98122
99123 final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory (sslContext , new AllowAllHostnameVerifier ());
100- return HttpClients .custom ().setSSLSocketFactory (
124+ return HttpClients .custom ()
125+ .setConnectionManager (connectionManager )
126+ .setSSLSocketFactory (
101127 sslsf ).build ();
102128
103129 } catch (final NoSuchAlgorithmException | KeyStoreException | KeyManagementException e ) {
104130 throw new SSLSetupException (e );
105131 }
106132 }
107133 else {
108- return HttpClients .createDefault ();
134+ return HttpClients .custom ()
135+ .setConnectionManager (connectionManager )
136+ .build ();
137+ }
138+ }
139+
140+ private static HttpHost buildHost (final ConnectionDetails connectionDetails ) throws MalformedURLException {
141+ final URI proxyUri = connectionDetails .getProxy ();
142+ if (proxyUri != null ) {
143+ return new HttpHost (proxyUri .getHost (), proxyUri .getPort (), proxyUri .getScheme ());
144+ } else {
145+ final URL url = NetUtils .buildUrl (connectionDetails , "/" );
146+ return new HttpHost (url .getHost (), NetUtils .getPort (url ), url .getProtocol ());
109147 }
110148 }
111149
@@ -116,12 +154,13 @@ public ConnectionDetails getConnectionDetails() {
116154
117155 @ Override
118156 public WebResponse getResponse (final Ds3Request request ) throws IOException , SignatureException {
119- try (final RequestExecutor requestExecutor = new RequestExecutor (this .client , request )) {
157+ try (final RequestExecutor requestExecutor = new RequestExecutor (this .client , host , request )) {
120158 int redirectCount = 0 ;
121159 do {
122160 final CloseableHttpResponse response = requestExecutor .execute ();
123161 if (response .getStatusLine ().getStatusCode () == HttpStatus .SC_TEMPORARY_REDIRECT ) {
124162 redirectCount ++;
163+ response .close ();
125164 LOG .info ("Performing retry - attempt: " + redirectCount );
126165 }
127166 else {
@@ -147,10 +186,10 @@ private class RequestExecutor implements Closeable {
147186 private final Checksum .Type checksumType ;
148187 private final CloseableHttpClient client ;
149188
150- public RequestExecutor (final CloseableHttpClient client , final Ds3Request ds3Request ) throws IOException {
189+ public RequestExecutor (final CloseableHttpClient client , final HttpHost host , final Ds3Request ds3Request ) throws IOException {
151190 this .client = client ;
152191 this .ds3Request = ds3Request ;
153- this .host = this . buildHost () ;
192+ this .host = host ;
154193 this .content = ds3Request .getStream ();
155194 if (this .content != null && !this .content .markSupported ()) {
156195 throw new RequiresMarkSupportedException ();
@@ -171,16 +210,6 @@ public CloseableHttpResponse execute() throws IOException, SignatureException {
171210 return client .execute (this .host , httpRequest , this .getContext ());
172211 }
173212
174- private HttpHost buildHost () throws MalformedURLException {
175- final URI proxyUri = NetworkClientImpl .this .connectionDetails .getProxy ();
176- if (proxyUri != null ) {
177- return new HttpHost (proxyUri .getHost (), proxyUri .getPort (), proxyUri .getScheme ());
178- } else {
179- final URL url = NetUtils .buildUrl (NetworkClientImpl .this .connectionDetails , "/" );
180- return new HttpHost (url .getHost (), NetUtils .getPort (url ), url .getProtocol ());
181- }
182- }
183-
184213 private HttpRequest buildHttpRequest () throws IOException {
185214 final String verb = this .ds3Request .getVerb ().toString ();
186215 final String path = this .buildPath ();
0 commit comments