On 2/10/2022 2:16 PM, Oleg Kalnichevski wrote:


On 2/10/2022 10:43 AM, Christophe Darville wrote:
Thank you very much Peter. I missed the point that HttpCacheContext was extending HttpClientContext.

Unfortunately, httpClient5 Async (CloseableHttpAsyncClient) is not sending credentials at first request even with your code (the same as mine except using HttpCacheContext in place of HttpClientContext).

I will check with Oleg on the way to produce logs.


The issue you are having may be the defect just reported as HTTPCLIENT-2203. I am looking into it. There is no need for wire logs anymore, because I have a local reproducer.

https://issues.apache.org/jira/browse/HTTPCLIENT-2203

Oleg


What is broken is the target host port normalization. When using explicitly defined ports the preemptive authentication works just fine. Please note the request URI contains a port in it.

This example works just fine for me:

----
public class AsyncPreemptiveBasicClientAuthentication {

    public static void main(final String[] args) throws Exception {
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope("httpbin.org", 80),
new UsernamePasswordCredentials("user", "passwd".toCharArray())); final CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
                .setDefaultCredentialsProvider(credsProvider)
                .build();
        httpclient.start();

        // Generate Basic scheme object and add it to the local auth cache
        final BasicScheme basicAuth = new BasicScheme();
basicAuth.initPreemptive(new UsernamePasswordCredentials("user", "passwd".toCharArray()));

        final HttpHost target = new HttpHost("http", "httpbin.org", 80);

        // Add AuthCache to the execution context
        final HttpClientContext localContext = HttpClientContext.create();
        localContext.resetAuthExchange(target, basicAuth);

final SimpleHttpRequest request = SimpleRequestBuilder.get("http://httpbin.org:80/basic-auth/user/passwd";)
                .build();

        System.out.println("Executing request " + request);
        for (int i = 0; i < 3; i++) {
            final Future<SimpleHttpResponse> future = httpclient.execute(
                    SimpleRequestProducer.create(request),
                    SimpleResponseConsumer.create(),
                    localContext,
                    new FutureCallback<SimpleHttpResponse>() {

                        @Override
public void completed(final SimpleHttpResponse response) { System.out.println(request + "->" + new StatusLine(response));
                            System.out.println(response.getBody());
                        }

                        @Override
                        public void failed(final Exception ex) {
                            System.out.println(request + "->" + ex);
                        }

                        @Override
                        public void cancelled() {
                            System.out.println(request + " cancelled");
                        }

                    });
            future.get();
        }

        System.out.println("Shutting down");
        httpclient.close(CloseMode.GRACEFUL);
    }
}

