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 deb094420..68e2f1d54 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 @@ 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 6570cc422..a41872fd8 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.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 7816f4485..c8e4e2649 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 @@ public void consumeResponse( 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 2af5b708e..3c79f608a 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 ClassicHttpResponse execute( Object userToken = context.getUserToken(); if (userToken == null) { - userToken = userTokenHandler.getUserToken(route, context); + userToken = userTokenHandler.getUserToken(route, request, context); context.setAttribute(HttpClientContext.USER_TOKEN, userToken); }