diff --git a/module-client/src/main/java/org/apache/http/client/protocol/RequestAddCookies.java b/module-client/src/main/java/org/apache/http/client/protocol/RequestAddCookies.java index 2a1f753ea..022f7846f 100644 --- a/module-client/src/main/java/org/apache/http/client/protocol/RequestAddCookies.java +++ b/module-client/src/main/java/org/apache/http/client/protocol/RequestAddCookies.java @@ -58,7 +58,7 @@ import org.apache.http.protocol.ExecutionContext; /** * Request interceptor that matches cookies available in the current - * {@link HttpState} to the request being executed and generates + * {@link CookieStore} to the request being executed and generates * corresponding cookierequest headers. * * @author Oleg Kalnichevski diff --git a/module-client/src/main/java/org/apache/http/client/protocol/ResponseProcessCookies.java b/module-client/src/main/java/org/apache/http/client/protocol/ResponseProcessCookies.java index 740bca143..588db75dc 100644 --- a/module-client/src/main/java/org/apache/http/client/protocol/ResponseProcessCookies.java +++ b/module-client/src/main/java/org/apache/http/client/protocol/ResponseProcessCookies.java @@ -48,7 +48,7 @@ import org.apache.http.cookie.SM; import org.apache.http.protocol.HttpContext; /** - * Response interceptor that populates the current {@link HttpState} with data + * Response interceptor that populates the current {@link CookieStore} with data * contained in response cookies received in the given the HTTP response. * * @author Oleg Kalnichevski diff --git a/module-client/src/main/java/org/apache/http/impl/client/BasicCookieStore.java b/module-client/src/main/java/org/apache/http/impl/client/BasicCookieStore.java new file mode 100644 index 000000000..b140a9768 --- /dev/null +++ b/module-client/src/main/java/org/apache/http/impl/client/BasicCookieStore.java @@ -0,0 +1,161 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Date; +import java.util.Iterator; + +import org.apache.http.client.CookieStore; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieIdentityComparator; + +/** + * Default implementation of {@link CookieStore} + * + * @author Remy Maucherat + * @author Rodney Waldhoff + * @author Jeff Dever + * @author Sean C. Sullivan + * @author Michael Becke + * @author Oleg Kalnichevski + * @author Mike Bowler + * @author Adrian Sutton + * + * @since 4.0 + */ +public class BasicCookieStore implements CookieStore { + + private final ArrayList cookies; + + private final Comparator cookieComparator; + + // -------------------------------------------------------- Class Variables + + /** + * Default constructor. + */ + public BasicCookieStore() { + super(); + this.cookies = new ArrayList(); + this.cookieComparator = new CookieIdentityComparator(); + } + + /** + * Adds an {@link Cookie HTTP cookie}, replacing any existing equivalent cookies. + * If the given cookie has already expired it will not be added, but existing + * values will still be removed. + * + * @param cookie the {@link Cookie cookie} to be added + * + * @see #addCookies(Cookie[]) + * + */ + public synchronized void addCookie(Cookie cookie) { + if (cookie != null) { + // first remove any old cookie that is equivalent + for (Iterator it = cookies.iterator(); it.hasNext();) { + Cookie tmp = (Cookie) it.next(); + if (cookieComparator.compare(cookie, tmp) == 0) { + it.remove(); + break; + } + } + if (!cookie.isExpired(new Date())) { + cookies.add(cookie); + } + } + } + + /** + * Adds an array of {@link Cookie HTTP cookies}. Cookies are added individually and + * in the given array order. If any of the given cookies has already expired it will + * not be added, but existing values will still be removed. + * + * @param cookies the {@link Cookie cookies} to be added + * + * @see #addCookie(Cookie) + * + */ + public synchronized void addCookies(Cookie[] cookies) { + if (cookies != null) { + for (int i = 0; i < cookies.length; i++) { + this.addCookie(cookies[i]); + } + } + } + + /** + * Returns an array of {@link Cookie cookies} that this HTTP + * state currently contains. + * + * @return an array of {@link Cookie cookies}. + */ + public synchronized Cookie[] getCookies() { + return (Cookie[]) (cookies.toArray(new Cookie[cookies.size()])); + } + + /** + * Removes all of {@link Cookie cookies} in this HTTP state + * that have expired by the specified {@link java.util.Date date}. + * + * @return true if any cookies were purged. + * + * @see Cookie#isExpired(Date) + */ + public synchronized boolean clearExpired(final Date date) { + if (date == null) { + return false; + } + boolean removed = false; + Iterator it = cookies.iterator(); + while (it.hasNext()) { + if (((Cookie) (it.next())).isExpired(date)) { + it.remove(); + removed = true; + } + } + return removed; + } + + public String toString() { + return cookies.toString(); + } + + /** + * Clears all cookies. + */ + public synchronized void clear() { + cookies.clear(); + } + +} diff --git a/module-client/src/main/java/org/apache/http/impl/client/BasicCredentialsProvider.java b/module-client/src/main/java/org/apache/http/impl/client/BasicCredentialsProvider.java new file mode 100644 index 000000000..9c531d5dd --- /dev/null +++ b/module-client/src/main/java/org/apache/http/impl/client/BasicCredentialsProvider.java @@ -0,0 +1,141 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.apache.http.client.CredentialsProvider; + +/** + * Default implementation of {@link CredentialsProvider} + * + * @author Remy Maucherat + * @author Rodney Waldhoff + * @author Jeff Dever + * @author Sean C. Sullivan + * @author Michael Becke + * @author Oleg Kalnichevski + * @author Mike Bowler + * @author Adrian Sutton + * + * @since 4.0 + */ +public class BasicCredentialsProvider implements CredentialsProvider { + + private final HashMap credMap; + + /** + * Default constructor. + */ + public BasicCredentialsProvider() { + super(); + this.credMap = new HashMap(); + } + + /** + * Sets the {@link Credentials credentials} for the given authentication + * scope. Any previous credentials for the given scope will be overwritten. + * + * @param authscope the {@link AuthScope authentication scope} + * @param credentials the authentication {@link Credentials credentials} + * for the given scope. + * + * @see #getCredentials(AuthScope) + */ + public synchronized void setCredentials(final AuthScope authscope, final Credentials credentials) { + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); + } + credMap.put(authscope, credentials); + } + + /** + * Find matching {@link Credentials credentials} for the given authentication scope. + * + * @param map the credentials hash map + * @param token the {@link AuthScope authentication scope} + * @return the credentials + * + */ + 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; + } + + /** + * Get the {@link Credentials credentials} for the given authentication scope. + * + * @param authscope the {@link AuthScope authentication scope} + * @return the credentials + * + * @see #setCredentials(AuthScope, Credentials) + */ + public synchronized Credentials getCredentials(final AuthScope authscope) { + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); + } + return matchCredentials(this.credMap, authscope); + } + + public String toString() { + return credMap.toString(); + } + + /** + * Clears all credentials. + */ + public synchronized void clear() { + this.credMap.clear(); + } + +} diff --git a/module-client/src/test/java/org/apache/http/client/TestAll.java b/module-client/src/test/java/org/apache/http/client/TestAll.java index 81748a6ed..fcb1e248b 100644 --- a/module-client/src/test/java/org/apache/http/client/TestAll.java +++ b/module-client/src/test/java/org/apache/http/client/TestAll.java @@ -55,7 +55,6 @@ public class TestAll extends TestCase { suite.addTest(TestAllConn.suite()); suite.addTest(TestAllConnImpl.suite()); suite.addTest(TestAllSSL.suite()); - suite.addTest(TestHttpState.suite()); return suite; } diff --git a/module-client/src/test/java/org/apache/http/conn/TestHttpRoute.java b/module-client/src/test/java/org/apache/http/conn/TestHttpRoute.java index 671ad5c53..a714b4313 100644 --- a/module-client/src/test/java/org/apache/http/conn/TestHttpRoute.java +++ b/module-client/src/test/java/org/apache/http/conn/TestHttpRoute.java @@ -245,7 +245,8 @@ public class TestHttpRoute extends TestCase { // for reference: this one should succeed HttpRoute route = new HttpRoute(TARGET1, null, chain1, false, true, false); - + assertNotNull(route); + try { route = new HttpRoute(null, null, chain1, false, true, false); diff --git a/module-client/src/test/java/org/apache/http/conn/TestRouteDirector.java b/module-client/src/test/java/org/apache/http/conn/TestRouteDirector.java index b30e5e2b9..1fef210ae 100644 --- a/module-client/src/test/java/org/apache/http/conn/TestRouteDirector.java +++ b/module-client/src/test/java/org/apache/http/conn/TestRouteDirector.java @@ -32,8 +32,6 @@ package org.apache.http.conn; import java.net.InetAddress; -import java.util.HashSet; -import java.util.Iterator; import junit.framework.Test; import junit.framework.TestCase; @@ -199,7 +197,6 @@ public class TestRouteDirector extends TestCase { HttpHost[] chainA = { PROXY1 }; HttpHost[] chainB = { PROXY1, PROXY2 }; HttpHost[] chainC = { PROXY2, PROXY1 }; - HttpHost[] chainD = { PROXY2 }; RouteDirector rowdy = new RouteDirector(); HttpRoute route1cA = new HttpRoute(TARGET1, null, chainA, @@ -210,7 +207,6 @@ public class TestRouteDirector extends TestCase { false, false, false); HttpRoute route1cD = new HttpRoute(TARGET1, null, chainC, false, false, false); - HttpRoute route1c0 = new HttpRoute(TARGET1, null, false); int step = rowdy.nextStep(route1cA, null); assertEquals("wrong step to route1cA", diff --git a/module-client/src/test/java/org/apache/http/impl/client/TestAllHttpClientImpl.java b/module-client/src/test/java/org/apache/http/impl/client/TestAllHttpClientImpl.java index ed8614bcd..64cc131b0 100644 --- a/module-client/src/test/java/org/apache/http/impl/client/TestAllHttpClientImpl.java +++ b/module-client/src/test/java/org/apache/http/impl/client/TestAllHttpClientImpl.java @@ -42,6 +42,7 @@ public class TestAllHttpClientImpl extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(); + suite.addTest(TestBasicCredentialsProvider.suite()); return suite; } diff --git a/module-client/src/test/java/org/apache/http/client/TestHttpState.java b/module-client/src/test/java/org/apache/http/impl/client/TestBasicCredentialsProvider.java similarity index 86% rename from module-client/src/test/java/org/apache/http/client/TestHttpState.java rename to module-client/src/test/java/org/apache/http/impl/client/TestBasicCredentialsProvider.java index 3632f513b..2288e5c94 100644 --- a/module-client/src/test/java/org/apache/http/client/TestHttpState.java +++ b/module-client/src/test/java/org/apache/http/impl/client/TestBasicCredentialsProvider.java @@ -26,7 +26,7 @@ * . */ -package org.apache.http.client; +package org.apache.http.impl.client; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; @@ -36,7 +36,7 @@ import junit.framework.*; /** * - * Simple tests for {@link HttpState}. + * Simple tests for {@link BasicCredentialsProvider}. * * @author Rodney Waldhoff * @author Jeff Dever @@ -46,7 +46,7 @@ import junit.framework.*; * @version $Id$ * */ -public class TestHttpState extends TestCase { +public class TestBasicCredentialsProvider extends TestCase { public final static Credentials CREDS1 = new UsernamePasswordCredentials("user1", "pass1"); @@ -64,40 +64,40 @@ public class TestHttpState extends TestCase { // ------------------------------------------------------------ Constructor - public TestHttpState(String testName) { + public TestBasicCredentialsProvider(String testName) { super(testName); } // ------------------------------------------------------------------- Main public static void main(String args[]) { - String[] testCaseName = { TestHttpState.class.getName() }; + String[] testCaseName = { TestBasicCredentialsProvider.class.getName() }; junit.textui.TestRunner.main(testCaseName); } // ------------------------------------------------------- TestCase Methods public static Test suite() { - return new TestSuite(TestHttpState.class); + return new TestSuite(TestBasicCredentialsProvider.class); } // ----------------------------------------------------------- Test Methods - public void testHttpStateCredentials() { - HttpState state = new HttpState(); + public void testBasicCredentialsProviderCredentials() { + BasicCredentialsProvider state = new BasicCredentialsProvider(); state.setCredentials(SCOPE1, CREDS1); state.setCredentials(SCOPE2, CREDS2); assertEquals(CREDS1, state.getCredentials(SCOPE1)); assertEquals(CREDS2, state.getCredentials(SCOPE2)); } - public void testHttpStateNoCredentials() { - HttpState state = new HttpState(); + public void testBasicCredentialsProviderNoCredentials() { + BasicCredentialsProvider state = new BasicCredentialsProvider(); assertEquals(null, state.getCredentials(BOGUS)); } - public void testHttpStateDefaultCredentials() { - HttpState state = new HttpState(); + public void testBasicCredentialsProviderDefaultCredentials() { + BasicCredentialsProvider state = new BasicCredentialsProvider(); state.setCredentials(AuthScope.ANY, CREDS1); state.setCredentials(SCOPE2, CREDS2); assertEquals(CREDS1, state.getCredentials(BOGUS)); @@ -106,7 +106,7 @@ public class TestHttpState extends TestCase { // --------------------------------- Test Methods for Selecting Credentials public void testDefaultCredentials() throws Exception { - HttpState state = new HttpState(); + BasicCredentialsProvider state = new BasicCredentialsProvider(); Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials(AuthScope.ANY, expected); Credentials got = state.getCredentials(DEFSCOPE); @@ -114,7 +114,7 @@ public class TestHttpState extends TestCase { } public void testRealmCredentials() throws Exception { - HttpState state = new HttpState(); + BasicCredentialsProvider state = new BasicCredentialsProvider(); Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials(DEFSCOPE, expected); Credentials got = state.getCredentials(DEFSCOPE); @@ -122,7 +122,7 @@ public class TestHttpState extends TestCase { } public void testHostCredentials() throws Exception { - HttpState state = new HttpState(); + BasicCredentialsProvider state = new BasicCredentialsProvider(); Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials( new AuthScope("host", AuthScope.ANY_PORT, AuthScope.ANY_REALM), expected); @@ -131,7 +131,7 @@ public class TestHttpState extends TestCase { } public void testWrongHostCredentials() throws Exception { - HttpState state = new HttpState(); + BasicCredentialsProvider state = new BasicCredentialsProvider(); Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials( new AuthScope("host1", AuthScope.ANY_PORT, "realm"), expected); @@ -141,7 +141,7 @@ public class TestHttpState extends TestCase { } public void testWrongRealmCredentials() throws Exception { - HttpState state = new HttpState(); + BasicCredentialsProvider state = new BasicCredentialsProvider(); Credentials cred = new UsernamePasswordCredentials("name", "pass"); state.setCredentials( new AuthScope("host", AuthScope.ANY_PORT, "realm1"), cred); @@ -196,7 +196,7 @@ public class TestHttpState extends TestCase { 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(); + BasicCredentialsProvider state = new BasicCredentialsProvider(); state.setCredentials(scope1, creds1); state.setCredentials(scope2, creds2); state.setCredentials(scope3, creds3); diff --git a/module-client/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java b/module-client/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java index 79ffaed3b..46cf0fcde 100644 --- a/module-client/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java +++ b/module-client/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java @@ -197,7 +197,9 @@ public class TestTSCCMNoServer extends TestCase { HttpRoute route2 = new HttpRoute(target2, null, false); ManagedClientConnection conn1 = mgr.getConnection(route1); + assertNotNull(conn1); ManagedClientConnection conn2 = mgr.getConnection(route2); + assertNotNull(conn2); try { // this should fail quickly, connection has not been released @@ -242,8 +244,11 @@ public class TestTSCCMNoServer extends TestCase { // route 3, limit 3 ManagedClientConnection conn1 = mgr.getConnection(route3, 10L); + assertNotNull(conn1); ManagedClientConnection conn2 = mgr.getConnection(route3, 10L); + assertNotNull(conn2); ManagedClientConnection conn3 = mgr.getConnection(route3, 10L); + assertNotNull(conn3); try { // should fail quickly, connection has not been released mgr.getConnection(route3, 10L); diff --git a/module-client/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java b/module-client/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java index 5c44c9e43..294df6a0a 100644 --- a/module-client/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java +++ b/module-client/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java @@ -31,12 +31,8 @@ package org.apache.http.mockup; import java.net.Socket; -import java.net.InetAddress; import org.apache.http.conn.SecureSocketFactory; -import org.apache.http.params.HttpParams; - - /** * {@link SecureSocketFactory} mockup implementation.