cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
olegk 2004/04/08 15:25:11 Modified:httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java Log: Removes references to deprecated methods Contributed by Oleg Kalnichevski Revision ChangesPath 1.20 +12 -8 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java Index: TestHttpConnectionManager.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- TestHttpConnectionManager.java28 Mar 2004 21:26:50 - 1.19 +++ TestHttpConnectionManager.java8 Apr 2004 22:25:11 - 1.20 @@ -372,8 +372,10 @@ public void testShutdownAll() { MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); -connectionManager.setMaxConnectionsPerHost(1); -connectionManager.setMaxTotalConnections(1); +connectionManager.getParams().setIntParameter( +HttpConnectionManagerParams.MAX_HOST_CONNECTIONS, 1); +connectionManager.getParams().setIntParameter( +HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS, 1); HostConfiguration host1 = new HostConfiguration(); host1.setHost(host1, -1, http); @@ -416,8 +418,10 @@ public void testShutdown() { MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); -connectionManager.setMaxConnectionsPerHost(1); -connectionManager.setMaxTotalConnections(1); +connectionManager.getParams().setIntParameter( +HttpConnectionManagerParams.MAX_HOST_CONNECTIONS, 1); +connectionManager.getParams().setIntParameter( +HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS, 1); HostConfiguration host1 = new HostConfiguration(); host1.setHost(host1, -1, http); - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
mbecke 2004/03/28 13:06:24 Modified:httpclient/src/java/org/apache/commons/httpclient Tag: HTTPCLIENT_2_0_BRANCH MultiThreadedHttpConnectionManager.java httpclient/src/test/org/apache/commons/httpclient Tag: HTTPCLIENT_2_0_BRANCH TestHttpConnectionManager.java Log: Added MultiThreadedHttpConnectionManager shutdown() and shutdownAll(). PR: 27589 Submitted by: Michael Becke Reviewed by: Oleg Kalnichevski Revision ChangesPath No revision No revision 1.17.2.8 +169 -15 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java Index: MultiThreadedHttpConnectionManager.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v retrieving revision 1.17.2.7 retrieving revision 1.17.2.8 diff -u -r1.17.2.7 -r1.17.2.8 --- MultiThreadedHttpConnectionManager.java 22 Feb 2004 18:21:13 - 1.17.2.7 +++ MultiThreadedHttpConnectionManager.java 28 Mar 2004 21:06:24 - 1.17.2.8 @@ -39,11 +39,12 @@ import java.lang.ref.WeakReference; import java.net.InetAddress; import java.net.SocketException; -import java.util.Collections; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; +import java.util.WeakHashMap; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.logging.Log; @@ -75,7 +76,7 @@ * A mapping from Reference to ConnectionSource. Used to reclaim resources when connections * are lost to the garbage collector. */ -public static final Map REFERENCE_TO_CONNECTION_SOURCE = Collections.synchronizedMap(new HashMap()); +private static final Map REFERENCE_TO_CONNECTION_SOURCE = new HashMap(); /** * The reference queue used to track when HttpConnections are lost to the @@ -88,9 +89,40 @@ */ private static ReferenceQueueThread REFERENCE_QUEUE_THREAD; -static { -REFERENCE_QUEUE_THREAD = new ReferenceQueueThread(); -REFERENCE_QUEUE_THREAD.start(); +/** + * Holds references to all active instances of this class. + */ +private static WeakHashMap ALL_CONNECTION_MANAGERS = new WeakHashMap(); + +/** + * Shuts down and cleans up resources used by all instances of + * MultiThreadedHttpConnectionManager. All static resources are released, all threads are + * stopped, and [EMAIL PROTECTED] #shutdown()} is called on all live instaces of + * MultiThreadedHttpConnectionManager. + * + * @see #shutdown() + */ +public static void shutdownAll() { + +synchronized (REFERENCE_TO_CONNECTION_SOURCE) { +// shutdown all connection managers +synchronized (ALL_CONNECTION_MANAGERS) { +Iterator connIter = ALL_CONNECTION_MANAGERS.keySet().iterator(); +while (connIter.hasNext()) { +MultiThreadedHttpConnectionManager connManager = +(MultiThreadedHttpConnectionManager) connIter.next(); +connIter.remove(); +connManager.shutdown(); +} +} + +// shutdown static resources +if (REFERENCE_QUEUE_THREAD != null) { +REFERENCE_QUEUE_THREAD.shutdown(); +REFERENCE_QUEUE_THREAD = null; +} +REFERENCE_TO_CONNECTION_SOURCE.clear(); +} } /** @@ -120,10 +152,57 @@ source.connectionPool = connectionPool; source.hostConfiguration = hostConfiguration; -REFERENCE_TO_CONNECTION_SOURCE.put( -connection.reference, -source -); +synchronized (REFERENCE_TO_CONNECTION_SOURCE) { + +// start the reference queue thread if needed +if (REFERENCE_QUEUE_THREAD == null) { +REFERENCE_QUEUE_THREAD = new ReferenceQueueThread(); +REFERENCE_QUEUE_THREAD.start(); +} + +REFERENCE_TO_CONNECTION_SOURCE.put( +connection.reference, +source +); +} +} + +/** + * Closes and releases all connections currently checked out of the given connection pool. + * @param connectionPool the connection pool to shutdown the connections for + */ +private static void shutdownCheckedOutConnections(ConnectionPool
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java TestWebappCookie.java TestWebappMethods.java
olegk 2004/02/15 05:30:55 Modified:httpclient/src/java/org/apache/commons/httpclient HttpMethod.java HttpMethodBase.java httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java TestWebappCookie.java TestWebappMethods.java Log: PR #26060 (Log level for message should be debug instead of error) HttpMethod#getResponseBody HttpMethod#getResponseBodyAsString changed to propagate IOException to the caller instead of logging and discarding it. The patch breaks 2.0 API compatibility. Contributed by Oleg Kalnichevski Revision ChangesPath 1.33 +10 -6 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java Index: HttpMethod.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- HttpMethod.java 19 Nov 2003 21:11:16 - 1.32 +++ HttpMethod.java 15 Feb 2004 13:30:55 - 1.33 @@ -398,8 +398,10 @@ * * @return The response body, or codenull/code if the * body is not available. + * + * @throws IOException if an I/O (transport) problem occurs */ -byte[] getResponseBody(); +byte[] getResponseBody() throws IOException; /** * Returns the response body of the HTTP method, if any, as a [EMAIL PROTECTED] String}. @@ -413,8 +415,10 @@ * * @return The response body converted to a codeString/code, or codenull/code * if the body is not available. + * + * @throws IOException if an I/O (transport) problem occurs */ -String getResponseBodyAsString(); +String getResponseBodyAsString() throws IOException; /** * Returns the response body of the HTTP method, if any, as an InputStream. 1.198 +23 -22 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java Index: HttpMethodBase.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v retrieving revision 1.197 retrieving revision 1.198 diff -u -r1.197 -r1.198 --- HttpMethodBase.java 14 Jan 2004 20:48:43 - 1.197 +++ HttpMethodBase.java 15 Feb 2004 13:30:55 - 1.198 @@ -672,26 +672,24 @@ * If response body is not available or cannot be read, returns ttnull/tt * * @return The response body. + * + * @throws IOException If an I/O (transport) problem occurs while obtaining the + * response body. */ -public byte[] getResponseBody() { +public byte[] getResponseBody() throws IOException { if (this.responseBody == null) { -try { -InputStream instream = getResponseBodyAsStream(); -if (instream != null) { -LOG.debug(Buffering response body); -ByteArrayOutputStream outstream = new ByteArrayOutputStream(); -byte[] buffer = new byte[4096]; -int len; -while ((len = instream.read(buffer)) 0) { -outstream.write(buffer, 0, len); -} -outstream.close(); -setResponseStream(null); -this.responseBody = outstream.toByteArray(); +InputStream instream = getResponseBodyAsStream(); +if (instream != null) { +LOG.debug(Buffering response body); +ByteArrayOutputStream outstream = new ByteArrayOutputStream(); +byte[] buffer = new byte[4096]; +int len; +while ((len = instream.read(buffer)) 0) { +outstream.write(buffer, 0, len); } -} catch (IOException e) { -LOG.error(I/O failure reading response body, e); -this.responseBody = null; +outstream.close(); +setResponseStream(null); +this.responseBody = outstream.toByteArray(); } } return this.responseBody; @@ -725,8 +723,11 @@ * in ttContent-Type/tt header. * * @return The response body. + * + * @throws IOException If an I/O (transport) problem occurs while obtaining the + * response body. */ -public String getResponseBodyAsString() { +public String getResponseBodyAsString() throws IOException { byte[] rawdata = null; if (responseAvailable()) {
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
olegk 2004/01/12 15:03:12 Modified:httpclient/src/java/org/apache/commons/httpclient HttpMethodDirector.java httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java Log: PR #25370 (exception during writeRequest leaves the connection un-released) Contributed by Michael Becke Reviewed by Oleg Kalnichevski Revision ChangesPath 1.13 +54 -51 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java Index: HttpMethodDirector.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- HttpMethodDirector.java 12 Jan 2004 18:50:14 - 1.12 +++ HttpMethodDirector.java 12 Jan 2004 23:03:12 - 1.13 @@ -369,17 +369,17 @@ // loop until the method is successfully processed, the retryHandler // returns false or a non-recoverable exception is thrown -while (true) { -execCount++; -requestSent = false; +try { +while (true) { +execCount++; +requestSent = false; -if (LOG.isTraceEnabled()) { -LOG.trace(Attempt number + execCount + to process request); -} -if (!this.conn.isOpen()) { -// this connection must be opened before it can be used -// This has nothing to do with opening a secure tunnel -try { +if (LOG.isTraceEnabled()) { +LOG.trace(Attempt number + execCount + to process request); +} +if (!this.conn.isOpen()) { +// this connection must be opened before it can be used +// This has nothing to do with opening a secure tunnel this.conn.open(); if (this.conn.isProxied() this.conn.isSecure() !(method instanceof ConnectMethod)) { @@ -389,49 +389,52 @@ return; } } -} catch (IOException e) { -releaseConnection = true; -throw e; -} catch (RuntimeException e) { -releaseConnection = true; -throw e; } -} -try { -method.execute(state, this.conn); -break; -} catch (HttpRecoverableException httpre) { -if (LOG.isDebugEnabled()) { +try { +method.execute(state, this.conn); +break; +} catch (HttpRecoverableException httpre) { LOG.debug(Closing the connection.); -} -this.conn.close(); -LOG.info(Recoverable exception caught when processing request); -// update the recoverable exception count. -recoverableExceptionCount++; +this.conn.close(); +LOG.info(Recoverable exception caught when processing request); +// update the recoverable exception count. +recoverableExceptionCount++; -// test if this method should be retried -MethodRetryHandler handler = method.getMethodRetryHandler(); -if (handler == null) { -handler = new DefaultMethodRetryHandler(); -} -if (!handler.retryMethod( -method, -this.conn, -httpre, -execCount, -requestSent) -) { -LOG.warn( -Recoverable exception caught but MethodRetryHandler.retryMethod() -+ returned false, rethrowing exception -); -// this connection can no longer be used, it has been closed -releaseConnection = true; -throw httpre; +// test if this method should be retried +MethodRetryHandler handler = method.getMethodRetryHandler(); +if (handler == null) { +handler = new DefaultMethodRetryHandler(); +} +if (!handler.retryMethod( +method, +
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
mbecke 2003/11/19 05:27:02 Modified:httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java Log: Changed MultiThreadedHttpConnectionManager to move to a single GC thread. Fixes memory and thread leaks. PR: 24309 Submitted by: Michael Becke Reviewed by: Eric Johnson Revision ChangesPath 1.14 +6 -5 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java Index: TestHttpConnectionManager.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- TestHttpConnectionManager.java19 Nov 2003 00:43:12 - 1.13 +++ TestHttpConnectionManager.java19 Nov 2003 13:27:02 - 1.14 @@ -229,6 +229,8 @@ httpClient = null; method = null; +System.gc(); + // this sleep appears to be necessary in order to give the JVM // time to clean up the miscellaneous pointers to the connection manager try { @@ -237,7 +239,6 @@ fail(shouldn't be interrupted.); } -System.gc(); Object connectionManager = wr.get(); assertNull(connectionManager should be null, connectionManager); } - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
mbecke 2003/11/19 05:27:42 Modified:httpclient/src/test/org/apache/commons/httpclient Tag: HTTPCLIENT_2_0_BRANCH TestHttpConnectionManager.java Log: Changed MultiThreadedHttpConnectionManager to move to a single GC thread. Fixes memory and thread leaks. PR: 24309 Submitted by: Michael Becke Reviewed by: Eric Johnson Revision ChangesPath No revision No revision 1.8.2.2 +6 -5 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java Index: TestHttpConnectionManager.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v retrieving revision 1.8.2.1 retrieving revision 1.8.2.2 diff -u -r1.8.2.1 -r1.8.2.2 --- TestHttpConnectionManager.java19 Nov 2003 00:10:45 - 1.8.2.1 +++ TestHttpConnectionManager.java19 Nov 2003 13:27:42 - 1.8.2.2 @@ -232,6 +232,8 @@ httpClient = null; method = null; +System.gc(); + // this sleep appears to be necessary in order to give the JVM // time to clean up the miscellaneous pointers to the connection manager try { @@ -240,7 +242,6 @@ fail(shouldn't be interrupted.); } -System.gc(); Object connectionManager = wr.get(); assertNull(connectionManager should be null, connectionManager); } - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
mbecke 2003/11/18 16:10:45 Modified:httpclient/src/java/org/apache/commons/httpclient Tag: HTTPCLIENT_2_0_BRANCH MultiThreadedHttpConnectionManager.java httpclient/src/test/org/apache/commons/httpclient Tag: HTTPCLIENT_2_0_BRANCH TestHttpConnectionManager.java Log: Changed MultiThreadedHttpConnectionManager to move to a single GC thread. Fixes memory and thread leaks. PR: 24309 Submitted by: Michael Becke Reviewed by: Eric Johnson Revision ChangesPath No revision No revision 1.17.2.5 +153 -61 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java Index: MultiThreadedHttpConnectionManager.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v retrieving revision 1.17.2.4 retrieving revision 1.17.2.5 diff -u -r1.17.2.4 -r1.17.2.5 --- MultiThreadedHttpConnectionManager.java 1 Sep 2003 18:05:51 - 1.17.2.4 +++ MultiThreadedHttpConnectionManager.java 19 Nov 2003 00:10:45 - 1.17.2.5 @@ -103,6 +103,79 @@ /** The default maximum number of connections allowed overall */ public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20; +/** + * A mapping from Reference to ConnectionSource. Used to reclaim resources when connections + * are lost to the garbage collector. + */ +public static final Map REFERENCE_TO_CONNECTION_SOURCE; + +/** + * The reference queue used to track when HttpConnections are lost to the + * garbage collector + */ +private static final ReferenceQueue REFERENCE_QUEUE; + +/** + * The thread responsible for handling lost connections. + */ +private static ReferenceQueueThread REFERENCE_QUEUE_THREAD; + + +static { +REFERENCE_TO_CONNECTION_SOURCE = Collections.synchronizedMap(new HashMap()); +REFERENCE_QUEUE = new ReferenceQueue(); +REFERENCE_QUEUE_THREAD = new ReferenceQueueThread(); +REFERENCE_QUEUE_THREAD.start(); +} + +/** + * Stores the reference to the given connection along with the hostConfig and connection pool. + * These values will be used to reclaim resources if the connection is lost to the garbage + * collector. This method should be called before a connection is released from the connection + * manager. + * + * pA static reference to the connection manager will also be stored. To ensure that + * the connection manager can be GCed [EMAIL PROTECTED] #removeReferenceToConnection(HttpConnection)} + * should be called for all connections that the connection manager is storing a reference + * to./p + * + * @param connection the connection to create a reference for + * @param hostConfiguration the connection's host config + * @param connectionPool the connection pool that created the connection + * + * @see #removeReferenceToConnection(HttpConnection) + */ +private static void storeReferenceToConnection( +HttpConnectionWithReference connection, +HostConfiguration hostConfiguration, +ConnectionPool connectionPool +) { + +ConnectionSource source = new ConnectionSource(); +source.connectionPool = connectionPool; +source.hostConfiguration = hostConfiguration; + +REFERENCE_TO_CONNECTION_SOURCE.put( +connection.reference, +source +); +} + +/** + * Removes the reference being stored for the given connection. This method should be called + * when the connection manager again has a direct reference to the connection. + * + * @param connection the connection to remove the reference for + * + * @see #storeReferenceToConnection(HttpConnection, HostConfiguration, ConnectionPool) + */ +private static void removeReferenceToConnection(HttpConnectionWithReference connection) { + +synchronized (REFERENCE_TO_CONNECTION_SOURCE) { +REFERENCE_TO_CONNECTION_SOURCE.remove(connection.reference); +} +} + // - Instance Variables /** Maximum number of connections allowed per host */ private int maxHostConnections = DEFAULT_MAX_HOST_CONNECTIONS; @@ -116,26 +189,11 @@ /** Connection Pool */ private ConnectionPool connectionPool; -/** mapping from reference to hostConfiguration */ -private Map referenceToHostConfig; - -/** -
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
mbecke 2003/11/18 16:43:12 Modified:httpclient/src/java/org/apache/commons/httpclient MultiThreadedHttpConnectionManager.java httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java Log: Changed MultiThreadedHttpConnectionManager to move to a single GC thread. Fixes memory and thread leaks. PR: 24309 Submitted by: Michael Becke Reviewed by: Eric Johnson Revision ChangesPath 1.28 +153 -62 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java Index: MultiThreadedHttpConnectionManager.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v retrieving revision 1.27 retrieving revision 1.28 diff -u -r1.27 -r1.28 --- MultiThreadedHttpConnectionManager.java 26 Oct 2003 09:49:16 - 1.27 +++ MultiThreadedHttpConnectionManager.java 19 Nov 2003 00:43:12 - 1.28 @@ -73,7 +73,6 @@ import java.net.SocketException; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.Map; @@ -105,6 +104,79 @@ /** The default maximum number of connections allowed overall */ public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20; +/** + * A mapping from Reference to ConnectionSource. Used to reclaim resources when connections + * are lost to the garbage collector. + */ +public static final Map REFERENCE_TO_CONNECTION_SOURCE; + +/** + * The reference queue used to track when HttpConnections are lost to the + * garbage collector + */ +private static final ReferenceQueue REFERENCE_QUEUE; + +/** + * The thread responsible for handling lost connections. + */ +private static ReferenceQueueThread REFERENCE_QUEUE_THREAD; + + +static { +REFERENCE_TO_CONNECTION_SOURCE = Collections.synchronizedMap(new HashMap()); +REFERENCE_QUEUE = new ReferenceQueue(); +REFERENCE_QUEUE_THREAD = new ReferenceQueueThread(); +REFERENCE_QUEUE_THREAD.start(); +} + +/** + * Stores the reference to the given connection along with the hostConfig and connection pool. + * These values will be used to reclaim resources if the connection is lost to the garbage + * collector. This method should be called before a connection is released from the connection + * manager. + * + * pA static reference to the connection manager will also be stored. To ensure that + * the connection manager can be GCed [EMAIL PROTECTED] #removeReferenceToConnection(HttpConnection)} + * should be called for all connections that the connection manager is storing a reference + * to./p + * + * @param connection the connection to create a reference for + * @param hostConfiguration the connection's host config + * @param connectionPool the connection pool that created the connection + * + * @see #removeReferenceToConnection(HttpConnection) + */ +private static void storeReferenceToConnection( +HttpConnectionWithReference connection, +HostConfiguration hostConfiguration, +ConnectionPool connectionPool +) { + +ConnectionSource source = new ConnectionSource(); +source.connectionPool = connectionPool; +source.hostConfiguration = hostConfiguration; + +REFERENCE_TO_CONNECTION_SOURCE.put( +connection.reference, +source +); +} + +/** + * Removes the reference being stored for the given connection. This method should be called + * when the connection manager again has a direct reference to the connection. + * + * @param connection the connection to remove the reference for + * + * @see #storeReferenceToConnection(HttpConnection, HostConfiguration, ConnectionPool) + */ +private static void removeReferenceToConnection(HttpConnectionWithReference connection) { + +synchronized (REFERENCE_TO_CONNECTION_SOURCE) { +REFERENCE_TO_CONNECTION_SOURCE.remove(connection.reference); +} +} + // - Instance Variables /** * Collection of parameters associated with this connection manager. @@ -114,26 +186,11 @@ /** Connection Pool */ private ConnectionPool connectionPool; -/** mapping from reference to hostConfiguration */ -private Map referenceToHostConfig; - -/** - * the reference queue
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
jsdever 2003/02/19 17:03:57 Modified:httpclient/src/java/org/apache/commons/httpclient MultiThreadedHttpConnectionManager.java httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java Log: Fix for the Request/Response race condition bug. Bugzilla: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13463 Contributed by: Micheal Becke This fix was taken from the bug as attachement 4908. Mike became a committer today! Revision ChangesPath 1.9 +396 -11 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java Index: MultiThreadedHttpConnectionManager.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- MultiThreadedHttpConnectionManager.java 30 Jan 2003 05:01:54 - 1.8 +++ MultiThreadedHttpConnectionManager.java 20 Feb 2003 01:03:56 - 1.9 @@ -63,14 +63,19 @@ package org.apache.commons.httpclient; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; +import java.net.SocketException; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; +import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -95,13 +100,13 @@ * HostConnectionPool}s */ private final Map mapHosts = new HashMap(); - + /** Maximum number of connections allowed */ private int maxConnections = 2; // Per RFC 2616 sec 8.1.4 /** mapping from reference to hostConfiguration */ private final Map referenceToHostConfig; - + /** * the reference queue used to track when HttpConnections are lost to the * garbage collector @@ -165,7 +170,7 @@ */ public HttpConnection getConnection(HostConfiguration hostConfiguration, long timeout) throws HttpException { - + LOG.trace(enter HttpConnectionManager.getConnection(HostConfiguration, long)); if (hostConfiguration == null) { @@ -184,7 +189,9 @@ hostConfiguration, timeout ); -return conn; +// wrap the connection in an adapter so we can ensure it is used +// only once +return new HttpConnectionAdapter(conn); } /** @@ -305,9 +312,17 @@ public void releaseConnection(HttpConnection conn) { LOG.trace(enter HttpConnectionManager.releaseConnection(HttpConnection)); +if (conn instanceof HttpConnectionAdapter) { +// connections given out are wrapped in an HttpConnectionAdapter +conn = ((HttpConnectionAdapter) conn).getWrappedConnection(); +} else { +// this is okay, when an HttpConnectionAdapter is released +// is releases the real connection +} + // make sure that the response has been read. SimpleHttpConnectionManager.finishLastResponse(conn); - + HostConfiguration connectionConfiguration = new HostConfiguration(); connectionConfiguration.setHost(conn.getHost(), conn.getPort(), conn.getProtocol()); @@ -320,8 +335,7 @@ + connectionConfiguration); } -final HostConnectionPool listConnections -= getConnectionPool(connectionConfiguration); +final HostConnectionPool listConnections = getConnectionPool(connectionConfiguration); synchronized (listConnections) { // Put the connect back in the available list and notify a waiter listConnections.freeConnections.addFirst(conn); @@ -342,7 +356,7 @@ private class HostConnectionPool { /** The list of free connections */ private LinkedList freeConnections = new LinkedList(); - + /** The number of created connections */ private int numConnections = 0; } @@ -460,4 +474,375 @@ } } +/** + * An HttpConnection wrapper that ensures a connection cannot be used + * once released. + */ +private static class HttpConnectionAdapter extends HttpConnection { + +// the wrapped connection +private HttpConnection wrappedConnection; + +/** + * Creates a new HttpConnectionAdapter. + * @param connection the connection to
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java
oglueck 2003/01/21 01:47:26 Modified:httpclient/src/java/org/apache/commons/httpclient HostConfiguration.java HttpConnection.java HttpConnectionManager.java MultiThreadedHttpConnectionManager.java SimpleHttpConnectionManager.java httpclient/src/java/org/apache/commons/httpclient/protocol Protocol.java httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java Log: connection pool now includes protocol Contributed by: Oleg Kalnichevski and Michael Becke Revision ChangesPath 1.6 +48 -13 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HostConfiguration.java Index: HostConfiguration.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HostConfiguration.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- HostConfiguration.java16 Jan 2003 13:28:39 - 1.5 +++ HostConfiguration.java21 Jan 2003 09:47:26 - 1.6 @@ -300,24 +300,59 @@ /** * @see java.lang.Object#equals(java.lang.Object) */ -public boolean equals(Object o) { +public synchronized boolean equals(Object o) { if ( o instanceof HostConfiguration ) { +// shortcut if we're comparing with ourselves +if ( o == this ) return true; + HostConfiguration config = (HostConfiguration)o; -return ( -proxyPort == config.getProxyPort() - ( -proxyHost == null -? config.getProxyHost() == null -: proxyHost.equals( config.getProxyHost() ) -) - getHostURL().equals( config.getHostURL() ) -); +if ( hostSet ) { +if ( +!host.equalsIgnoreCase( config.getHost() ) +|| port != config.getPort() +|| !protocol.equals( config.getProtocol() ) +) { +// either host, port or protocol don't match +return false; +} +} else if ( config.isHostSet() ) { +return false; +} +if ( proxyHost != null ) { +if ( +!proxyHost.equalsIgnoreCase( config.getProxyHost() ) +|| proxyPort != config.getProxyPort() +) { +// either proxyHost or proxyPort don't match +return false; +} +} else if ( config.getProxyHost() != null ) { +return false; +} + +// everything matches +return true; } else { return false; +} + +} + +/** + * @see java.lang.Object#hashCode() + */ +public int hashCode() { + +if ( host != null ) { +return host.hashCode(); +} else if ( proxyHost != null ) { +return proxyHost.hashCode(); +} else { +return super.hashCode(); } } 1.33 +19 -4 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java Index: HttpConnection.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- HttpConnection.java 19 Jan 2003 15:05:15 - 1.32 +++ HttpConnection.java 21 Jan 2003 09:47:26 - 1.33 @@ -156,6 +156,21 @@ ); } +/** + * Creates a new HttpConnection. + * + * @param hostConfiguration the host/proxy/protocol to use + */ +public HttpConnection( HostConfiguration hostConfiguration ) { +this( +hostConfiguration.getProxyHost(), +hostConfiguration.getProxyPort(), +hostConfiguration.getHost(), +hostConfiguration.getPort(), +hostConfiguration.getProtocol() +); +} + public HttpConnection( String proxyHost, int proxyPort, 1.13 +5 -7 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnectionManager.java Index: HttpConnectionManager.java
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java TestURIUtil.java TestNoHost.java
marcsaeg02/04/12 14:17:06 Modified:httpclient/src/test/org/apache/commons/httpclient TestNoHost.java Added: httpclient/src/test/org/apache/commons/httpclient TestHttpConnectionManager.java TestURIUtil.java Log: Added new test suites for HttpConnectionManager and URIUtil. Revision ChangesPath 1.6 +6 -4 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java Index: TestNoHost.java === RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- TestNoHost.java 28 Mar 2002 03:59:06 - 1.5 +++ TestNoHost.java 12 Apr 2002 21:17:06 - 1.6 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java,v 1.5 2002/03/28 03:59:06 marcsaeg Exp $ - * $Revision: 1.5 $ - * $Date: 2002/03/28 03:59:06 $ + * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java,v 1.6 2002/04/12 21:17:06 marcsaeg Exp $ + * $Revision: 1.6 $ + * $Date: 2002/04/12 21:17:06 $ * * * The Apache Software License, Version 1.1 @@ -71,7 +71,7 @@ * (True unit tests, by some definitions.) * * @author Rodney Waldhoff - * @version $Id: TestNoHost.java,v 1.5 2002/03/28 03:59:06 marcsaeg Exp $ + * @version $Id: TestNoHost.java,v 1.6 2002/04/12 21:17:06 marcsaeg Exp $ */ public class TestNoHost extends TestCase { @@ -92,6 +92,8 @@ suite.addTest(TestAuthenticator.suite()); suite.addTest(TestHttpClientNoHost.suite()); suite.addTest(TestHttpUrlMethod.suite()); +suite.addTest(TestHttpConnectionManager.suite()); +suite.addTest(TestURIUtil.suite()); return suite; } 1.1 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java Index: TestHttpConnectionManager.java === /* * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v 1.1 2002/04/12 21:17:06 marcsaeg Exp $ * $Revision: 1.1 $ * $Date: 2002/04/12 21:17:06 $ * * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *notice, this list of conditions and the following disclaimer in *the documentation and/or other materials provided with the *distribution. * * 3. The end-user documentation included with the redistribution, if *any, must include the following acknowlegement: * This product includes software developed by the *Apache Software Foundation (http://www.apache.org/). *Alternately, this acknowlegement may appear in the software itself, *if and wherever such third-party acknowlegements normally appear. * * 4. The names The Jakarta Project, Tomcat, and Apache Software *Foundation must not be used to endorse or promote products derived *from this software without prior written permission. For written *permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called Apache *nor may Apache appear in their names without prior written *permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *