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
29
30 package org.apache.commons.httpclient.auth;
31
32 import org.apache.commons.httpclient.util.LangUtils;
33
34 /***
35 * The class represents an authentication scope consisting of a host name,
36 * a port number, a realm name and an authentication scheme name which
37 * {@link org.apache.commons.httpclient.Credentials} apply to.
38 *
39 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
40 * @author <a href="mailto:adrian@intencha.com">Adrian Sutton</a>
41 *
42 * @since 3.0
43 */
44 public class AuthScope {
45
46 /***
47 * The <tt>null</tt> value represents any host. In the future versions of
48 * HttpClient the use of this parameter will be discontinued.
49 */
50 public static final String ANY_HOST = null;
51
52 /***
53 * The <tt>-1</tt> value represents any port.
54 */
55 public static final int ANY_PORT = -1;
56
57 /***
58 * The <tt>null</tt> value represents any realm.
59 */
60 public static final String ANY_REALM = null;
61
62 /***
63 * The <tt>null</tt> value represents any authentication scheme.
64 */
65 public static final String ANY_SCHEME = null;
66
67 /***
68 * Default scope matching any host, port, realm and authentication scheme.
69 * In the future versions of HttpClient the use of this parameter will be
70 * discontinued.
71 */
72 public static final AuthScope ANY = new AuthScope(ANY_HOST, ANY_PORT, ANY_REALM, ANY_SCHEME);
73
74 /*** The authentication scheme the credentials apply to. */
75 private String scheme = null;
76
77 /*** The realm the credentials apply to. */
78 private String realm = null;
79
80 /*** The host the credentials apply to. */
81 private String host = null;
82
83 /*** The port the credentials apply to. */
84 private int port = -1;
85
86 /*** Creates a new credentials scope for the given
87 * <tt>host</tt>, <tt>port</tt>, <tt>realm</tt>, and
88 * <tt>authentication scheme</tt>.
89 *
90 * @param host the host the credentials apply to. May be set
91 * to <tt>null</tt> if credenticals are applicable to
92 * any host.
93 * @param port the port the credentials apply to. May be set
94 * to negative value if credenticals are applicable to
95 * any port.
96 * @param realm the realm the credentials apply to. May be set
97 * to <tt>null</tt> if credenticals are applicable to
98 * any realm.
99 * @param scheme the authentication scheme the credentials apply to.
100 * May be set to <tt>null</tt> if credenticals are applicable to
101 * any authentication scheme.
102 *
103 * @since 3.0
104 */
105 public AuthScope(final String host, int port,
106 final String realm, final String scheme)
107 {
108 this.host = (host == null) ? ANY_HOST: host.toLowerCase();
109 this.port = (port < 0) ? ANY_PORT: port;
110 this.realm = (realm == null) ? ANY_REALM: realm;
111 this.scheme = (scheme == null) ? ANY_SCHEME: scheme.toUpperCase();;
112 }
113
114 /*** Creates a new credentials scope for the given
115 * <tt>host</tt>, <tt>port</tt>, <tt>realm</tt>, and any
116 * authentication scheme.
117 *
118 * @param host the host the credentials apply to. May be set
119 * to <tt>null</tt> if credenticals are applicable to
120 * any host.
121 * @param port the port the credentials apply to. May be set
122 * to negative value if credenticals are applicable to
123 * any port.
124 * @param realm the realm the credentials apply to. May be set
125 * to <tt>null</tt> if credenticals are applicable to
126 * any realm.
127 *
128 * @since 3.0
129 */
130 public AuthScope(final String host, int port, final String realm) {
131 this(host, port, realm, ANY_SCHEME);
132 }
133
134 /*** Creates a new credentials scope for the given
135 * <tt>host</tt>, <tt>port</tt>, any realm name, and any
136 * authentication scheme.
137 *
138 * @param host the host the credentials apply to. May be set
139 * to <tt>null</tt> if credenticals are applicable to
140 * any host.
141 * @param port the port the credentials apply to. May be set
142 * to negative value if credenticals are applicable to
143 * any port.
144 *
145 * @since 3.0
146 */
147 public AuthScope(final String host, int port) {
148 this(host, port, ANY_REALM, ANY_SCHEME);
149 }
150
151 /***
152 * Creates a copy of the given credentials scope.
153 *
154 * @since 3.0
155 */
156 public AuthScope(final AuthScope authscope) {
157 super();
158 if (authscope == null) {
159 throw new IllegalArgumentException("Scope may not be null");
160 }
161 this.host = authscope.getHost();
162 this.port = authscope.getPort();
163 this.realm = authscope.getRealm();
164 this.scheme = authscope.getScheme();
165 }
166
167 /***
168 * @return the host
169 *
170 * @since 3.0
171 */
172 public String getHost() {
173 return this.host;
174 }
175
176 /***
177 * @return the port
178 *
179 * @since 3.0
180 */
181 public int getPort() {
182 return this.port;
183 }
184
185 /***
186 * @return the realm name
187 *
188 * @since 3.0
189 */
190 public String getRealm() {
191 return this.realm;
192 }
193
194 /***
195 * @return the scheme type
196 *
197 * @since 3.0
198 */
199 public String getScheme() {
200 return this.scheme;
201 }
202
203 /*** Determines if the given parameters are equal.
204 *
205 * @param p1 the parameter
206 * @param p2 the other parameter
207 * @return boolean true if the parameters are equal, otherwise false.
208 */
209 private static boolean paramsEqual(final String p1, final String p2) {
210 if (p1 == null) {
211 return p1 == p2;
212 } else {
213 return p1.equals(p2);
214 }
215 }
216
217 /*** Determines if the given parameters are equal.
218 *
219 * @param p1 the parameter
220 * @param p2 the other parameter
221 * @return boolean true if the parameters are equal, otherwise false.
222 */
223 private static boolean paramsEqual(int p1, int p2) {
224 return p1 == p2;
225 }
226
227 /***
228 * Tests if the authentication scopes match.
229 *
230 * @return the match factor. Negative value signifies no match.
231 * Non-negative signifies a match. The greater the returned value
232 * the closer the match.
233 *
234 * @since 3.0
235 */
236 public int match(final AuthScope that) {
237 int factor = 0;
238 if (paramsEqual(this.scheme, that.scheme)) {
239 factor += 1;
240 } else {
241 if (this.scheme != ANY_SCHEME && that.scheme != ANY_SCHEME) {
242 return -1;
243 }
244 }
245 if (paramsEqual(this.realm, that.realm)) {
246 factor += 2;
247 } else {
248 if (this.realm != ANY_REALM && that.realm != ANY_REALM) {
249 return -1;
250 }
251 }
252 if (paramsEqual(this.port, that.port)) {
253 factor += 4;
254 } else {
255 if (this.port != ANY_PORT && that.port != ANY_PORT) {
256 return -1;
257 }
258 }
259 if (paramsEqual(this.host, that.host)) {
260 factor += 8;
261 } else {
262 if (this.host != ANY_HOST && that.host != ANY_HOST) {
263 return -1;
264 }
265 }
266 return factor;
267 }
268
269 /***
270 * @see java.lang.Object#equals(Object)
271 */
272 public boolean equals(Object o) {
273 if (o == null) {
274 return false;
275 }
276 if (o == this) {
277 return true;
278 }
279 if (!(o instanceof AuthScope)) {
280 return super.equals(o);
281 }
282 AuthScope that = (AuthScope) o;
283 return
284 paramsEqual(this.host, that.host)
285 && paramsEqual(this.port, that.port)
286 && paramsEqual(this.realm, that.realm)
287 && paramsEqual(this.scheme, that.scheme);
288 }
289
290 /***
291 * @see java.lang.Object#toString()
292 */
293 public String toString() {
294 StringBuffer buffer = new StringBuffer();
295 if (this.scheme != null) {
296 buffer.append(this.scheme.toUpperCase());
297 buffer.append(' ');
298 }
299 if (this.realm != null) {
300 buffer.append('\'');
301 buffer.append(this.realm);
302 buffer.append('\'');
303 } else {
304 buffer.append("<any realm>");
305 }
306 if (this.host != null) {
307 buffer.append('@');
308 buffer.append(this.host);
309 if (this.port >= 0) {
310 buffer.append(':');
311 buffer.append(this.port);
312 }
313 }
314 return buffer.toString();
315 }
316
317 /***
318 * @see java.lang.Object#hashCode()
319 */
320 public int hashCode() {
321 int hash = LangUtils.HASH_SEED;
322 hash = LangUtils.hashCode(hash, this.host);
323 hash = LangUtils.hashCode(hash, this.port);
324 hash = LangUtils.hashCode(hash, this.realm);
325 hash = LangUtils.hashCode(hash, this.scheme);
326 return hash;
327 }
328 }