---
Executing request GET http://httpbin.org:80/basic-auth/user/passwd
2022-02-10 15:10:47,511 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient] ex-0000000001 preparing request execution 2022-02-10 15:10:47,520 DEBUG [main][org.apache.hc.client5.http.protocol.RequestAddCookies] ex-0000000001 Cookie spec selected: strict 2022-02-10 15:10:47,524 DEBUG [main][org.apache.hc.client5.http.protocol.RequestAuthCache] ex-0000000001 Auth cache not set in the context 2022-02-10 15:10:47,524 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncProtocolExec] ex-0000000001 target auth state: UNCHALLENGED 2022-02-10 15:10:47,530 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncProtocolExec] ex-0000000001 proxy auth state: UNCHALLENGED 2022-02-10 15:10:47,532 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncConnectExec] ex-0000000001 acquiring connection with route {}->http://httpbin.org:80 2022-02-10 15:10:47,533 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ex-0000000001 acquiring endpoint (3 MINUTES) 2022-02-10 15:10:47,534 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000001 endpoint lease request (3 MINUTES) [route: {}->http://httpbin.org:80][total available: 0; route allocated: 0 of 5; total allocated: 0 of 25] 2022-02-10 15:10:47,538 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000001 endpoint leased [route: {}->http://httpbin.org:80][total available: 0; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:47,538 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000001 acquired ep-0000000000 2022-02-10 15:10:47,539 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ex-0000000001 acquired endpoint ep-0000000000 2022-02-10 15:10:47,539 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000000 connecting endpoint (3 MINUTES) 2022-02-10 15:10:47,539 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000000 connecting endpoint to http://httpbin.org:80 (3 MINUTES) 2022-02-10 15:10:47,541 DEBUG [main][org.apache.hc.client5.http.impl.nio.MultihomeIOSessionRequester] http://httpbin.org:80 resolving remote address 2022-02-10 15:10:47,541 DEBUG [main][org.apache.hc.client5.http.impl.nio.MultihomeIOSessionRequester] http://httpbin.org:80 resolved to [httpbin.org/54.221.78.73, httpbin.org/3.209.99.235, httpbin.org/52.55.211.119, httpbin.org/35.171.190.227] 2022-02-10 15:10:47,542 DEBUG [main][org.apache.hc.client5.http.impl.nio.MultihomeIOSessionRequester] http://httpbin.org:80 connecting null to httpbin.org/54.221.78.73:80 (3 MINUTES) 2022-02-10 15:10:47,755 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.MultihomeIOSessionRequester] http://httpbin.org:80 connected c-0000000000 /192.168.8.102:49873->httpbin.org/54.221.78.73:80 2022-02-10 15:10:47,765 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000000 connected c-0000000000 2022-02-10 15:10:47,765 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000000 endpoint connected 2022-02-10 15:10:47,765 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.AsyncConnectExec] ex-0000000001 connected to target 2022-02-10 15:10:47,765 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.AsyncConnectExec] ex-0000000001 route fully established 2022-02-10 15:10:47,766 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000001 executing GET /basic-auth/user/passwd HTTP/1.1 2022-02-10 15:10:47,769 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000000 start execution ex-0000000001 2022-02-10 15:10:47,769 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000000 executing exchange ex-0000000001 over c-0000000000 2022-02-10 15:10:47,771 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.DefaultManagedAsyncClientConnection] c-0000000000 RequestExecutionCommand with NORMAL priority 2022-02-10 15:10:47,792 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000001 send request GET /basic-auth/user/passwd HTTP/1.1, null entity 2022-02-10 15:10:47,792 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> GET /basic-auth/user/passwd HTTP/1.1 2022-02-10 15:10:47,792 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> User-Agent: Apache-HttpAsyncClient/5.1.4-SNAPSHOT (Java/1.8.0_272) 2022-02-10 15:10:47,792 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Authorization: Basic dXNlcjpwYXNzd2Q= 2022-02-10 15:10:47,792 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Host: httpbin.org:80 2022-02-10 15:10:47,793 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Connection: keep-alive 2022-02-10 15:10:47,946 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << HTTP/1.1 200 OK 2022-02-10 15:10:47,946 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Date: Thu, 10 Feb 2022 14:10:48 GMT 2022-02-10 15:10:47,946 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Content-Type: application/json 2022-02-10 15:10:47,946 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Content-Length: 47 2022-02-10 15:10:47,946 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Connection: keep-alive 2022-02-10 15:10:47,947 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Server: gunicorn/19.9.0 2022-02-10 15:10:47,947 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Access-Control-Allow-Origin: * 2022-02-10 15:10:47,947 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Access-Control-Allow-Credentials: true 2022-02-10 15:10:47,949 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000001 consume response HTTP/1.1 200 OK, entity len 47 2022-02-10 15:10:47,959 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000001 consume response data, len 47 bytes 2022-02-10 15:10:47,959 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000001 end of response data
GET http://httpbin.org:80/basic-auth/user/passwd->HTTP/1.1 200 OK
SimpleBody{content length=47, content type=application/json}
2022-02-10 15:10:47,962 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient] ex-0000000002 preparing request execution 2022-02-10 15:10:47,962 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient] ex-0000000001 message exchange successfully completed 2022-02-10 15:10:47,962 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000000 releasing valid endpoint 2022-02-10 15:10:47,962 DEBUG [main][org.apache.hc.client5.http.protocol.RequestAddCookies] ex-0000000002 Cookie spec selected: strict 2022-02-10 15:10:47,962 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000000 releasing endpoint 2022-02-10 15:10:47,962 DEBUG [main][org.apache.hc.client5.http.protocol.RequestAuthCache] ex-0000000002 Auth cache not set in the context 2022-02-10 15:10:47,962 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncProtocolExec] ex-0000000002 target auth state: UNCHALLENGED 2022-02-10 15:10:47,962 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000000 connection c-0000000000 can be kept alive for 3 MINUTES 2022-02-10 15:10:47,962 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncProtocolExec] ex-0000000002 proxy auth state: UNCHALLENGED 2022-02-10 15:10:47,962 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncConnectExec] ex-0000000002 acquiring connection with route {}->http://httpbin.org:80 2022-02-10 15:10:47,962 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ex-0000000002 acquiring endpoint (3 MINUTES) 2022-02-10 15:10:47,963 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000000 connection released [route: {}->http://httpbin.org:80][total available: 1; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:47,963 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000002 endpoint lease request (3 MINUTES) [route: {}->http://httpbin.org:80][total available: 1; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:47,963 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] c-0000000000 Connection is kept alive 2022-02-10 15:10:47,963 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000002 endpoint leased [route: {}->http://httpbin.org:80][total available: 0; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:47,963 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000002 acquired ep-0000000001 2022-02-10 15:10:47,963 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ex-0000000002 acquired endpoint ep-0000000001 2022-02-10 15:10:47,963 DEBUG [main][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000002 executing GET /basic-auth/user/passwd HTTP/1.1 2022-02-10 15:10:47,964 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000001 start execution ex-0000000002 2022-02-10 15:10:47,964 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000001 executing exchange ex-0000000002 over c-0000000000 2022-02-10 15:10:47,964 DEBUG [main][org.apache.hc.client5.http.impl.nio.DefaultManagedAsyncClientConnection] c-0000000000 RequestExecutionCommand with NORMAL priority 2022-02-10 15:10:47,964 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000002 send request GET /basic-auth/user/passwd HTTP/1.1, null entity 2022-02-10 15:10:47,964 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> GET /basic-auth/user/passwd HTTP/1.1 2022-02-10 15:10:47,964 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> User-Agent: Apache-HttpAsyncClient/5.1.4-SNAPSHOT (Java/1.8.0_272) 2022-02-10 15:10:47,964 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Authorization: Basic dXNlcjpwYXNzd2Q= 2022-02-10 15:10:47,965 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Host: httpbin.org:80 2022-02-10 15:10:47,965 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Connection: keep-alive 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << HTTP/1.1 200 OK 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Date: Thu, 10 Feb 2022 14:10:48 GMT 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Content-Type: application/json 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Content-Length: 47 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Connection: keep-alive 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Server: gunicorn/19.9.0 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Access-Control-Allow-Origin: * 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Access-Control-Allow-Credentials: true 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000002 consume response HTTP/1.1 200 OK, entity len 47 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000002 consume response data, len 47 bytes 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000002 end of response data
GET http://httpbin.org:80/basic-auth/user/passwd->HTTP/1.1 200 OK
SimpleBody{content length=47, content type=application/json}
2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient] ex-0000000002 message exchange successfully completed 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000001 releasing valid endpoint 2022-02-10 15:10:48,099 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient] ex-0000000003 preparing request execution 2022-02-10 15:10:48,099 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000001 releasing endpoint 2022-02-10 15:10:48,100 DEBUG [main][org.apache.hc.client5.http.protocol.RequestAddCookies] ex-0000000003 Cookie spec selected: strict 2022-02-10 15:10:48,100 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000001 connection c-0000000000 can be kept alive for 3 MINUTES 2022-02-10 15:10:48,100 DEBUG [main][org.apache.hc.client5.http.protocol.RequestAuthCache] ex-0000000003 Auth cache not set in the context 2022-02-10 15:10:48,100 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000001 connection released [route: {}->http://httpbin.org:80][total available: 1; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:48,100 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncProtocolExec] ex-0000000003 target auth state: UNCHALLENGED 2022-02-10 15:10:48,100 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] c-0000000000 Connection is kept alive 2022-02-10 15:10:48,100 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncProtocolExec] ex-0000000003 proxy auth state: UNCHALLENGED 2022-02-10 15:10:48,100 DEBUG [main][org.apache.hc.client5.http.impl.async.AsyncConnectExec] ex-0000000003 acquiring connection with route {}->http://httpbin.org:80 2022-02-10 15:10:48,100 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ex-0000000003 acquiring endpoint (3 MINUTES) 2022-02-10 15:10:48,100 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000003 endpoint lease request (3 MINUTES) [route: {}->http://httpbin.org:80][total available: 1; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:48,101 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000003 endpoint leased [route: {}->http://httpbin.org:80][total available: 0; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:48,101 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ex-0000000003 acquired ep-0000000002 2022-02-10 15:10:48,101 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ex-0000000003 acquired endpoint ep-0000000002 2022-02-10 15:10:48,101 DEBUG [main][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000003 executing GET /basic-auth/user/passwd HTTP/1.1 2022-02-10 15:10:48,101 DEBUG [main][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000002 start execution ex-0000000003 2022-02-10 15:10:48,101 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000002 executing exchange ex-0000000003 over c-0000000000 2022-02-10 15:10:48,101 DEBUG [main][org.apache.hc.client5.http.impl.nio.DefaultManagedAsyncClientConnection] c-0000000000 RequestExecutionCommand with NORMAL priority 2022-02-10 15:10:48,102 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000003 send request GET /basic-auth/user/passwd HTTP/1.1, null entity 2022-02-10 15:10:48,102 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> GET /basic-auth/user/passwd HTTP/1.1 2022-02-10 15:10:48,102 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> User-Agent: Apache-HttpAsyncClient/5.1.4-SNAPSHOT (Java/1.8.0_272) 2022-02-10 15:10:48,102 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Authorization: Basic dXNlcjpwYXNzd2Q= 2022-02-10 15:10:48,102 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Host: httpbin.org:80 2022-02-10 15:10:48,102 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 >> Connection: keep-alive 2022-02-10 15:10:48,257 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << HTTP/1.1 200 OK 2022-02-10 15:10:48,257 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Date: Thu, 10 Feb 2022 14:10:48 GMT 2022-02-10 15:10:48,257 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Content-Type: application/json 2022-02-10 15:10:48,257 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Content-Length: 47 2022-02-10 15:10:48,257 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Connection: keep-alive 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Server: gunicorn/19.9.0 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Access-Control-Allow-Origin: * 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.headers] c-0000000000 << Access-Control-Allow-Credentials: true 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000003 consume response HTTP/1.1 200 OK, entity len 47 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000003 consume response data, len 47 bytes 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec] ex-0000000003 end of response data
GET http://httpbin.org:80/basic-auth/user/passwd->HTTP/1.1 200 OK
Shutting down
SimpleBody{content length=47, content type=application/json}
2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient] ex-0000000003 message exchange successfully completed 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] ep-0000000002 releasing valid endpoint 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000002 releasing endpoint 2022-02-10 15:10:48,258 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000002 connection c-0000000000 can be kept alive for 3 MINUTES 2022-02-10 15:10:48,259 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] ep-0000000002 connection released [route: {}->http://httpbin.org:80][total available: 1; route allocated: 1 of 5; total allocated: 1 of 25] 2022-02-10 15:10:48,259 DEBUG [main][org.apache.hc.client5.http.impl.async.AbstractHttpAsyncClientBase] Shutdown GRACEFUL 2022-02-10 15:10:48,259 DEBUG [httpclient-dispatch-1][org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient] c-0000000000 Connection is kept alive 2022-02-10 15:10:48,262 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] Shutdown connection pool GRACEFUL 2022-02-10 15:10:48,262 DEBUG [main][org.apache.hc.client5.http.impl.nio.DefaultManagedAsyncClientConnection] c-0000000000 Shutdown connection GRACEFUL 2022-02-10 15:10:48,263 DEBUG [main][org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager] Connection pool shut down






Regards,
Christophe

On 10 Feb 2022, at 10:26, Naber, Peter <peter.na...@alfa.de> wrote:

Hi,

ok, than a little bit more code 😊


    public CloseableHttpClient getHttpClient() throws IOException, NoSuchAlgorithmException {         final SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).setSoKeepAlive(true).build();
        String tlsString = System.getProperty("https.protocols");
        if ((tlsString == null) || tlsString.isEmpty()) {
            tlsString = "";
            final String[] protocols = SSLContext.getDefault().getSupportedSSLParameters().getProtocols();
            for (final String protocol : protocols) {
                if (protocol.startsWith("TLS")) {
                    tlsString = tlsString.length() == 0 ? tlsString + protocol : tlsString + "," + protocol;
                }
            }
        }
        final PoolingHttpClientConnectionManager connManager = PoolingHttpClientConnectionManagerBuilder.create() .setConnectionFactory(this.connFactory).setDnsResolver(new SystemDefaultDnsResolver()) .setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create().setSslContext(this.sslContext)
                        .setTlsVersions(tlsString.split(",")).build())
