Index: java/org/apache/commons/httpclient/HostConfiguration.java
===================================================================
RCS file: java/org/apache/commons/httpclient/HostConfiguration.java
diff -N java/org/apache/commons/httpclient/HostConfiguration.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/HostConfiguration.java 20 Nov 2002 14:42:58 -0000
@@ -0,0 +1,176 @@
+package org.apache.commons.httpclient;
+
+import java.security.InvalidParameterException;
+
+/**
+ */
+public class HostConfiguration implements Cloneable{
+
+ private String host;
+ private int port;
+ private String protocol;
+ private boolean hostSet;
+
+ private String proxyHost;
+ private int proxyPort;
+ private boolean proxySet;
+
+ /**
+ * Constructor for HostConfiguration.
+ */
+ public HostConfiguration() {
+
+ this.host = null;
+ this.port = -1;
+ this.protocol = null;
+ this.hostSet = false;
+
+ this.proxyHost = null;
+ this.proxyPort = -1;
+ this.proxySet = false;
+
+ }
+
+ /**
+ * Copy constructor for HostConfiguration
+ *
+ * @param hostConfiguration the hostConfiguration to copy
+ */
+ public HostConfiguration( HostConfiguration hostConfiguration ) {
+
+ // wrap all of the assignments in a synchronized block to avoid
+ // having to negotiate the monitor for each method call
+ synchronized( hostConfiguration ) {
+ this.host = hostConfiguration.getHost();
+ this.port = hostConfiguration.getPort();
+ this.protocol = hostConfiguration.getProtocol();
+ this.hostSet = hostConfiguration.isHostSet();
+
+ this.proxyHost = hostConfiguration.getProxyHost();
+ this.proxyPort = hostConfiguration.getProxyPort();
+ this.proxySet = hostConfiguration.isProxySet();
+ }
+
+ }
+
+ public synchronized boolean isHostSet() {
+ return hostSet;
+ }
+
+ public synchronized void setHost(
+ String host,
+ int port,
+ String protocol
+ ) {
+ if ( host == null ) {
+ throw new InvalidParameterException( "host must not be null" );
+ }
+ if ( protocol == null ) {
+ throw new InvalidParameterException( "protocol must not be null" );
+ }
+
+ this.host = host;
+ this.port = port;
+ this.protocol = protocol;
+
+ this.hostSet = true;
+
+ }
+
+ public synchronized String getHostURL() {
+
+ if ( !hostSet ) {
+ throw new IllegalStateException(
+ "a default host must be set to create a host URL"
+ );
+ }
+
+ String url = protocol + "://" + host;
+
+ if ( port != -1 ) {
+ url += ":" + port;
+ }
+
+ return url;
+
+ }
+
+ /**
+ * Returns the host.
+ * @return String
+ */
+ public synchronized String getHost() {
+ return host;
+ }
+
+ /**
+ * Returns the port.
+ * @return int
+ */
+ public synchronized int getPort() {
+ return port;
+ }
+
+ /**
+ * Returns the protocol.
+ * @return String
+ */
+ public synchronized String getProtocol() {
+ return protocol;
+ }
+
+ public synchronized boolean isProxySet() {
+ return proxySet;
+ }
+
+ public synchronized void setProxy( String proxyHost, int proxyPort ) {
+
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+
+ this.proxySet = true;
+
+ }
+
+ /**
+ * Returns the proxyHost.
+ * @return String
+ */
+ public synchronized String getProxyHost() {
+ return proxyHost;
+ }
+
+ /**
+ * Returns the proxyPort.
+ * @return int
+ */
+ public synchronized int getProxyPort() {
+ return proxyPort;
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+
+ if ( o instanceof HostConfiguration ) {
+
+ HostConfiguration config = (HostConfiguration)o;
+
+ return (
+ proxyPort == config.getProxyPort()
+ && (
+ proxyHost == null
+ ? config.getProxyHost() == null
+ : proxyHost.equals( config.getProxyHost() )
+ )
+ && getHostURL().equals( config.getHostURL() )
+ );
+
+ } else {
+ return false;
+ }
+
+ }
+
+}
Index: java/org/apache/commons/httpclient/HttpClient.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpClient.java,v
retrieving revision 1.60
diff -u -r1.60 HttpClient.java
--- java/org/apache/commons/httpclient/HttpClient.java 12 Nov 2002 09:58:22 -0000 1.60
+++ java/org/apache/commons/httpclient/HttpClient.java 20 Nov 2002 14:43:09 -0000
@@ -67,6 +67,8 @@
import java.io.IOException;
import java.net.URL;
+import java.security.InvalidParameterException;
+
import javax.net.ssl.SSLSocketFactory;
@@ -80,7 +82,9 @@
* @author Rodney Waldhoff
* @author Sean C. Sullivan
* @author dIon Gillard
- * @author Ortwin Glück
+ * @author Ortwin Gl?ck
+ * @author Michael Becke
+ *
* @version $Revision: 1.60 $ $Date: 2002/11/12 09:58:22 $
*/
@@ -98,14 +102,26 @@
* Constructor.
*/
public HttpClient() {
+ this( new SimpleHttpConnectionManager() );
}
- // ----------------------------------------------------- Instance Variables
-
/**
- * My {@link HttpConnection connection}.
+ * Constructor.
*/
- private HttpConnection connection = null;
+ public HttpClient( HttpConnectionManager httpConnectionManager ) {
+
+ if ( httpConnectionManager == null ) {
+ throw new InvalidParameterException("httpConnectionManager cannot be null");
+ }
+
+ this.state = new HttpState();
+ this.state.setHttpConnectionManager( httpConnectionManager );
+
+ this.hostConfiguration = new HostConfiguration();
+
+ }
+
+ // ----------------------------------------------------- Instance Variables
/**
* My {@link HttpState state}.
@@ -114,10 +130,17 @@
private SSLSocketFactory sslSocketFactory = null;
+ /** the timout when waiting for a connection from the connectionManager */
+ private long httpConnectionTimeout = 0;
+
private int timeoutInMilliseconds = 0;
private int connectionTimeout = 0;
+ private HostConfiguration hostConfiguration;
+
+ private boolean strictMode = false;
+
// ------------------------------------------------------------- Properties
/**
@@ -126,10 +149,7 @@
* @see #setState(HttpState)
* @return the shared client state
*/
- public HttpState getState() {
- if (null == state) {
- state = new HttpState();
- }
+ public synchronized HttpState getState() {
return state;
}
@@ -139,16 +159,38 @@
* @see #getState()
* @param state the new state for the client
*/
- public void setState(HttpState state) {
+ public synchronized void setState(HttpState state) {
this.state = state;
}
/**
+ *
+ * @param strictMode true if strict mode should be used
+ *
+ * @see #isStrictMode()
+ *
+ */
+ public synchronized void setStrictMode(boolean strictMode) {
+ this.strictMode = strictMode;
+ }
+
+ /**
+ *
+ * @return true if strict mode being used
+ *
+ * @see #setStrictMode(boolean)
+ *
+ */
+ public synchronized boolean isStrictMode() {
+ return strictMode;
+ }
+
+ /**
* Specifies an alternative factory for SSL sockets.
* @see HttpConnection#setSSLSocketFactory(SSLSocketFactory) HttpConnection.setSSLSocketFactory
* @param sslSocketFactory a living instance of the alternative SSLSocketFactory
*/
- public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
+ public synchronized void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
}
@@ -160,34 +202,44 @@
* @param newTimeoutInMilliseconds Timeout in milliseconds
*
*/
- public void setTimeout(int newTimeoutInMilliseconds) {
+ public synchronized void setTimeout(int newTimeoutInMilliseconds) {
this.timeoutInMilliseconds = newTimeoutInMilliseconds;
}
/**
+ * Sets the timeout used when retrieving an HttpConnection from the
+ * HttpConnectionManager.
+ *
+ * @param timeout the timeout in milliseconds
+ *
+ * @see HttpConnectionManager#getConnection(String, long)
+ */
+ public synchronized void setHttpConnectionFactoryTimeout( long timeout ) {
+ this.httpConnectionTimeout = timeout;
+ }
+
+ /**
* Sets the timeout until a connection is etablished. A value of 0 means
* the timeout is not used. The default value is 0.
* @see HttpConnection#setConnectionTimeout(int)
* @param newTimeoutInMilliseconds Timeout in milliseconds.
*/
- public void setConnectionTimeout(int newTimeoutInMilliseconds) {
+ public synchronized void setConnectionTimeout(int newTimeoutInMilliseconds) {
this.connectionTimeout = newTimeoutInMilliseconds;
}
// --------------------------------------------------------- Public Methods
/**
- * Start an HTTP session with the server at the given
- * host and port.
+ * @deprecated use hostConfiguration
+ *
+ * Sets the host, port and protocol(http) to be used when executing a
+ * method.
+ *
* @param host the host to connect to
* @param port the port to connect to
*
- * @see #startSession(String, int, boolean)
- * @see #startSession(String, int, Credentials)
- * @see #startSession(String, int, Credentials, boolean)
- * @see #startSession(String, int, String, int)
- * @see #endSession()
- *
+ * @see #getHostConfiguration()
*/
public void startSession(String host, int port) {
log.trace("enter HttpClient.startSession(String, int)");
@@ -195,19 +247,16 @@
}
/**
- * Start an HTTP or HTTPS session with the server at the given
- * host and port.
+ * @deprecated use hostConfiguration
+ *
+ * Sets the host, port and protocol to be used when executing a method.
+ *
* @param host the host to connect to
* @param port the port to connect to
* @param https when true, create an HTTPS session
*
- * @see #startSession(String, int)
- * @see #startSession(String, int, Credentials)
- * @see #startSession(String, int, Credentials, boolean)
- * @see #startSession(String, int, String, int)
- * @see #endSession()
- *
- */
+ * @see #getHostConfiguration()
+ */
public void startSession(String host, int port, boolean https) {
log.trace("enter HttpClient.startSession(String, int, boolean)");
@@ -215,48 +264,47 @@
log.debug("HttpClient.startSession(String,int,boolean): Host:"
+ host + " Port:" + port + " HTTPS:" + https);
}
- connection = new HttpConnection(host, port, https);
+
+ this.hostConfiguration.setHost(
+ host,
+ port,
+ https ? "https" : "http"
+ );
}
/**
- * Start an HTTP session with the server at the given
- * host and port using the given default
- * default credentials.
+ * @deprecated use hostConfiguration and httpState
+ *
+ * Sets the host, port, protocol(http) and credentials to be used when
+ * executing a method.
*
* @param host the host to connect to
* @param port the port to connect to
* @param creds the default credentials to use
*
- * @see #startSession(String, int, boolean)
- * @see #startSession(String, int)
+ * @see #getHostConfiguration()
+ * @see #getState()
* @see #startSession(String, int, Credentials, boolean)
- * @see #startSession(String, int, String, int)
- * @see #endSession()
- *
*/
public void startSession(String host, int port, Credentials creds) {
log.trace("enter HttpClient.startSession(String, int, Credentials)");
startSession(host, port, creds, false);
}
-
/**
- * Start an HTTP or HTTPS session with the server at the given
- * host and port using the given default
- * default credentials.
+ * @deprecated use hostConfiguration and httpState
+ *
+ * Sets the host, port, protocol and credentials to be used when executing a
+ * method.
*
* @param host the host to connect to
* @param port the port to connect to
* @param creds the default credentials to use
* @param https when true, create an HTTPS session
*
- * @see #startSession(String, int, boolean)
- * @see #startSession(String, int)
- * @see #startSession(String, int, Credentials)
- * @see #startSession(String, int, String, int)
- * @see #endSession()
- *
- */
+ * @see #getHostConfiguration()
+ * @see #getState()
+ */
public void startSession(String host, int port, Credentials creds, boolean https) {
log.trace("enter HttpClient.startSession(String, int, Credentials, boolean)");
@@ -268,22 +316,30 @@
+ " HTTPS:" + https);
}
getState().setCredentials(null, creds);
- connection = new HttpConnection(host, port, https);
+ this.hostConfiguration.setHost(
+ host,
+ port,
+ https ? "https" : "http"
+ );
}
-
/**
- * Start an HTTP or HTTPS session with the server specified by the scheme,
- * userinfo, host and port of the given uri.
+ * @deprecated use hostConfiguration and httpState
+ *
+ * Sets the host, port, protocol and credentials to be used when executing a
+ * method using the server specified by the scheme, userinfo, host and port
+ * of the given uri.
*
* Note that the path component is not utilized. *
* @param uri an HttpURL or HttpsURL instance; the
* {@link URI URI} from which the scheme, userinfo, host and port of the
* session are determined
+ *
* @exception IllegalStateException not enough information to process
- * @see #startSession
- * @see #endSession
+ *
+ * @see #getHostConfiguration()
+ * @see #getState()
*/
public void startSession(URI uri) throws URIException {
log.trace("enter HttpClient.startSession(URI)");
@@ -315,29 +371,27 @@
throw new IllegalStateException
("HttpURL or HttpsURL instance required");
}
- connection = new HttpConnection(host, port, secure);
+ this.hostConfiguration.setHost(
+ host,
+ port,
+ secure ? "https" : "http"
+ );
}
-
/**
- * Start an HTTP or HTTPS session with the server specified
- * by the protocol, host and port of the given
- * url.
+ * @deprecated use hostConfiguration
+ *
+ * Sets the host, port and protocol to be used when executing a method.
*
* Note that everything but the protocol, host and port of the * given url is ignored. *
- * @param url the {@link URL URL} from which the protocol, host, - * and port of the session are determined - * - * @see #startSession(String, int, boolean) - * @see #startSession(String, int) - * @see #startSession(String, int, Credentials) - * @see #startSession(String, int, Credentials, boolean) - * @see #startSession(java.net.URL, Credentials) - * @see #startSession(String, int, String, int) - * @see #endSession() + * @param url the {@link URL URL} from which the protocol, host, and port of + * the session are determined + * + * @exception IllegalArgumentException if the protocol is not http or https * + * @see #getHostConfiguration() */ public void startSession(URL url) { log.trace("enter HttpClient.startSession(String, int, Credentials, boolean)"); @@ -355,25 +409,22 @@ } /** - * Start an HTTP or HTTPS session with the server specified - * by the protocol, host and port of the given - * url, using the given credentials by default. + * @deprecated use hostConfiguration and httpState + * + * Sets the host, port, protocol and credentials to be used when executing a + * method. ** Note that everything but the protocol, host and port of the * given url is ignored. *
+ * @param url the {@link URL URL} from which the protocol, host, and port of + * the session are determined * @param creds the default credentials to use - * @param url the {@link URL URL} from which the protocol, host, - * and port of the session are determined - * - * @see #startSession(java.net.URL) - * @see #startSession(String, int, boolean) - * @see #startSession(String, int) - * @see #startSession(String, int, Credentials) - * @see #startSession(String, int, Credentials, boolean) - * @see #startSession(String, int, String, int) - * @see #endSession() + * + * @exception IllegalArgumentException if the protocol is not http or https * + * @see #getHostConfiguration() + * @see #getState() */ public void startSession(URL url, Credentials creds) { log.trace("enter HttpClient.startSession(URL, Credentials)"); @@ -382,100 +433,150 @@ } /** - * Start an HTTP session with the server specified - * by the given host and port - * via the given proxyhost and proxyport. + * @deprecated use hostConfiguration + * + * Sets the host, port, protocol(http) and proxy to be used when executing a + * method. + * * @param host the host to connect to * @param port the port to connect to * @param proxyhost the proxy host to connect via * @param proxyport the proxy port to connect via * - * @see #endSession() - * + * @see #getHostConfiguration() */ public void startSession(String host, int port, String proxyhost, int proxyport) { log.trace("enter HttpClient.startSession(String, int, String, int)"); startSession(host, port, proxyhost, proxyport, false); } - /** - * Start an HTTP session with the server specified - * by the given host and port - * via the given proxyhost and proxyport. - * + * @deprecated use hostConfiguration + * + * Sets the host, port, protocol and proxy to be used when executing a + * method. + * * @param host the host to connect to * @param port the port to connect to * @param proxyhost the proxy host to connect via * @param proxyport the proxy port to connect via * @param secure whether or not to connect using HTTPS - * - * @see #endSession() - * + * + * @see #getHostConfiguration() */ public void startSession(String host, int port, String proxyhost, int proxyport, boolean secure) { log.trace("enter HttpClient.startSession(String, int, String, int, boolean)"); - connection = new HttpConnection(proxyhost, proxyport, host, port, secure); + this.hostConfiguration.setHost( + host, + port, + secure ? "https" : "http" + ); + this.hostConfiguration.setProxy( proxyhost, proxyport ); } /** - * Execute the given {@link HttpMethod} using my current - * {@link HttpConnection connection} and {@link HttpState}. + * Executes the given method. * - * @param method the {@link HttpMethod} to execute. This parameter must be non-null. + * @param method the {@link HttpMethod} to execute. * @return the method's response code * * @throws java.io.IOException if an I/O error occurs * @throws HttpException if a protocol exception occurs - * @throws IllegalStateException if the session has not been started - * */ - public synchronized int executeMethod(HttpMethod method) - throws IOException, HttpException, IllegalStateException { + public int executeMethod(HttpMethod method) + throws IOException, HttpException { + log.trace("enter HttpClient.executeMethod(HttpMethod)"); + return executeMethod(getHostConfiguration(), method); + + } + + /** + * Executes the given method. + * + * @param method the {@link HttpMethod} to execute. + * @return the method's response code + * + * @throws java.io.IOException if an I/O error occurs + * @throws HttpException if a protocol exception occurs + */ + public int executeMethod(HostConfiguration hostConfiguration, HttpMethod method) + throws IOException, HttpException { + log.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod)"); if (null == method) { throw new NullPointerException("HttpMethod parameter"); } - if (null == connection) { - throw new IllegalStateException( - "The startSession method must be called before executeMethod"); + int soTimeout = 0; + boolean strictMode = false; + SSLSocketFactory socketFactory = null; + int connectionTimeout = 0; + long httpConnectionTimeout = 0; + HttpState state = null; + HostConfiguration defaultHostConfiguration = null; + + /* access all synchronized data in a single block, this will keeps us + * from accessing data asynchronously as well having to regain the lock + * for each item. + */ + synchronized ( this ) { + soTimeout = this.timeoutInMilliseconds; + strictMode = this.strictMode; + socketFactory = this.sslSocketFactory; + connectionTimeout = this.connectionTimeout; + httpConnectionTimeout = this.httpConnectionTimeout; + state = getState(); + defaultHostConfiguration = getHostConfiguration(); + } + + HostConfiguration methodConfiguration = new HostConfiguration(hostConfiguration); + + if ( hostConfiguration != defaultHostConfiguration ) { + // we may need to appy some defaults + if ( !methodConfiguration.isHostSet() ) { + methodConfiguration.setHost( + defaultHostConfiguration.getHost(), + defaultHostConfiguration.getPort(), + defaultHostConfiguration.getProtocol() + ); + } + if ( !methodConfiguration.isProxySet() && defaultHostConfiguration.isProxySet() ) { + methodConfiguration.setProxy( + defaultHostConfiguration.getProxyHost(), + defaultHostConfiguration.getProxyPort() + ); + } } + // FIXME: need to pass proxy config somehow + HttpConnection connection = state.getHttpConnectionManager().getConnection( + methodConfiguration, + httpConnectionTimeout + ); + + method.setStrictMode(strictMode); + if (!connection.isOpen()) { - connection.setSSLSocketFactory(sslSocketFactory); - connection.setSoTimeout(timeoutInMilliseconds); + connection.setSSLSocketFactory(socketFactory); + connection.setSoTimeout(soTimeout); connection.setConnectionTimeout(connectionTimeout); connection.open(); if (connection.isProxied() && connection.isSecure()) { method = new ConnectMethod(method); } } - return method.execute(getState(), connection); + + return method.execute(state, connection); } /** - * End the current session, closing my the associated - * {@link HttpConnection connection} if any. - * - * @see #startSession(String, int) - * @see #startSession(String, int, boolean) - * @see #startSession(String, int, Credentials) - * @see #startSession(String, int, Credentials, boolean) - * @see #startSession(java.net.URL) - * @see #startSession(java.net.URL, Credentials) - * @see #startSession(String, int, String, int) - * - * @throws java.io.IOException when i/o errors occur closing the connection - * + * @deprecated this method has no effect. HttpMethod.releaseConnection() + * should be used to release resources after a HttpMethod has been executed. + * + * @see HttpMethod#releaseConnection() */ public void endSession() throws IOException { - log.trace("enter HttpClient.endSession()"); - if (null != connection) { - connection.close(); - connection = null; - } } /** @@ -485,7 +586,7 @@ * the session has not been started via startSession. */ public String getHost() { - return connection != null ? connection.getHost() : null; + return hostConfiguration.getHost(); } /** @@ -495,6 +596,23 @@ * has not been started via startSession(). */ public int getPort() { - return connection != null ? connection.getPort() : -1; + return hostConfiguration.getPort(); } + + /** + * Returns the hostConfiguration. + * @return HostConfiguration + */ + public synchronized HostConfiguration getHostConfiguration() { + return hostConfiguration; + } + + /** + * Sets the hostConfiguration. + * @param hostConfiguration The hostConfiguration to set + */ + public synchronized void setHostConfiguration(HostConfiguration hostConfiguration) { + this.hostConfiguration = hostConfiguration; + } + } Index: java/org/apache/commons/httpclient/HttpConnection.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v retrieving revision 1.24 diff -u -r1.24 HttpConnection.java --- java/org/apache/commons/httpclient/HttpConnection.java 12 Nov 2002 09:58:22 -0000 1.24 +++ java/org/apache/commons/httpclient/HttpConnection.java 20 Nov 2002 14:43:00 -0000 @@ -83,7 +83,7 @@ * * @author Rod Waldhoff * @author Sean C. Sullivan - * @author Ortwin Glück + * @author Ortwin Gl?ck * @version $Revision: 1.24 $ $Date: 2002/11/12 09:58:22 $ */ public class HttpConnection { @@ -744,6 +744,29 @@ closeSocketAndStreams(); } + /** + * Returns the httpConnectionManager. + * @return HttpConnectionManager + */ + public HttpConnectionManager getHttpConnectionManager() { + return httpConnectionManager; + } + + /** + * Sets the httpConnectionManager. + * @param httpConnectionManager The httpConnectionManager to set + */ + public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) { + this.httpConnectionManager = httpConnectionManager; + } + + public void releaseConnection() { + log.trace("enter HttpConnection.releaseConnection()"); + if ( httpConnectionManager != null ) { + httpConnectionManager.releaseConnection( this ); + } + } + // ------------------------------------------------------ Protected Methods @@ -847,6 +870,7 @@ return sslSocketFactory.createSocket(host, port); } } + // ------------------------------------------------------------- Attributes /** Log object for this class. */ @@ -883,4 +907,7 @@ private boolean _tunnelEstablished = false; /** Timeout until connection established (Socket created). 0 means no timeout. */ private int connect_timeout = 0; + /** the connection manager that created this connection or null */ + private HttpConnectionManager httpConnectionManager; + } Index: java/org/apache/commons/httpclient/HttpConnectionManager.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnectionManager.java,v retrieving revision 1.11 diff -u -r1.11 HttpConnectionManager.java --- java/org/apache/commons/httpclient/HttpConnectionManager.java 29 Sep 2002 21:59:47 -0000 1.11 +++ java/org/apache/commons/httpclient/HttpConnectionManager.java 20 Nov 2002 14:43:02 -0000 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnectionManager.java,v 1.11 2002/09/29 21:59:47 sullis Exp $ - * $Revision: 1.11 $ - * $Date: 2002/09/29 21:59:47 $ + * $Header: $ + * $Revision: $ + * $Date: $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -28,7 +28,7 @@ * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * - * 4. The names "The Jakarta Project", "HttpClient", and "Apache Software + * 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 apache@apache.org. @@ -62,366 +62,57 @@ package org.apache.commons.httpclient; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.LinkedList; /** - * Manages a set of HttpConnections for various host:ports. This class is - * used by HttpMultiClient. - * - * @author Marc A. Saegesser */ -public class HttpConnectionManager -{ - // -------------------------------------------------------- Class Variables - /** Log object for this class. */ - private static final Log log = LogFactory.getLog(HttpConnectionManager.class); - - // ----------------------------------------------------- Instance Variables - private Map mapHosts = new HashMap(); - private Map mapNumConnections = new HashMap(); - private int maxConnections = 2; // Per RFC 2616 sec 8.1.4 - private String proxyHost = null; - private int proxyPort = -1; - - /** - * No-args constructor - */ - public HttpConnectionManager() { - } - - /** - * Set the proxy host to use for all connections. - * - * @param proxyHost - the proxy host name - */ - public void setProxyHost(String proxyHost) { - this.proxyHost = proxyHost; - } - - /** - * Get the proxy host. - * - * @return the proxy host name - */ - public String getProxyHost() { - return proxyHost; - } - - /** - * Set the proxy port to use for all connections. - * - * @param proxyPort - the proxy port number - */ - public void setProxyPort(int proxyPort) { - this.proxyPort = proxyPort; - } - - /** - * Get the proxy port number. - * - * @return the proxy port number - */ - public int getProxyPort() { - return proxyPort; - } - - /** - * Set the maximum number of connections allowed for a given host:port. - * Per RFC 2616 section 8.1.4, this value defaults to 2. - * - * @param maxConnections - number of connections allowed for each host:port - */ - public void setMaxConnectionsPerHost(int maxConnections) { - this.maxConnections = maxConnections; - } - - /** - * Get the maximum number of connections allowed for a given host:port. - * - * @return The maximum number of connections allowed for a given host:port. - */ - public int getMaxConnectionsPerHost() { - return maxConnections; - } - - /** - * Get an HttpConnection for a given URL. The URL must be fully - * specified (i.e. contain a protocol and a host (and optional port number). - * If the maximum number of connections for the host has been reached, this - * method will block forever until a connection becomes available. - * - * @param sURL - a fully specified URL. - * @return an HttpConnection for the given host:port - * @exception java.net.MalformedURLException - * @exception org.apache.commons.httpclient.HttpException - - * If no connection becomes available before the timeout expires - */ - public HttpConnection getConnection(String sURL) - throws HttpException, MalformedURLException { - return getConnection(sURL, 0); - } +public interface HttpConnectionManager { /** - * Return the port provided if not -1 (default), return 443 if the - * protocol is HTTPS, otherwise 80. + * Gets an HttpConnection for a given host configuration. If a connection is + * not available this method will block until one is. * - * This functionality is a URLUtil and may be better off in URIUtils + * The connection manager should be registered with any HttpConnection that + * is created. * - * @param protocol the protocol to use to get the port for, e.g. http or - * https - * @param port the port provided with the url (could be -1) - * @return the port for the specified port and protocol. + * @param hostConfiguration the host configuration to use to configure the + * connection + * + * @return an HttpConnection for the given configuration + * + * @see HttpConnection#setHttpConnectionManager(HttpConnectionManager) */ - private static int getPort(String protocol, int port) { - log.trace("HttpConnectionManager.getPort(String, port)"); + public HttpConnection getConnection(HostConfiguration hostConfiguration) + throws MalformedURLException; - // default to provided port - int portForProtocol = port; - if (portForProtocol == -1) { - if (protocol.equalsIgnoreCase("HTTPS")) { - portForProtocol = 443; - } else { - portForProtocol = 80; - } - } - return portForProtocol; - } - /** - * Get an HttpConnection for a given URL. The URL must be fully - * specified (i.e. contain a protocol and a host (and optional port number). - * If the maximum number of connections for the host has been reached, this - * method will block fortimeout milliseconds or until a
- * connection becomes available. If no connection becomes available before
- * the timeout expires an HttpException exception will be thrown.
+ * Gets an HttpConnection for a given host configuration. If a connection is
+ * not available, this method will block for at most the specified number of
+ * milliseconds or until a connection becomes available.
*
- * @param sURL - a fully specified URL.
- * @param timeout - the time (in milliseconds) to wait for a connection
- * to become available
- * @return an HttpConnection for the given host:port
- * @exception java.net.MalformedURLException
- * @exception org.apache.commons.httpclient.HttpException -
- * If no connection becomes available before the timeout expires
- */
- public HttpConnection getConnection(String sURL, long timeout)
- throws HttpException, MalformedURLException {
- log.trace("enter HttpConnectionManager.getConnection(String, long)");
-
- // FIXME: This method is too big
- if (sURL == null) {
- throw new MalformedURLException("URL is null");
- }
-
- URL url = new URL(sURL);
- // Get the protocol and port (use default port if not specified)
- String protocol = url.getProtocol();
- String host = url.getHost();
- int port = HttpConnectionManager.getPort(protocol, url.getPort());
- final String hostAndPort = host + ":" + port;
-
- if (log.isDebugEnabled()) {
- log.debug("HttpConnectionManager.getConnection: key = "
- + hostAndPort);
- }
-
- // Look for a list of connections for the given host:port
- LinkedList listConnections = getConnections(hostAndPort);
-
- HttpConnection conn = null;
- // get a connection from the 'pool', waiting for 'timeout' if no
- // connections are currently available
- synchronized(listConnections) {
- if (listConnections.size() > 0) {
- conn = (HttpConnection)listConnections.removeFirst();
- } else {
- // get number of connections to host:port
- Integer numConnections = getConnectionsInUse(hostAndPort);
- if (numConnections.intValue() < maxConnections) {
- // Create a new connection
- boolean isSecure = protocol.equalsIgnoreCase("HTTPS");
- conn = new HttpConnection(proxyHost, proxyPort, host, port,
- isSecure);
- numConnections = new Integer(numConnections.intValue() + 1);
- mapNumConnections.put(hostAndPort, numConnections);
- } else {
- conn = waitForConnection(listConnections, timeout);
- }
- }
- }
-
- return conn;
- }
-
- /**
- * Get the pool (list) of connections available for the given host and port
+ * The connection manager should be registered with any HttpConnection that
+ * is created.
*
- * @param hostAndPort the key for the connection pool
- * @return a pool (list) of connections available for the given key
+ * @param hostConfiguration the host configuration to use to configure the
+ * connection
+ * @param timeout - the time (in milliseconds) to wait for a connection to
+ * become available, 0 to specify an infinite timeout
+ *
+ * @return an HttpConnection for the given configuraiton
+ *
+ * @exception org.apache.commons.httpclient.HttpException if no connection
+ * becomes available before the timeout expires
+ *
+ * @see HttpConnection#setHttpConnectionManager(HttpConnectionManager)
*/
- private LinkedList getConnections(String hostAndPort) {
- log.trace("enter HttpConnectionManager.getConnections(String)");
+ public HttpConnection getConnection(HostConfiguration hostConfiguration, long timeout)
+ throws HttpException, MalformedURLException;
- // Look for a list of connections for the given host:port
- LinkedList listConnections = null;
- synchronized (mapHosts) {
- listConnections = (LinkedList) mapHosts.get(hostAndPort);
- if (listConnections == null) {
- // First time for this host:port
- listConnections = new LinkedList();
- mapHosts.put(hostAndPort, listConnections);
- mapNumConnections.put(hostAndPort, new Integer(0));
- }
- }
- return listConnections;
- }
-
/**
- * Get the number of connections in use for the key
+ * Releases the given HttpConnection for use by other requests.
*
- * @param hostAndPort the key that connections are tracked on
- * @return the number of connections in use for the given key
- */
- public Integer getConnectionsInUse(String hostAndPort) {
- log.trace("enter HttpConnectionManager.getConnectionsInUse(String)");
- // FIXME: Shouldn't this be synchronized on mapNumConnections? or
- // mapHosts?
-
- Integer numConnections = (Integer)mapNumConnections.get(hostAndPort);
- if (numConnections == null) {
- log.error("HttpConnectionManager.getConnection: "
- + "No connection count for " + hostAndPort);
- // This should never happen, but just in case we'll try to recover.
- numConnections = new Integer(0);
- mapNumConnections.put(hostAndPort, numConnections);
- }
- return numConnections;
- }
-
- /**
- * wait for a connection from the pool
- */
- private HttpConnection waitForConnection(LinkedList pool, long timeout)
- throws HttpException {
- log.trace("enter HttpConnectionManager.waitForConnection(LinkedList, long)");
-
- // No connections available, so wait
- // Start the timeout thread
- TimeoutThread threadTimeout = new TimeoutThread();
- threadTimeout.setTimeout(timeout);
- threadTimeout.setWakeupThread(Thread.currentThread());
- threadTimeout.start();
-
- HttpConnection conn = null;
- // wait for the connection to be available
- while(conn == null){ // spin lock
- try {
- log.debug("HttpConnectionManager.getConnection: waiting for "
- + "connection from " + pool);
- pool.wait();
- } catch (InterruptedException e) {
- throw new HttpException("Timeout waiting for connection.");
- }
- if (pool.size() > 0) {
- conn = (HttpConnection)pool.removeFirst();
- threadTimeout.interrupt();
- }
- }
- return conn;
- }
-
- /**
- * Make the given HttpConnection available for use by other requests.
- * If another thread is blocked in getConnection() waiting for a connection
- * for this host:port, they will be woken up.
- *
* @param conn - The HttpConnection to make available.
*/
- public void releaseConnection(HttpConnection conn) {
- log.trace("enter HttpConnectionManager.releaseConnection(HttpConnection)");
-
- String host = conn.getHost();
- int port = conn.getPort();
- String key = host + ":" + port;
-
- if(log.isDebugEnabled()){
- log.debug("HttpConnectionManager.releaseConnection: Release connection for " + host + ":" + port);
- }
-
- LinkedList listConnections = null;
- synchronized(mapHosts){
- listConnections = (LinkedList)mapHosts.get(key);
- if(listConnections == null){
- // This is an error, but we'll try to recover
- log.error("HttpConnectionManager.releaseConnection: No connect list for " + key);
- listConnections = new LinkedList();
- mapHosts.put(key, listConnections);
- mapNumConnections.put(key, new Integer(1));
- }
- }
-
- synchronized(listConnections){
- // Put the connect back in the available list and notify a waiter
- listConnections.addFirst(conn);
- listConnections.notify();
- }
- }
-
- /**
- * In getConnection, if the maximum number of connections has already
- * been reached the call will block. This class is used to help provide
- * a timeout facility for this wait. Because Java does not provide a way to
- * determine if wait() returned due to a notify() or a timeout, we need
- * an outside mechanism to interrupt the waiting thread after the specified
- * timeout interval.
- */
- private static class TimeoutThread extends Thread {
-
- private long timeout = 0;
- private Thread thrdWakeup = null;
-
- public void setTimeout(long timeout)
- {
- this.timeout = timeout;
- }
-
- public long getTimeout()
- {
- return timeout;
- }
-
- public void setWakeupThread(Thread thrdWakeup)
- {
- this.thrdWakeup = thrdWakeup;
- }
-
- public Thread getWakeupThread()
- {
- return thrdWakeup;
- }
-
- public void run() {
- log.trace("TimeoutThread.run()");
- if(timeout == 0){
- return;
- }
- if(thrdWakeup == null){
- return;
- }
+ public void releaseConnection(HttpConnection conn);
- try{
- sleep(timeout);
- thrdWakeup.interrupt();
- }catch(InterruptedException e){
- log.debug("InterruptedException caught as expected");
- // This is expected
- }
- }
- }
}
Index: java/org/apache/commons/httpclient/HttpMethod.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java,v
retrieving revision 1.19
diff -u -r1.19 HttpMethod.java
--- java/org/apache/commons/httpclient/HttpMethod.java 7 Sep 2002 01:07:47 -0000 1.19
+++ java/org/apache/commons/httpclient/HttpMethod.java 20 Nov 2002 14:43:02 -0000
@@ -303,6 +303,13 @@
public void recycle();
/**
+ * Releases the connection being used by this method. In particular the
+ * connection is used to read the response(if there is one) and will be held
+ * until the response has been read.
+ */
+ public void releaseConnection();
+
+ /**
* Use this method internally to add footers.
* @since 2.0
*/
Index: java/org/apache/commons/httpclient/HttpMethodBase.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
retrieving revision 1.78
diff -u -r1.78 HttpMethodBase.java
--- java/org/apache/commons/httpclient/HttpMethodBase.java 8 Nov 2002 23:14:30 -0000 1.78
+++ java/org/apache/commons/httpclient/HttpMethodBase.java 20 Nov 2002 14:43:07 -0000
@@ -64,23 +64,21 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.URL;
+import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
+import java.net.URL;
import java.util.Date;
-import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
+import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.commons.httpclient.util.URIUtil;
/**
*
@@ -157,10 +155,10 @@
* @author dIon Gillard
* @author Jeff Dever
* @author Davanum Srinivas
- * @author Ortwin Glück
+ * @author Ortwin Gl?ck
*/
public abstract class HttpMethodBase implements HttpMethod {
- //~ Static variables/initializers ··········································
+ //~ Static variables/initializers ??????????????????????????????????????????
/** Maximum number of redirects and authentications that will be followed */
private static int maxForwards = 100;
@@ -182,7 +180,7 @@
USER_AGENT = new Header("User-Agent", agent);
}
- //~ Instance variables ·····················································
+ //~ Instance variables ?????????????????????????????????????????????????????
/** My request headers, if any. */
private Map requestHeaders = new HashMap();
@@ -210,6 +208,9 @@
/** The response body, assuming it has not be intercepted by a sub-class. */
private InputStream responseStream = null;
+
+ /** The connection that the response stream was read from. */
+ private HttpConnection responseConnection = null;
/** Buffer for the response */
private byte[] responseBody = null;
@@ -242,7 +243,7 @@
protected static final String DEFAULT_CHARSET = "US-ASCII";
- //~ Constructors ···························································
+ //~ Constructors ???????????????????????????????????????????????????????????
// ----------------------------------------------------------- Constructors
@@ -267,7 +268,7 @@
}
}
- //~ Methods ································································
+ //~ Methods ????????????????????????????????????????????????????????????????
// ------------------------------------------- Property Setters and Getters
@@ -758,6 +759,15 @@
return false;
}
+ private void wrapReponseStream( HttpConnection connection ) {
+
+ if ( responseStream != null ) {
+ this.responseConnection = connection;
+ this.responseStream = new ResponseAutoReleaseInputStream(responseStream);
+ }
+
+ }
+
/**
* Execute this method. Note that we cannot currently support redirects
* that change the connection parameters (host, port, protocol) because
@@ -831,9 +841,11 @@
//if the authentication is successful, return the statusCode
//otherwise, drop through the switch and try again.
if (processAuthenticationResponse(state, conn)) {
+ wrapReponseStream(conn);
return statusCode;
}
} else { //let the client handle the authenticaiton
+ wrapReponseStream(conn);
return statusCode;
}
break;
@@ -844,12 +856,14 @@
log.debug("Redirect required");
if (! processRedirectResponse(state, conn)) {
+ wrapReponseStream(conn);
return statusCode;
}
break;
default:
// neither an unauthorized nor a redirect response
+ wrapReponseStream(conn);
return statusCode;
} //end of switch
@@ -872,6 +886,8 @@
}
} //end of loop
+ wrapReponseStream(conn);
+
log.error("Narrowly avoided an infinite loop in execute");
throw new HttpRecoverableException("Maximum redirects ("+ maxForwards +") exceeded");
}
@@ -1027,6 +1043,8 @@
public void recycle() {
log.trace("enter HttpMethodBase.recycle()");
+ releaseConnection();
+
path = null;
followRedirects = false;
doAuthentication = true;
@@ -1041,6 +1059,19 @@
}
/**
+ * @see org.apache.commons.httpclient.HttpMethod#releaseConnection()
+ */
+ public void releaseConnection() {
+
+ if ( responseConnection != null ) {
+ responseConnection.releaseConnection();
+ this.responseConnection = null;
+ this.responseStream = null;
+ }
+
+ }
+
+ /**
* Remove the request header associated with the given name. Note that
* header-name matching is case insensitive.
*
@@ -1585,7 +1616,7 @@
responseBody = null; // is this desired?
Header lengthHeader = getResponseHeader("Content-Length");
Header transferEncodingHeader = getResponseHeader("Transfer-Encoding");
- InputStream is = conn.getResponseInputStream(this);
+ InputStream is = conn.getResponseInputStream();
if (wireLog.isDebugEnabled()) {
is = new WireLogInputStream(is);
}
@@ -1615,6 +1646,8 @@
try {
int expectedLength = Integer.parseInt(lengthValue);
+ // FIXME: what if the content length is 0, perhaps we should
+ // just return an empty stream in that case
result = new ContentLengthInputStream(is, expectedLength);
} catch(NumberFormatException e) {
throw new HttpException(
@@ -1628,11 +1661,14 @@
&& !getName().equals(ConnectMethod.NAME)){
result = is;
}
- if (result == null) return null;
+ if (result == null) {
+ return null;
+ }
if (shouldCloseConnection()) {
result = new AutoCloseInputStream(result, conn);
}
+
return result;
}
@@ -2262,5 +2298,65 @@
return getContentCharSet(getResponseHeader("Content-Type"));
}
+ /**
+ * Releases this connection from its connectionManager when the response has
+ * been read.
+ */
+ private class ResponseAutoReleaseInputStream extends InputStream {
+
+ private InputStream is;
+
+ public ResponseAutoReleaseInputStream(InputStream is) {
+ this.is = is;
+ }
+
+ /**
+ * @see java.io.InputStream#close()
+ */
+ public void close() throws IOException {
+ is.close();
+ releaseConnection();
+ }
+
+ /**
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException {
+ int b = is.read();
+
+ if ( b == -1 ) {
+ releaseConnection();
+ }
+
+ return b;
+ }
+
+ /**
+ * @see java.io.InputStream#read(byte, int, int)
+ */
+ public int read(byte[] array, int off, int len) throws IOException {
+ int b = is.read(array, off, len);
+
+ if ( b == -1 ) {
+ releaseConnection();
+ }
+
+ return b;
+ }
+
+ /**
+ * @see java.io.InputStream#read(byte)
+ */
+ public int read(byte[] array) throws IOException {
+ int b = is.read(array);
+
+ if ( b == -1 ) {
+ releaseConnection();
+ }
+
+ return b;
+ }
+
+ }
}
Index: java/org/apache/commons/httpclient/HttpMultiClient.java
===================================================================
RCS file: java/org/apache/commons/httpclient/HttpMultiClient.java
diff -N java/org/apache/commons/httpclient/HttpMultiClient.java
--- java/org/apache/commons/httpclient/HttpMultiClient.java 16 Oct 2002 16:58:26 -0000 1.17
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,344 +0,0 @@
-/*
- * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMultiClient.java,v 1.17 2002/10/16 16:58:26 jsdever Exp $
- * $Revision: 1.17 $
- * $Date: 2002/10/16 16:58:26 $
- * ====================================================================
- *
- * 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", "HttpClient", 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 apache@apache.org.
- *
- * 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.
- * ====================================================================
- *
- * 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
- * true if strict mode should be used
- *
- * @see #isStrictMode()
- *
- */
- public void setStrictMode(boolean strictMode) {
- this.strictMode = strictMode;
- }
-
- /**
- *
- * @return true if strict mode being used
- *
- * @see #setStrictMode(boolean)
- *
- */
- public boolean isStrictMode() {
- return strictMode;
- }
-
- /**
- * Sets the connection timeout. The connection timeout is how long (in
- * milliseconds) HttpMultiClient will block in executeMethod waiting for
- * a connection to the requested server to become available.
- *
- * Setting the connection timeout to 0 will cause executeMethod() to
- * block indefinitely (this is the default behaviour).
- *
- * @param timeout the time, in milliseconds, to block waiting for an
- * available connection
- * @see #getConnectionTimeout
- * @see #executeMethod
- */
- public void setConnectionTimeout(int timeout) {
- this.timeoutConnection = timeout;
- }
-
- /**
- * Returns the value of connection timeout.
- *
- * @return the connection timeout value
- * @see #setConnectionTimeout
- */
- public int getConnectionTimeout() {
- return timeoutConnection;
- }
-
- /**
- * Sets the request timeout. The executeMethod method calls
- * HttpConnection.setSoTimeout() with this value before executing the
- * request.
- *
- * @param timeout the SoTimeout value, in milliseconds
- * @see #getRequestTimeout
- * @see HttpConnection#setSoTimeout
- */
- public void setRequestTimeout(int timeout) {
- this.timeoutRequest = timeout;
- }
-
- /**
- * Returns the value of the request timeout.
- *
- * @return the request timeout
- * @see #setRequestTimeout(int)
- */
- public int getRequestTimeout() {
- return timeoutRequest;
- }
-
- /**
- * Sets the hostname for the HTTP proxy server to use for all
- * requests.
- *
- * @param host The hostname of the HTTP proxy server
- * @see HttpConnectionManager#setProxyHost
- */
- public void setProxyHost(String host) {
- mgr.setProxyHost(host);
- }
-
- /**
- * Returns the hostname for the HTTP proxy server in use for
- * all requests.
- *
- * @return the hostname of the HTTP proxy server
- * @see HttpConnectionManager#getProxyHost
- */
- public String getProxyHost() {
- return mgr.getProxyHost();
- }
-
- /**
- * Sets the port number for the HTTP proxy server to use
- * for all requests.
- *
- * @param port the proxy server port number
- * @see HttpConnectionManager#setProxyPort
- */
- public void setProxyPort(int port) {
- mgr.setProxyPort(port);
- }
-
- /**
- * Specifies an alternative factory for SSL sockets.
- * @see HttpConnection#setSSLSocketFactory(SSLSocketFactory) HttpConnection
- * setSSLSocketFactory
- * @param sslSocketFactory a living instance of the alternative
- * SSLSocketFactory
- */
- public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
- this.sslSocketFactory = sslSocketFactory;
- }
-
- /**
- * Returns the HTTP proxy server port number
- *
- * @return the HTTP proxy server port number
- * @see HttpConnectionManager#getProxyPort
- */
- public int getProxyPort() {
- return mgr.getProxyPort();
- }
-
- /**
- *
- * Execute the given {@link HttpUrlMethod} using my current
- * {@link HttpConnection connection} and {@link HttpState}.
- *
- * @param method the {@link HttpMethod} to execute. Must be non-null.
- * @return the method's response code
- *
- * @throws IOException if an I/O error occurs
- * @throws HttpException if a protocol exception occurs
- *
- */
- public int executeMethod(HttpUrlMethod method)
- throws IOException, HttpException {
- log.trace("enter executeMethod(HttpUrlMethod)");
-
- if (null == method) {
- throw new NullPointerException("method parameter");
- }
-
- HttpConnection connection = mgr.getConnection(method.getUrl(),
- timeoutConnection);
- connection.setSoTimeout(timeoutRequest);
- if (!connection.isOpen()) {
- connection.setSSLSocketFactory(sslSocketFactory);
- }
-
- int status = 0;
-
- method.setStrictMode(strictMode);
-
- try {
- status = method.execute(getState(), connection);
- } catch (IOException ex) {
- throw ex; // it might be IOException or HttpException instance.
- } finally {
- mgr.releaseConnection(connection);
- }
-
- // FIXME: Why is this different from the redirect processing in
- // HttpMethodBase
- if (status == HttpStatus.SC_MOVED_PERMANENTLY
- || status == HttpStatus.SC_MOVED_TEMPORARILY
- || status == HttpStatus.SC_SEE_OTHER
- || status == HttpStatus.SC_TEMPORARY_REDIRECT) {
- Header header = method.getResponseHeader("Location");
- String url = header.getValue();
- if (url == null) {
- log.error("HttpMultiClient.executeMethod: Received redirect "
- + "without Location header.");
- throw new HttpException("Received redirect without Location "
- + "header.");
- }
-
- method.recycle();
- method.setUrl(url);
- return executeMethod(method);
- }
-
- return status;
- }
-
-}
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.12
diff -u -r1.12 HttpState.java
--- java/org/apache/commons/httpclient/HttpState.java 5 Sep 2002 04:57:00 -0000 1.12
+++ java/org/apache/commons/httpclient/HttpState.java 20 Nov 2002 14:42:57 -0000
@@ -82,6 +82,7 @@
* @author Rodney Waldhoff
* @author Jeff Dever
* @author Sean C. Sullivan
+ * @author Michael Becke
*
* @version $Revision: 1.12 $ $Date: 2002/09/05 04:57:00 $
*
@@ -105,11 +106,24 @@
*/
private ArrayList cookies = new ArrayList();
+ private HttpConnectionManager httpConnectionManager;
+
// -------------------------------------------------------- Class Variables
/** Log object for this class. */
private static final Log log = LogFactory.getLog(HttpState.class);
+ /**
+ * Constructor for HttpState.
+ */
+ public HttpState() {
+
+ super();
+
+ this.httpConnectionManager = new SimpleHttpConnectionManager();
+
+ }
+
// ------------------------------------------------------------- Properties
/**
@@ -122,7 +136,7 @@
* @see #addCookies(Cookie[])
*
*/
- public void addCookie(Cookie cookie) {
+ public synchronized void addCookie(Cookie cookie) {
log.trace("enter HttpState.addCookie(Cookie)");
if (cookie != null) {
@@ -151,7 +165,7 @@
*
*
*/
- public void addCookies(Cookie[] newcookies) {
+ public synchronized void addCookies(Cookie[] newcookies) {
log.trace("enter HttpState.addCookies(Cookie[])");
if (newcookies != null) {
@@ -169,7 +183,7 @@
* @see #getCookies(String, int, String, boolean, java.util.Date)
*
*/
- public Cookie[] getCookies() {
+ public synchronized Cookie[] getCookies() {
log.trace("enter HttpState.getCookies()");
return (Cookie[])(cookies.toArray(new Cookie[cookies.size()]));
}
@@ -189,7 +203,13 @@
* @see #getCookies()
*
*/
- public Cookie[] getCookies(String domain, int port, String path, boolean secure, Date now) {
+ public synchronized Cookie[] getCookies(
+ String domain,
+ int port,
+ String path,
+ boolean secure,
+ Date now
+ ) {
log.trace("enter HttpState.getCookies(String, int, String, boolean, Date)");
ArrayList list = new ArrayList(cookies.size());
@@ -211,7 +231,7 @@
* @see #purgeExpiredCookies(java.util.Date)
*
*/
- public boolean purgeExpiredCookies() {
+ public synchronized boolean purgeExpiredCookies() {
log.trace("enter HttpState.purgeExpiredCookies()");
return purgeExpiredCookies(new Date());
}
@@ -224,7 +244,7 @@
* @see #purgeExpiredCookies()
*
*/
- public boolean purgeExpiredCookies(Date date) {
+ public synchronized boolean purgeExpiredCookies(Date date) {
log.trace("enter HttpState.purgeExpiredCookies(Date)");
boolean removed = false;
Iterator it = cookies.iterator();
@@ -256,7 +276,7 @@
* @see #setProxyCredentials(String, Credentials)
*
*/
- public void setCredentials(String realm, Credentials credentials) {
+ public synchronized void setCredentials(String realm, Credentials credentials) {
log.trace("enter HttpState.setCredentials(String, Credentials)");
credMap.put(realm,credentials);
}
@@ -275,7 +295,7 @@
* @see #setCredentials(String, Credentials)
*
*/
- public Credentials getCredentials(String realm) {
+ public synchronized Credentials getCredentials(String realm) {
log.trace("enter HttpState.getCredentials(String)");
Credentials creds = (Credentials) credMap.get(realm);
@@ -305,7 +325,7 @@
* @see #setCredentials(String, Credentials)
*
*/
- public void setProxyCredentials(String realm, Credentials credentials) {
+ public synchronized void setProxyCredentials(String realm, Credentials credentials) {
log.trace("enter HttpState.setProxyCredentials(String, credentials)");
proxyCred.put(realm, credentials);
}
@@ -322,7 +342,7 @@
* @return the credentials
* @see #setProxyCredentials
*/
- public Credentials getProxyCredentials(String realm) {
+ public synchronized Credentials getProxyCredentials(String realm) {
log.trace("enter HttpState.getProxyCredentials(String)");
Credentials creds = (Credentials) proxyCred.get(realm);
if (creds == null) {
@@ -331,7 +351,7 @@
return creds;
}
- public String toString()
+ public synchronized String toString()
{
StringBuffer sbResult = new StringBuffer();
@@ -401,4 +421,23 @@
}
return sbResult;
}
+
+ /**
+ * Returns the httpConnectionManager.
+ * @return HttpConnectionManager
+ */
+ public synchronized HttpConnectionManager getHttpConnectionManager() {
+ return httpConnectionManager;
+ }
+
+ /**
+ * Sets the httpConnectionManager.
+ * @param httpConnectionManager The httpConnectionManager to set
+ */
+ public synchronized void setHttpConnectionManager(
+ HttpConnectionManager httpConnectionManager
+ ) {
+ this.httpConnectionManager = httpConnectionManager;
+ }
+
}
Index: java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java
===================================================================
RCS file: java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java
diff -N java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 20 Nov 2002 14:43:01 -0000
@@ -0,0 +1,475 @@
+/*
+ * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnectionManager.java,v 1.11 2002/09/29 21:59:47 sullis Exp $
+ * $Revision: 1.11 $
+ * $Date: 2002/09/29 21:59:47 $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2002 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", "HttpClient", 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 apache@apache.org.
+ *
+ * 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.
+ * ====================================================================
+ *
+ * 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
+ *