You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2021/09/27 17:14:05 UTC

[httpcomponents-client] 04/04: Corrected resolution of the target host in DefaultUserTokenHandler

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git

commit 54133d6585a0b4a57bd67b1fcb7070c5dd5ac943
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Sep 26 15:51:23 2021 +0200

    Corrected resolution of the target host in DefaultUserTokenHandler
---
 .../apache/hc/client5/http/UserTokenHandler.java   | 19 +++++++++++
 .../client5/http/impl/DefaultUserTokenHandler.java | 38 ++++++++++++++--------
 .../http/impl/async/HttpAsyncMainClientExec.java   |  2 +-
 .../client5/http/impl/classic/MainClientExec.java  |  2 +-
 4 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/UserTokenHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/UserTokenHandler.java
index deb0944..68e2f1d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/UserTokenHandler.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/UserTokenHandler.java
@@ -29,6 +29,7 @@ package org.apache.hc.client5.http;
 
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.protocol.HttpContext;
 
 /**
@@ -60,4 +61,22 @@ public interface UserTokenHandler {
      */
     Object getUserToken(HttpRoute route, HttpContext context);
 
+    /**
+     * The token object returned by this method is expected to uniquely
+     * identify the current user if the context is user specific or to be
+     * {@code null} if it is not.
+     *
+     * @param route HTTP route
+     * @param request HTTP request
+     * @param context the execution context
+     *
+     * @return user token that uniquely identifies the user or
+     * {@code null} if the context is not user specific.
+     *
+     * @since 5.2
+     */
+    default Object getUserToken(HttpRoute route, HttpRequest request, HttpContext context) {
+        return getUserToken(route, context);
+    }
+
 }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultUserTokenHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultUserTokenHandler.java
index 6570cc4..a41872f 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultUserTokenHandler.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultUserTokenHandler.java
@@ -37,6 +37,8 @@ import org.apache.hc.client5.http.auth.AuthScheme;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.protocol.HttpContext;
 
 /**
@@ -61,28 +63,38 @@ public class DefaultUserTokenHandler implements UserTokenHandler {
 
     @Override
     public Object getUserToken(final HttpRoute route, final HttpContext context) {
+        return getUserToken(route, null, context);
+    }
+
+    @Override
+    public Object getUserToken(final HttpRoute route, final HttpRequest request, final HttpContext context) {
 
         final HttpClientContext clientContext = HttpClientContext.adapt(context);
 
-        Principal userPrincipal = null;
+        final HttpHost target = request != null ? new HttpHost(request.getScheme(), request.getAuthority()) : route.getTargetHost();
 
-        final AuthExchange targetAuthExchange = clientContext.getAuthExchange(route.getTargetHost());
+        final AuthExchange targetAuthExchange = clientContext.getAuthExchange(target);
         if (targetAuthExchange != null) {
-            userPrincipal = getAuthPrincipal(targetAuthExchange);
-            if (userPrincipal == null && route.getProxyHost() != null) {
-                final AuthExchange proxyAuthExchange = clientContext.getAuthExchange(route.getProxyHost());
-                userPrincipal = getAuthPrincipal(proxyAuthExchange);
+            final Principal authPrincipal = getAuthPrincipal(targetAuthExchange);
+            if (authPrincipal != null) {
+                return authPrincipal;
             }
         }
-
-        if (userPrincipal == null) {
-            final SSLSession sslSession = clientContext.getSSLSession();
-            if (sslSession != null) {
-                userPrincipal = sslSession.getLocalPrincipal();
+        final HttpHost proxy = route.getProxyHost();
+        if (proxy != null) {
+            final AuthExchange proxyAuthExchange = clientContext.getAuthExchange(proxy);
+            if (proxyAuthExchange != null) {
+                final Principal authPrincipal = getAuthPrincipal(proxyAuthExchange);
+                if (authPrincipal != null) {
+                    return authPrincipal;
+                }
             }
         }
-
-        return userPrincipal;
+        final SSLSession sslSession = clientContext.getSSLSession();
+        if (sslSession != null) {
+            return sslSession.getLocalPrincipal();
+        }
+        return null;
     }
 
     private static Principal getAuthPrincipal(final AuthExchange authExchange) {
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java
index 7816f44..c8e4e26 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java
@@ -196,7 +196,7 @@ class HttpAsyncMainClientExec implements AsyncExecChainHandler {
                 final TimeValue keepAliveDuration = keepAliveStrategy.getKeepAliveDuration(response, clientContext);
                 Object userToken = clientContext.getUserToken();
                 if (userToken == null) {
-                    userToken = userTokenHandler.getUserToken(route, clientContext);
+                    userToken = userTokenHandler.getUserToken(route, request, clientContext);
                     clientContext.setAttribute(HttpClientContext.USER_TOKEN, userToken);
                 }
                 execRuntime.markConnectionReusable(userToken, keepAliveDuration);
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MainClientExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MainClientExec.java
index 2af5b70..3c79f60 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MainClientExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MainClientExec.java
@@ -106,7 +106,7 @@ public final class MainClientExec implements ExecChainHandler {
 
             Object userToken = context.getUserToken();
             if (userToken == null) {
-                userToken = userTokenHandler.getUserToken(route, context);
+                userToken = userTokenHandler.getUserToken(route, request, context);
                 context.setAttribute(HttpClientContext.USER_TOKEN, userToken);
             }