3131import org .apache .http .entity .ContentType ;
3232import org .apache .http .entity .StringEntity ;
3333import org .apache .http .impl .client .BasicCredentialsProvider ;
34+ import org .apache .http .impl .client .TargetAuthenticationStrategy ;
3435import org .apache .http .impl .nio .client .HttpAsyncClientBuilder ;
36+ import org .apache .http .message .BasicHeader ;
3537import org .apache .http .nio .entity .NStringEntity ;
3638import org .apache .http .util .EntityUtils ;
3739import org .elasticsearch .mocksocket .MockHttpServer ;
3840import org .junit .After ;
39- import org .junit .AfterClass ;
4041import org .junit .Before ;
41- import org .junit .BeforeClass ;
4242
4343import java .io .IOException ;
4444import java .io .InputStreamReader ;
@@ -147,6 +147,8 @@ public HttpAsyncClientBuilder customizeHttpClient(final HttpAsyncClientBuilder h
147147 if (usePreemptiveAuth == false ) {
148148 // disable preemptive auth by ignoring any authcache
149149 httpClientBuilder .disableAuthCaching ();
150+ // don't use the "persistent credentials strategy"
151+ httpClientBuilder .setTargetAuthenticationStrategy (new TargetAuthenticationStrategy ());
150152 }
151153
152154 return httpClientBuilder .setDefaultCredentialsProvider (credentialsProvider );
@@ -193,7 +195,7 @@ public void onFailure(Exception exception) {
193195 assertTrue ("timeout waiting for requests to be sent" , latch .await (10 , TimeUnit .SECONDS ));
194196 if (exceptions .isEmpty () == false ) {
195197 AssertionError error = new AssertionError ("expected no failures but got some. see suppressed for first 10 of ["
196- + exceptions .size () + "] failures" );
198+ + exceptions .size () + "] failures" );
197199 for (Exception exception : exceptions .subList (0 , Math .min (10 , exceptions .size ()))) {
198200 error .addSuppressed (exception );
199201 }
@@ -217,7 +219,7 @@ public void testHeaders() throws IOException {
217219 Response esResponse ;
218220 try {
219221 esResponse = restClient .performRequest (method , "/" + statusCode , Collections .<String , String >emptyMap (), requestHeaders );
220- } catch (ResponseException e ) {
222+ } catch (ResponseException e ) {
221223 esResponse = e .getResponse ();
222224 }
223225
@@ -291,8 +293,8 @@ public void testEncodeParams() throws IOException {
291293 /**
292294 * Verify that credentials are sent on the first request with preemptive auth enabled (default when provided with credentials).
293295 */
294- public void testPreemptiveAuthEnabled () throws IOException {
295- final String [] methods = { "POST" , "PUT" , "GET" , "DELETE" };
296+ public void testPreemptiveAuthEnabled () throws IOException {
297+ final String [] methods = {"POST" , "PUT" , "GET" , "DELETE" };
296298
297299 try (RestClient restClient = createRestClient (true , true )) {
298300 for (final String method : methods ) {
@@ -306,8 +308,8 @@ public void testPreemptiveAuthEnabled() throws IOException {
306308 /**
307309 * Verify that credentials are <em>not</em> sent on the first request with preemptive auth disabled.
308310 */
309- public void testPreemptiveAuthDisabled () throws IOException {
310- final String [] methods = { "POST" , "PUT" , "GET" , "DELETE" };
311+ public void testPreemptiveAuthDisabled () throws IOException {
312+ final String [] methods = {"POST" , "PUT" , "GET" , "DELETE" };
311313
312314 try (RestClient restClient = createRestClient (true , false )) {
313315 for (final String method : methods ) {
@@ -318,12 +320,31 @@ public void testPreemptiveAuthDisabled() throws IOException {
318320 }
319321 }
320322
323+ /**
324+ * Verify that credentials continue to be sent even if a 401 (Unauthorized) response is received
325+ */
326+ public void testAuthCredentialsAreNotClearedOnAuthChallenge () throws IOException {
327+ final String [] methods = {"POST" , "PUT" , "GET" , "DELETE" };
328+
329+ try (RestClient restClient = createRestClient (true , true )) {
330+ for (final String method : methods ) {
331+ Header realmHeader = new BasicHeader ("WWW-Authenticate" , "Basic realm=\" test\" " );
332+ final Response response401 = bodyTest (restClient , method , 401 , new Header []{realmHeader });
333+ assertThat (response401 .getHeader ("Authorization" ), startsWith ("Basic" ));
334+
335+ final Response response200 = bodyTest (restClient , method , 200 , new Header [0 ]);
336+ assertThat (response200 .getHeader ("Authorization" ), startsWith ("Basic" ));
337+ }
338+ }
339+
340+ }
341+
321342 public void testUrlWithoutLeadingSlash () throws Exception {
322343 if (pathPrefix .length () == 0 ) {
323344 try {
324345 restClient .performRequest ("GET" , "200" );
325346 fail ("request should have failed" );
326- } catch (ResponseException e ) {
347+ } catch (ResponseException e ) {
327348 assertEquals (404 , e .getResponse ().getStatusLine ().getStatusCode ());
328349 }
329350 } else {
@@ -335,8 +356,8 @@ public void testUrlWithoutLeadingSlash() throws Exception {
335356 {
336357 //pathPrefix is not required to start with '/', will be added automatically
337358 try (RestClient restClient = RestClient .builder (
338- new HttpHost (httpServer .getAddress ().getHostString (), httpServer .getAddress ().getPort ()))
339- .setPathPrefix (pathPrefix .substring (1 )).build ()) {
359+ new HttpHost (httpServer .getAddress ().getHostString (), httpServer .getAddress ().getPort ()))
360+ .setPathPrefix (pathPrefix .substring (1 )).build ()) {
340361 Response response = restClient .performRequest ("GET" , "200" );
341362 //a trailing slash gets automatically added if a pathPrefix is configured
342363 assertEquals (200 , response .getStatusLine ().getStatusCode ());
@@ -350,10 +371,15 @@ private Response bodyTest(final String method) throws IOException {
350371 }
351372
352373 private Response bodyTest (final RestClient restClient , final String method ) throws IOException {
353- String requestBody = "{ \" field\" : \" value\" }" ;
354374 int statusCode = randomStatusCode (getRandom ());
375+ return bodyTest (restClient , method , statusCode , new Header [0 ]);
376+ }
377+
378+ private Response bodyTest (RestClient restClient , String method , int statusCode , Header [] headers ) throws IOException {
379+ String requestBody = "{ \" field\" : \" value\" }" ;
355380 Request request = new Request (method , "/" + statusCode );
356381 request .setJsonEntity (requestBody );
382+ request .setHeaders (headers );
357383 Response esResponse ;
358384 try {
359385 esResponse = restClient .performRequest (request );
0 commit comments