2121import org .apache .http .HttpHost ;
2222import org .apache .http .auth .AuthScope ;
2323import org .apache .http .auth .UsernamePasswordCredentials ;
24+ import org .apache .http .client .AuthCache ;
2425import org .apache .http .client .ClientProtocolException ;
2526import org .apache .http .client .CredentialsProvider ;
2627import org .apache .http .client .ResponseHandler ;
2930import org .apache .http .client .methods .HttpGet ;
3031import org .apache .http .client .methods .HttpPost ;
3132import org .apache .http .client .methods .HttpPut ;
33+ import org .apache .http .client .protocol .HttpClientContext ;
3234import org .apache .http .client .utils .URIBuilder ;
3335import org .apache .http .entity .StringEntity ;
36+ import org .apache .http .impl .auth .BasicScheme ;
37+ import org .apache .http .impl .client .BasicAuthCache ;
3438import org .apache .http .impl .client .BasicCredentialsProvider ;
3539import org .apache .http .impl .client .CloseableHttpClient ;
3640import org .apache .http .impl .client .HttpClientBuilder ;
4549import org .sourcelab .kafka .connect .apiclient .rest .handlers .RestResponseHandler ;
4650
4751import java .io .IOException ;
52+ import java .net .MalformedURLException ;
4853import java .net .SocketException ;
4954import java .net .URISyntaxException ;
55+ import java .net .URL ;
5056import java .nio .charset .StandardCharsets ;
5157import java .util .Arrays ;
5258import java .util .Collection ;
@@ -78,6 +84,8 @@ public class HttpClientRestClient implements RestClient {
7884 */
7985 private CloseableHttpClient httpClient ;
8086
87+ private HttpClientContext httpClientContext ;
88+
8189 /**
8290 * Constructor.
8391 */
@@ -109,6 +117,15 @@ public void init(final Configuration configuration) {
109117 // Define our RequestConfigBuilder
110118 final RequestConfig .Builder requestConfigBuilder = RequestConfig .custom ();
111119
120+ // Define our Credentials Provider
121+ final CredentialsProvider credsProvider = new BasicCredentialsProvider ();
122+
123+ // Define our context
124+ httpClientContext = HttpClientContext .create ();
125+
126+ // Define our auth cache
127+ final AuthCache authCache = new BasicAuthCache ();
128+
112129 // If we have a configured proxy host
113130 if (configuration .getProxyHost () != null ) {
114131 // Define proxy host
@@ -120,21 +137,53 @@ public void init(final Configuration configuration) {
120137
121138 // If we have proxy auth enabled
122139 if (configuration .getProxyUsername () != null ) {
123- // Create credential provider
124- final CredentialsProvider credsProvider = new BasicCredentialsProvider ();
140+ // Add proxy credentials
125141 credsProvider .setCredentials (
126142 new AuthScope (configuration .getProxyHost (), configuration .getProxyPort ()),
127143 new UsernamePasswordCredentials (configuration .getProxyUsername (), configuration .getProxyPassword ())
128144 );
129145
130- // Attach Credentials provider to client builder.
131- clientBuilder .setDefaultCredentialsProvider (credsProvider );
146+ // Preemptive load context with authentication.
147+ authCache .put (
148+ new HttpHost (configuration .getProxyHost (), configuration .getProxyPort (), configuration .getProxyScheme ()), new BasicScheme ()
149+ );
132150 }
133151
134152 // Attach Proxy to request config builder
135153 requestConfigBuilder .setProxy (proxyHost );
136154 }
137155
156+ // If BasicAuth credentials are configured.
157+ if (configuration .getBasicAuthUsername () != null ) {
158+ try {
159+ // parse ApiHost for Hostname and port.
160+ final URL apiUrl = new URL (configuration .getApiHost ());
161+
162+ // Add Kafka-Connect credentials
163+ credsProvider .setCredentials (
164+ new AuthScope (apiUrl .getHost (), apiUrl .getPort ()),
165+ new UsernamePasswordCredentials (
166+ configuration .getBasicAuthUsername (),
167+ configuration .getBasicAuthPassword ()
168+ )
169+ );
170+
171+ // Preemptive load context with authentication.
172+ authCache .put (
173+ new HttpHost (apiUrl .getHost (), apiUrl .getPort (), apiUrl .getProtocol ()), new BasicScheme ()
174+ );
175+ } catch (final MalformedURLException exception ) {
176+ throw new RuntimeException (exception .getMessage (), exception );
177+ }
178+ }
179+
180+ // Configure context.
181+ httpClientContext .setAuthCache (authCache );
182+ httpClientContext .setCredentialsProvider (credsProvider );
183+
184+ // Attach Credentials provider to client builder.
185+ clientBuilder .setDefaultCredentialsProvider (credsProvider );
186+
138187 // Attach default request config
139188 clientBuilder .setDefaultRequestConfig (requestConfigBuilder .build ());
140189
@@ -211,7 +260,7 @@ private <T> T submitGetRequest(final String url, final Map<String, String> getPa
211260 logger .debug ("Executing request {}" , get .getRequestLine ());
212261
213262 // Execute and return
214- return httpClient .execute (get , responseHandler );
263+ return httpClient .execute (get , responseHandler , httpClientContext );
215264 } catch (final ClientProtocolException | SocketException | URISyntaxException connectionException ) {
216265 // Typically this is a connection issue.
217266 throw new ConnectionException (connectionException .getMessage (), connectionException );
@@ -244,7 +293,7 @@ private <T> T submitPostRequest(final String url, final Object requestBody, fina
244293 logger .debug ("Executing request {} with {}" , post .getRequestLine (), jsonPayloadStr );
245294
246295 // Execute and return
247- return httpClient .execute (post , responseHandler );
296+ return httpClient .execute (post , responseHandler , httpClientContext );
248297 } catch (final ClientProtocolException | SocketException connectionException ) {
249298 // Typically this is a connection issue.
250299 throw new ConnectionException (connectionException .getMessage (), connectionException );
@@ -276,7 +325,7 @@ private <T> T submitPutRequest(final String url, final Object requestBody, final
276325 logger .debug ("Executing request {} with {}" , put .getRequestLine (), jsonPayloadStr );
277326
278327 // Execute and return
279- return httpClient .execute (put , responseHandler );
328+ return httpClient .execute (put , responseHandler , httpClientContext );
280329 } catch (final ClientProtocolException | SocketException connectionException ) {
281330 // Typically this is a connection issue.
282331 throw new ConnectionException (connectionException .getMessage (), connectionException );
@@ -307,7 +356,7 @@ private <T> T submitDeleteRequest(final String url, final Object requestBody, fi
307356 logger .debug ("Executing request {} with {}" , delete .getRequestLine (), jsonPayloadStr );
308357
309358 // Execute and return
310- return httpClient .execute (delete , responseHandler );
359+ return httpClient .execute (delete , responseHandler , httpClientContext );
311360 } catch (final ClientProtocolException | SocketException connectionException ) {
312361 // Typically this is a connection issue.
313362 throw new ConnectionException (connectionException .getMessage (), connectionException );
0 commit comments