1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.client5.http.impl.auth;
29
30 import org.apache.hc.client5.http.SchemePortResolver;
31 import org.apache.hc.client5.http.auth.AuthCache;
32 import org.apache.hc.client5.http.auth.AuthExchange;
33 import org.apache.hc.client5.http.auth.AuthScheme;
34 import org.apache.hc.client5.http.auth.AuthStateCacheable;
35 import org.apache.hc.client5.http.protocol.HttpClientContext;
36 import org.apache.hc.core5.annotation.Contract;
37 import org.apache.hc.core5.annotation.Internal;
38 import org.apache.hc.core5.annotation.ThreadingBehavior;
39 import org.apache.hc.core5.http.HttpHost;
40 import org.apache.hc.core5.http.protocol.HttpContext;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49 @Internal
50 @Contract(threading = ThreadingBehavior.STATELESS)
51 public final class AuthCacheKeeper {
52
53 private static final Logger LOG = LoggerFactory.getLogger(AuthCacheKeeper.class);
54
55 private final SchemePortResolver schemePortResolver;
56
57 public AuthCacheKeeper(final SchemePortResolver schemePortResolver) {
58 this.schemePortResolver = schemePortResolver;
59 }
60
61 public void updateOnChallenge(final HttpHost host,
62 final String pathPrefix,
63 final AuthExchange authExchange,
64 final HttpContext context) {
65 clearCache(host, pathPrefix, HttpClientContext.cast(context));
66 }
67
68 public void updateOnNoChallenge(final HttpHost host,
69 final String pathPrefix,
70 final AuthExchange authExchange,
71 final HttpContext context) {
72 if (authExchange.getState() == AuthExchange.State.SUCCESS) {
73 updateCache(host, pathPrefix, authExchange.getAuthScheme(), HttpClientContext.cast(context));
74 }
75 }
76
77 public void updateOnResponse(final HttpHost host,
78 final String pathPrefix,
79 final AuthExchange authExchange,
80 final HttpContext context) {
81 if (authExchange.getState() == AuthExchange.State.FAILURE) {
82 clearCache(host, pathPrefix, HttpClientContext.cast(context));
83 }
84 }
85
86 public void loadPreemptively(final HttpHost host,
87 final String pathPrefix,
88 final AuthExchange authExchange,
89 final HttpContext context) {
90 if (authExchange.getState() == AuthExchange.State.UNCHALLENGED) {
91 AuthScheme authScheme = loadFromCache(host, pathPrefix, HttpClientContext.cast(context));
92 if (authScheme == null && pathPrefix != null) {
93 authScheme = loadFromCache(host, null, HttpClientContext.cast(context));
94 }
95 if (authScheme != null) {
96 authExchange.select(authScheme);
97 }
98 }
99 }
100
101 private AuthScheme loadFromCache(final HttpHost host,
102 final String pathPrefix,
103 final HttpClientContext clientContext) {
104 final AuthCache authCache = clientContext.getAuthCache();
105 if (authCache != null) {
106 final AuthScheme authScheme = authCache.get(host, pathPrefix);
107 if (authScheme != null) {
108 if (LOG.isDebugEnabled()) {
109 final String exchangeId = clientContext.getExchangeId();
110 LOG.debug("{} Re-using cached '{}' auth scheme for {}{}", exchangeId, authScheme.getName(), host,
111 pathPrefix != null ? pathPrefix : "");
112 }
113 return authScheme;
114 }
115 }
116 return null;
117 }
118
119 private void updateCache(final HttpHost host,
120 final String pathPrefix,
121 final AuthScheme authScheme,
122 final HttpClientContext clientContext) {
123 final boolean cacheable = authScheme.getClass().getAnnotation(AuthStateCacheable.class) != null;
124 if (cacheable) {
125 AuthCache authCache = clientContext.getAuthCache();
126 if (authCache == null) {
127 authCache = new BasicAuthCache(schemePortResolver);
128 clientContext.setAuthCache(authCache);
129 }
130 if (LOG.isDebugEnabled()) {
131 final String exchangeId = clientContext.getExchangeId();
132 LOG.debug("{} Caching '{}' auth scheme for {}{}", exchangeId, authScheme.getName(), host,
133 pathPrefix != null ? pathPrefix : "");
134 }
135 authCache.put(host, pathPrefix, authScheme);
136 }
137 }
138
139 private void clearCache(final HttpHost host,
140 final String pathPrefix,
141 final HttpClientContext clientContext) {
142 final AuthCache authCache = clientContext.getAuthCache();
143 if (authCache != null) {
144 if (LOG.isDebugEnabled()) {
145 final String exchangeId = clientContext.getExchangeId();
146 LOG.debug("{} Clearing cached auth scheme for {}{}", exchangeId, host,
147 pathPrefix != null ? pathPrefix : "");
148 }
149 authCache.remove(host, pathPrefix);
150 }
151 }
152
153 }