Index: java/org/apache/commons/httpclient/HttpState.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpState.java,v
retrieving revision 1.34
diff -u -r1.34 HttpState.java
--- java/org/apache/commons/httpclient/HttpState.java 12 Jun 2004 22:47:23 -0000 1.34
+++ java/org/apache/commons/httpclient/HttpState.java 20 Jun 2004 13:09:43 -0000
@@ -355,24 +355,26 @@
* @return the credentials
*
*/
- private static Credentials matchCredentials(HashMap map, AuthScope authscope) {
- AuthScope key = authscope;
- Credentials creds = (Credentials) map.get(key);
- if (creds == null && authscope.getScheme() != null) {
- key = new AuthScope(authscope.getHost(), authscope.getPort(), authscope.getRealm());
- creds = (Credentials) map.get(key);
- }
- if (creds == null && authscope.getRealm() != null) {
- key = new AuthScope(authscope.getHost(), authscope.getPort());
- creds = (Credentials) map.get(key);
- }
- if (creds == null && authscope.getPort() >= 0) {
- key = new AuthScope(authscope.getHost(), -1);
- creds = (Credentials) map.get(key);
- }
- if (creds == null && authscope.getHost() != null) {
- key = AuthScope.ANY;
- creds = (Credentials) map.get(key);
+ private static Credentials matchCredentials(final HashMap map, final AuthScope authscope) {
+ // see if we get a direct hit
+ Credentials creds = (Credentials)map.get(authscope);
+ if (creds == null) {
+ // Nope.
+ // Do a full scan
+ int bestMatchFactor = -1;
+ AuthScope bestMatch = null;
+ Iterator items = map.keySet().iterator();
+ while (items.hasNext()) {
+ AuthScope current = (AuthScope)items.next();
+ int factor = authscope.match(current);
+ if (factor > bestMatchFactor) {
+ bestMatchFactor = factor;
+ bestMatch = current;
+ }
+ }
+ if (bestMatch != null) {
+ creds = (Credentials)map.get(bestMatch);
+ }
}
return creds;
}
Index: java/org/apache/commons/httpclient/auth/AuthScope.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthScope.java,v
retrieving revision 1.1
diff -u -r1.1 AuthScope.java
--- java/org/apache/commons/httpclient/auth/AuthScope.java 12 Jun 2004 22:47:23 -0000 1.1
+++ java/org/apache/commons/httpclient/auth/AuthScope.java 20 Jun 2004 13:09:44 -0000
@@ -103,10 +103,10 @@
public AuthScope(final String host, int port,
final String realm, final String scheme)
{
- this.host = host;
- this.port = port;
- this.realm = realm;
- this.scheme = scheme;
+ this.host = (host == null) ? ANY_HOST: host.toLowerCase();
+ this.port = (port < 0) ? ANY_PORT: port;
+ this.realm = (realm == null) ? ANY_REALM: realm;
+ this.scheme = (scheme == null) ? ANY_SCHEME: scheme.toUpperCase();;
}
/** Creates a new credentials scope for the given
@@ -198,37 +198,70 @@
return this.scheme;
}
- /** Determines if the given parameters match. Note that null acts as a
- * wildcard so if either of the parameters are null, it is considered a match.
+ /** Determines if the given parameters are equal.
*
* @param p1 the parameter
* @param p2 the other parameter
- * @return boolean true if the parameters match, otherwise false.
+ * @return boolean true if the parameters are equal, otherwise false.
*/
- private static boolean paramsMatchIgnoreCase(final String p1, final String p2) {
- return p1 == null || p2 == null || p1.equalsIgnoreCase(p2);
+ private static boolean paramsEqual(final String p1, final String p2) {
+ if (p1 == null) {
+ return p1 == p2;
+ } else {
+ return p1.equals(p2);
+ }
}
- /** Determines if the given parameters match. Note that null acts as a
- * wildcard so if either of the parameters are null, it is considered a match.
+ /** Determines if the given parameters are equal.
*
* @param p1 the parameter
* @param p2 the other parameter
- * @return boolean true if the parameters match, otherwise false.
+ * @return boolean true if the parameters are equal, otherwise false.
*/
- private static boolean paramsMatch(final String p1, final String p2) {
- return p1 == null || p2 == null || p1.equals(p2);
+ private static boolean paramsEqual(int p1, int p2) {
+ return p1 == p2;
}
- /** Determines if the given parameters match. Note that negative value acts as a
- * wildcard so if either of the parameters are negative, it is considered a match.
+ /**
+ * Tests if the authentication scopes match.
*
- * @param p1 the parameter
- * @param p2 the other parameter
- * @return boolean true if the parameters match, otherwise false.
+ * @return the match factor. Negative value signifies no match.
+ * Non-negative signifies a match. The greater the returned value
+ * the closer the match.
+ *
+ * @since 3.0
*/
- private static boolean paramsMatch(int p1, int p2) {
- return p1 < 0 || p2 < 0 || p1 == p2;
+ public int match(final AuthScope that) {
+ int factor = 0;
+ if (paramsEqual(this.scheme, that.scheme)) {
+ factor += 1;
+ } else {
+ if (this.scheme != ANY_SCHEME && that.scheme != ANY_SCHEME) {
+ return -1;
+ }
+ }
+ if (paramsEqual(this.realm, that.realm)) {
+ factor += 2;
+ } else {
+ if (this.realm != ANY_REALM && that.realm != ANY_REALM) {
+ return -1;
+ }
+ }
+ if (paramsEqual(this.port, that.port)) {
+ factor += 4;
+ } else {
+ if (this.port != ANY_PORT && that.port != ANY_PORT) {
+ return -1;
+ }
+ }
+ if (paramsEqual(this.host, that.host)) {
+ factor += 8;
+ } else {
+ if (this.host != ANY_HOST && that.host != ANY_HOST) {
+ return -1;
+ }
+ }
+ return factor;
}
/**
@@ -246,10 +279,10 @@
}
AuthScope that = (AuthScope) o;
return
- paramsMatchIgnoreCase(this.host, that.host)
- && paramsMatch(this.port, that.port)
- && paramsMatch(this.realm, that.realm)
- && paramsMatchIgnoreCase(this.scheme, that.scheme);
+ paramsEqual(this.host, that.host)
+ && paramsEqual(this.port, that.port)
+ && paramsEqual(this.realm, that.realm)
+ && paramsEqual(this.scheme, that.scheme);
}
/**
@@ -278,6 +311,7 @@
}
return buffer.toString();
}
+
/**
* @see java.lang.Object#hashCode()
*/
Index: test/org/apache/commons/httpclient/TestHttpState.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpState.java,v
retrieving revision 1.6
diff -u -r1.6 TestHttpState.java
--- test/org/apache/commons/httpclient/TestHttpState.java 13 Jun 2004 12:13:08 -0000 1.6
+++ test/org/apache/commons/httpclient/TestHttpState.java 20 Jun 2004 13:09:45 -0000
@@ -30,6 +30,8 @@
package org.apache.commons.httpclient;
+import org.apache.commons.httpclient.auth.AuthScope;
+
import junit.framework.*;
/**
@@ -39,17 +41,26 @@
* @author Rodney Waldhoff
* @author Jeff Dever
* @author Sean C. Sullivan
+ * @author Oleg Kalnichevski
*
* @version $Id: TestHttpState.java,v 1.6 2004/06/13 12:13:08 olegk Exp $
*
*/
public class TestHttpState extends TestCase {
- public final Credentials creds1 = new UsernamePasswordCredentials("user1", "pass1");
- public final Credentials creds2 = new UsernamePasswordCredentials("user2", "pass2");
-
- public final String realm1 = "realm1";
- public final String realm2 = "realm2";
+ public final static Credentials CREDS1 =
+ new UsernamePasswordCredentials("user1", "pass1");
+ public final static Credentials CREDS2 =
+ new UsernamePasswordCredentials("user2", "pass2");
+
+ public final static AuthScope SCOPE1 =
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "realm1");
+ public final static AuthScope SCOPE2 =
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "realm2");
+ public final static AuthScope BOGUS =
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "bogus");
+ public final static AuthScope DEFSCOPE =
+ new AuthScope("host", AuthScope.ANY_PORT, "realm");
// ------------------------------------------------------------ Constructor
@@ -74,10 +85,10 @@
public void testHttpStateCredentials() {
HttpState state = new HttpState();
- state.setCredentials(realm1, null, creds1);
- state.setCredentials(realm2, null, creds2);
- assertEquals(creds1, state.getCredentials(realm1, null));
- assertEquals(creds2, state.getCredentials(realm2, null));
+ state.setCredentials(SCOPE1, CREDS1);
+ state.setCredentials(SCOPE2, CREDS2);
+ assertEquals(CREDS1, state.getCredentials(SCOPE1));
+ assertEquals(CREDS2, state.getCredentials(SCOPE2));
}
public void testToString()
@@ -91,44 +102,43 @@
state.addCookie(new Cookie("flub", "duck", "yuck"));
assertNotNull(state.toString());
- state.setCredentials(realm1, null, creds1);
+ state.setCredentials(SCOPE1, CREDS1);
assertNotNull(state.toString());
- state.setProxyCredentials(realm2, null, creds2);
+ state.setProxyCredentials(SCOPE2, CREDS2);
assertNotNull(state.toString());
}
public void testHttpStateNoCredentials() {
HttpState state = new HttpState();
- assertEquals(null, state.getCredentials("bogus", null));
+ assertEquals(null, state.getCredentials(BOGUS));
}
public void testHttpStateDefaultCredentials() {
HttpState state = new HttpState();
- state.setCredentials(null, null, creds1);
- state.setCredentials(realm2, null, creds2);
- assertEquals(creds1, state.getCredentials("bogus", null));
+ state.setCredentials(AuthScope.ANY, CREDS1);
+ state.setCredentials(SCOPE2, CREDS2);
+ assertEquals(CREDS1, state.getCredentials(BOGUS));
}
-
public void testHttpStateProxyCredentials() {
HttpState state = new HttpState();
- state.setProxyCredentials(realm1, null, creds1);
- state.setProxyCredentials(realm2, null, creds2);
- assertEquals(creds1, state.getProxyCredentials(realm1, null));
- assertEquals(creds2, state.getProxyCredentials(realm2, null));
+ state.setProxyCredentials(SCOPE1, CREDS1);
+ state.setProxyCredentials(SCOPE2, CREDS2);
+ assertEquals(CREDS1, state.getProxyCredentials(SCOPE1));
+ assertEquals(CREDS2, state.getProxyCredentials(SCOPE2));
}
public void testHttpStateProxyNoCredentials() {
HttpState state = new HttpState();
- assertEquals(null, state.getProxyCredentials("bogus", null));
+ assertEquals(null, state.getProxyCredentials(BOGUS));
}
public void testHttpStateProxyDefaultCredentials() {
HttpState state = new HttpState();
- state.setProxyCredentials(null, null, creds1);
- state.setProxyCredentials(realm2, null, creds2);
- assertEquals(creds1, state.getProxyCredentials("bogus", null));
+ state.setProxyCredentials(AuthScope.ANY, CREDS1);
+ state.setProxyCredentials(SCOPE2, CREDS2);
+ assertEquals(CREDS1, state.getProxyCredentials(BOGUS));
}
// --------------------------------- Test Methods for Selecting Credentials
@@ -136,65 +146,112 @@
public void testDefaultCredentials() throws Exception {
HttpState state = new HttpState();
Credentials expected = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials(null, null, expected);
- Credentials got = state.getCredentials("realm", "host");
+ state.setCredentials(AuthScope.ANY, expected);
+ Credentials got = state.getCredentials(DEFSCOPE);
assertEquals(got, expected);
}
public void testRealmCredentials() throws Exception {
HttpState state = new HttpState();
Credentials expected = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials("realm", "host", expected);
- Credentials got = state.getCredentials("realm", "host");
+ state.setCredentials(DEFSCOPE, expected);
+ Credentials got = state.getCredentials(DEFSCOPE);
assertEquals(expected, got);
}
public void testHostCredentials() throws Exception {
HttpState state = new HttpState();
Credentials expected = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials(null, "host", expected);
- Credentials got = state.getCredentials("realm", "host");
- assertEquals(expected, got);
- }
-
- public void testBothCredentials() throws Exception {
- HttpState state = new HttpState();
- Credentials expected = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials("realm", "host", expected);
- Credentials got = state.getCredentials("realm", "host");
+ state.setCredentials(
+ new AuthScope("host", AuthScope.ANY_PORT, AuthScope.ANY_REALM), expected);
+ Credentials got = state.getCredentials(DEFSCOPE);
assertEquals(expected, got);
}
public void testWrongHostCredentials() throws Exception {
HttpState state = new HttpState();
Credentials expected = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials(null, "host1", expected);
- Credentials got = state.getCredentials("realm", "host2");
+ state.setCredentials(
+ new AuthScope("host1", AuthScope.ANY_PORT, "realm"), expected);
+ Credentials got = state.getCredentials(
+ new AuthScope("host2", AuthScope.ANY_PORT, "realm"));
assertNotSame(expected, got);
}
public void testWrongRealmCredentials() throws Exception {
HttpState state = new HttpState();
Credentials cred = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials("realm1", "host", cred);
- Credentials got = state.getCredentials("realm2", "host");
- assertNotSame(cred, got);
- }
-
- public void testRealmSpoof() throws Exception {
- HttpState state = new HttpState();
- Credentials cred = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials(null, "admin.apache.org", cred);
- Credentials got = state.getCredentials("admin.apache.org", "myhost");
+ state.setCredentials(
+ new AuthScope("host", AuthScope.ANY_PORT, "realm1"), cred);
+ Credentials got = state.getCredentials(
+ new AuthScope("host", AuthScope.ANY_PORT, "realm2"));
assertNotSame(cred, got);
}
+
+ // ------------------------------- Test Methods for matching Credentials
- public void testRealmSpoof2() throws Exception {
+ public void testScopeMatching() {
+ AuthScope authscope1 = new AuthScope("somehost", 80, "somerealm", "somescheme");
+ AuthScope authscope2 = new AuthScope("someotherhost", 80, "somerealm", "somescheme");
+ assertTrue(authscope1.match(authscope2) < 0);
+
+ int m1 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "somescheme"));
+ int m2 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm", AuthScope.ANY_SCHEME));
+ assertTrue(m2 > m1);
+
+ m1 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "somescheme"));
+ m2 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm", AuthScope.ANY_SCHEME));
+ assertTrue(m2 > m1);
+
+ m1 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm", "somescheme"));
+ m2 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, 80, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME));
+ assertTrue(m2 > m1);
+
+ m1 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, 80, "somerealm", "somescheme"));
+ m2 = authscope1.match(
+ new AuthScope("somehost", AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME));
+ assertTrue(m2 > m1);
+
+ m1 = authscope1.match(AuthScope.ANY);
+ m2 = authscope1.match(
+ new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "somescheme"));
+ assertTrue(m2 > m1);
+ }
+
+ public void testCredentialsMatching() {
+ Credentials creds1 = new UsernamePasswordCredentials("name1", "pass1");
+ Credentials creds2 = new UsernamePasswordCredentials("name2", "pass2");
+ Credentials creds3 = new UsernamePasswordCredentials("name3", "pass3");
+
+ AuthScope scope1 = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM);
+ AuthScope scope2 = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm");
+ AuthScope scope3 = new AuthScope("somehost", AuthScope.ANY_PORT, AuthScope.ANY_REALM);
+
HttpState state = new HttpState();
- Credentials cred = new UsernamePasswordCredentials("name", "pass");
- state.setCredentials(null, "whatever", cred);
- Credentials got = state.getCredentials("nullwhatever", null);
- assertNotSame(cred, got);
- }
+ state.setCredentials(scope1, creds1);
+ state.setCredentials(scope2, creds2);
+ state.setCredentials(scope3, creds3);
+
+ Credentials got = state.getCredentials(
+ new AuthScope("someotherhost", 80, "someotherrealm", "basic"));
+ Credentials expected = creds1;
+ assertEquals(expected, got);
+
+ got = state.getCredentials(
+ new AuthScope("someotherhost", 80, "somerealm", "basic"));
+ expected = creds2;
+ assertEquals(expected, got);
+ got = state.getCredentials(
+ new AuthScope("somehost", 80, "someotherrealm", "basic"));
+ expected = creds3;
+ assertEquals(expected, got);
+ }
}