.setDefaultSocketConfig(socketConfig).setValidateAfterInactivity(TimeValue.ofSeconds(10L)).build();

        this.defaultRequestConfig = RequestConfig.custom().setCookieSpec(StandardCookieSpec.RELAXED) .setAuthenticationEnabled(true).setExpectContinueEnabled(false).setContentCompressionEnabled(true) .setConnectionRequestTimeout(Timeout.ofMilliseconds(this.getConnectionRequestTimeout())) .setConnectTimeout(Timeout.ofMilliseconds(this.getConnectTimeout())) .setResponseTimeout(Timeout.ofMilliseconds(this.getSocketTimeout())) .setRedirectsEnabled(this.getRedirect()).setCircularRedirectsAllowed(false)
                .setTargetPreferredAuthSchemes(
                        Arrays.asList(StandardAuthScheme.DIGEST, StandardAuthScheme.BASIC, StandardAuthScheme.NTLM)) .setProxyPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.BASIC, StandardAuthScheme.NTLM)).build();

        final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

        final CachingHttpClientBuilder cachingHttpClients = CachingHttpClients.custom(); cachingHttpClients.setCacheConfig(this.getHttpCacheConfig().getCacheConfig()).setConnectionManager(connManager) .setRedirectStrategy(redirectStrategy).setDefaultCookieStore(this.getCookieStore())
                .setDefaultRequestConfig(this.defaultRequestConfig);
        if (this.getHttpCacheConfig().getCacheFileName() != null) {
            cachingHttpClients.setCacheDir(new File(this.getHttpCacheConfig().getCacheFileName()));
        }

        final HttpClientBuilder httpBuild = cachingHttpClients;
        httpBuild.addExecInterceptorBefore("test", "compress", new ContentCompressionExec());
        if (this.getHttpProxy() != null) {
            final HttpProxy hproxy = this.getHttpProxy();
            this.proxy = new HttpHost(hproxy.getHost(), hproxy.getPort());
            httpBuild.setProxy(this.proxy);
            httpBuild.setRoutePlanner(new DefaultProxyRoutePlanner(this.proxy) {
                @Override
                protected HttpHost determineProxy(final HttpHost target, final HttpContext context)
                        throws HttpException {

                    if (ExecuteHttp.this.httpProxy == null) {
                        return null;
                    }
                    if (ExecuteHttp.this.httpProxy.getProxyNonHosts() != null) {                         for (final String proxy1 : ExecuteHttp.this.httpProxy.getProxyNonHosts()) {
                            try {
                                if (target.getHostName().matches(proxy1)) {
                                    return null;
                                }
                            } catch (final Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    return super.determineProxy(target, context);
                }
            });
        }
        final CloseableHttpClient httpClient = httpBuild.build();

        return httpClient;
    }


    private void basicRequest(final String basicCommand, final String urls1) throws Exception {
        int status = 0;
        String returnString = "";
        try (CloseableHttpClient httpClient = this.getHttpClient()) {
            for (final String url : this.getURL(this.replace(urls1))) {
                final HttpUriRequestBase basicRequest = new HttpUriRequestBase(basicCommand, new URI(url));
                final URL aURL = new URL(url);

                this.setHeaders(basicRequest);
                final HttpCacheContext context = this.getHttpCacheContext(aURL);                 this.log.info("[basicRequest]  " + basicRequest.getRequestUri());                 final CloseableHttpResponse response = httpClient.execute(basicRequest, context);

                try {
                    status = response.getCode();
                    ...

Regards,

Peter

-----Ursprüngliche Nachricht-----
Von: Christophe Darville <c...@internetvista.com>
Gesendet: Donnerstag, 10. Februar 2022 08:42
An: HttpClient User Discussion <httpclient-users@hc.apache.org>
Betreff: Re: Preemptive authentication in Http Client 5 Async

Hi Peter,

Thank you for your answer. Once you get an HttpCacheContext instance, how do you link it with the request ? I see no setter on the HttpClient nor on the RequestConfig.

Regards,
Christophe

On 9 Feb 2022, at 17:15, Naber, Peter <peter.na...@alfa.de> wrote:

Hi,

I use the HttpCacheContext but I think with the httpclient5 the preemtive authentication is implemented the same way.


    public HttpCacheContext getHttpCacheContext(final URL aURL) throws Exception {         final HttpHost targetHost = new HttpHost(aURL.getProtocol(), aURL.getHost(), aURL.getPort()==-1?aURL.getDefaultPort():aURL.getPort());
        final HttpCacheContext context = HttpCacheContext.create();
        final AuthCache authCache = new BasicAuthCache();
        if (this.getPreAuth() && this.getUser()!= null && this.getPassword()!=null ) {
            if (this.getAuthScheme() == AuthScheme.BASIC) {
                final BasicScheme basicAuth = new BasicScheme();
                basicAuth.initPreemptive(
                        new UsernamePasswordCredentials(this.getUser(), this.getPassword().toCharArray()));
                authCache.put(targetHost, basicAuth);
            } else if (this.getAuthScheme() == AuthScheme.DIGEST) {
                final DigestScheme digestScheme = new DigestScheme();
                final UsernamePasswordCredentials creds = new UsernamePasswordCredentials(this.replace(this.getUser()), this.replace(this.getPassword()).toCharArray());                 digestScheme.initPreemptive(creds, UUID.randomUUID().toString().replaceAll("-", ""), "vectorius");
                authCache.put(targetHost, digestScheme);
            }
            context.setAuthCache(authCache);
        }
context.setCredentialsProvider(this.getCredentialsProvider(aURL));
        return context;
    }

regards,

Peter

-----Ursprüngliche Nachricht-----
Von: Christophe Darville <c...@internetvista.com>
Gesendet: Mittwoch, 9. Februar 2022 17:00
An: HttpClient User Discussion <httpclient-users@hc.apache.org>
Betreff: Preemptive authentication in Http Client 5 Async

Hi,

I am trying to make preemptive authentication in HttpClient 5 Async mode using the following code, but I does not work, first request is still without authentication and the authentication is done on the second request :

    HttpClientContext httpContext = HttpClientContext.create();
    CredentialsProvider credentialsProvider = getCredentialsProvider();
    if (preemptive) {
        URI uri = URI.create(url);
        HttpHost targetHost = new HttpHost(uri.getScheme(), uri.getHost(), uri.getPort());
        AuthCache authCache = new BasicAuthCache();
        BasicScheme basicAuth = new BasicScheme();
        authCache.put(targetHost, basicAuth);
        httpContext.setAuthCache(authCache);
    }
    httpContext.setCredentialsProvider(credentialsProvider);

This code was working in httpClient 4. Any suggestion on how to make preemptive authentication work in HttpClient5 Async ?

Thank you,
Christophe




---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org

Reply via email to