Index: C:/Documents and Settings/Sam/workspace/httpcomponents-client/module-client/src/test/java/org/apache/http/impl/conn/TestSCMWithServer.java =================================================================== --- C:/Documents and Settings/Sam/workspace/httpcomponents-client/module-client/src/test/java/org/apache/http/impl/conn/TestSCMWithServer.java (revision 0) +++ C:/Documents and Settings/Sam/workspace/httpcomponents-client/module-client/src/test/java/org/apache/http/impl/conn/TestSCMWithServer.java (revision 0) @@ -0,0 +1,73 @@ +package org.apache.http.impl.conn; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.apache.http.HttpHost; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.params.ConnManagerParams; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.localserver.ServerTestBase; +import org.apache.http.params.HttpParams; + +public class TestSCMWithServer extends ServerTestBase { + + public TestSCMWithServer(String testName) { + super(testName); + } + + public static void main(String args[]) { + String[] testCaseName = { TestSCMWithServer.class.getName() }; + junit.textui.TestRunner.main(testCaseName); + } + + public static Test suite() { + return new TestSuite(TestSCMWithServer.class); + } + + /** + * Helper to instantiate a SingleClientConnManager. + * + * @param params the parameters, or + * null to use defaults + * @param schreg the scheme registry, or + * null to use defaults + * + * @return a connection manager to test + */ + public SingleClientConnManager createSCCM(HttpParams params, + SchemeRegistry schreg) { + if (params == null) + params = defaultParams; + if (schreg == null) + schreg = supportedSchemes; + + return new SingleClientConnManager(params, schreg); + } + + /** + * Tests that SCM can still connect to the same host after + * a connection was aborted. + */ + public void testOpenAfterAbort() throws Exception { + HttpParams mgrpar = defaultParams.copy(); + ConnManagerParams.setMaxTotalConnections(mgrpar, 1); + + SingleClientConnManager mgr = createSCCM(mgrpar, null); + + final HttpHost target = getServerHttp(); + final HttpRoute route = new HttpRoute(target, null, false); + + ManagedClientConnection conn = mgr.getConnection(route, null); + assertTrue(conn instanceof AbstractClientConnAdapter); + ((AbstractClientConnAdapter) conn).abortConnection(); + + conn = mgr.getConnection(route, null); + assertFalse("connection should have been closed", conn.isOpen()); + conn.open(route, httpContext, defaultParams); + + mgr.releaseConnection(conn); + mgr.shutdown(); + } +} Index: C:/Documents and Settings/Sam/workspace/httpcomponents-client/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java =================================================================== --- C:/Documents and Settings/Sam/workspace/httpcomponents-client/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java (revision 659132) +++ C:/Documents and Settings/Sam/workspace/httpcomponents-client/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java (working copy) @@ -41,6 +41,7 @@ import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.RouteTracker; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.params.HttpParams; @@ -215,21 +216,33 @@ revokeConnection(); // check re-usability of the connection + boolean recreate = false; + boolean shutdown = false; + if (uniquePoolEntry.connection.isOpen()) { - final boolean shutdown = - ((uniquePoolEntry.tracker == null) || // how could that happen? - !uniquePoolEntry.tracker.toRoute().equals(route)); + RouteTracker tracker = uniquePoolEntry.tracker; + shutdown = (tracker == null || // can happen if method is aborted + !tracker.toRoute().equals(route)); + } else { + // If the connection is not open, create a new PoolEntry, + // as the connection may have been marked not reusable, + // due to aborts -- and the PoolEntry should not be reused + // either. There's no harm in recreating an entry if + // the connection is closed. + recreate = true; + } - if (shutdown) { - try { - uniquePoolEntry.shutdown(); - } catch (IOException iox) { - LOG.debug("Problem shutting down connection.", iox); - // create a new connection, just to be sure - uniquePoolEntry = new PoolEntry(); - } + if (shutdown) { + recreate = true; + try { + uniquePoolEntry.shutdown(); + } catch (IOException iox) { + LOG.debug("Problem shutting down connection.", iox); } } + + if(recreate) + uniquePoolEntry = new PoolEntry(); managedConn = new ConnAdapter(uniquePoolEntry, route);