You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by og...@apache.org on 2002/11/12 10:58:23 UTC
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestHttpConnection.java
oglueck 2002/11/12 01:58:23
Modified: httpclient/src/java/org/apache/commons/httpclient
HttpClient.java HttpConnection.java
httpclient/src/java/org/apache/commons/httpclient/methods
PostMethod.java
httpclient/src/test/org/apache/commons/httpclient
TestHttpConnection.java
Added: httpclient/src/java/org/apache/commons/httpclient/util
TimeoutController.java
Log:
Added connection timeout (bug #10973)
and corrected some whitespace
Revision Changes Path
1.60 +36 -23 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpClient.java
Index: HttpClient.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpClient.java,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -r1.59 -r1.60
--- HttpClient.java 21 Oct 2002 14:15:38 -0000 1.59
+++ HttpClient.java 12 Nov 2002 09:58:22 -0000 1.60
@@ -116,6 +116,8 @@
private int timeoutInMilliseconds = 0;
+ private int connectionTimeout = 0;
+
// ------------------------------------------------------------- Properties
/**
@@ -152,16 +154,26 @@
/**
* Sets the SO_TIMEOUT which is the timeout for waiting for data.
- *
+ *
* A timeout value of zero is interpreted as an infinite timeout.
- *
+ *
* @param newTimeoutInMilliseconds Timeout in milliseconds
- *
+ *
*/
public void setTimeout(int newTimeoutInMilliseconds) {
this.timeoutInMilliseconds = newTimeoutInMilliseconds;
}
+ /**
+ * 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) {
+ this.connectionTimeout = newTimeoutInMilliseconds;
+ }
+
// --------------------------------------------------------- Public Methods
/**
@@ -175,7 +187,7 @@
* @see #startSession(String, int, Credentials, boolean)
* @see #startSession(String, int, String, int)
* @see #endSession()
- *
+ *
*/
public void startSession(String host, int port) {
log.trace("enter HttpClient.startSession(String, int)");
@@ -214,13 +226,13 @@
* @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 #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)");
@@ -237,22 +249,22 @@
* @param port the port to connect to
* @param creds the default credentials to use
* @param https when <code>true</code>, 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()
- *
+ *
*/
public void startSession(String host, int port, Credentials creds, boolean https) {
log.trace("enter HttpClient.startSession(String, int, Credentials, boolean)");
if (log.isDebugEnabled()) {
log.debug(
- "Starting HttpClient session"
- + " Host:" + host
- + " Port:" + port + " Credentials:" + creds
+ "Starting HttpClient session"
+ + " Host:" + host
+ + " Port:" + port + " Credentials:" + creds
+ " HTTPS:" + https);
}
getState().setCredentials(null, creds);
@@ -331,14 +343,14 @@
log.trace("enter HttpClient.startSession(String, int, Credentials, boolean)");
if ("https".equalsIgnoreCase(url.getProtocol())) {
- startSession(url.getHost(), url.getPort() == -1 ? 443
- : url.getPort(), true);
+ startSession(url.getHost(), url.getPort() == -1 ? 443
+ : url.getPort(), true);
} else if ("http".equalsIgnoreCase(url.getProtocol())) {
startSession(url.getHost(), url.getPort() == -1 ? 80
- : url.getPort(), false);
+ : url.getPort(), false);
} else {
throw new IllegalArgumentException("Protocol " + url.getProtocol()
- + " not supported in URL " + url);
+ + " not supported in URL " + url);
}
}
@@ -391,7 +403,7 @@
* Start an HTTP session with the server specified
* by the given <i>host</i> and <i>port</i>
* via the given <i>proxyhost</i> and <i>proxyport</i>.
- *
+ *
* @param host the host to connect to
* @param port the port to connect to
* @param proxyhost the proxy host to connect via
@@ -416,7 +428,7 @@
* @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 {
@@ -434,6 +446,7 @@
if (!connection.isOpen()) {
connection.setSSLSocketFactory(sslSocketFactory);
connection.setSoTimeout(timeoutInMilliseconds);
+ connection.setConnectionTimeout(connectionTimeout);
connection.open();
if (connection.isProxied() && connection.isSecure()) {
method = new ConnectMethod(method);
@@ -453,9 +466,9 @@
* @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
- *
+ *
*/
public void endSession() throws IOException {
log.trace("enter HttpClient.endSession()");
1.24 +133 -64 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.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- HttpConnection.java 31 Oct 2002 07:45:34 -0000 1.23
+++ HttpConnection.java 12 Nov 2002 09:58:22 -0000 1.24
@@ -62,6 +62,7 @@
package org.apache.commons.httpclient;
+import org.apache.commons.httpclient.util.TimeoutController;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -130,7 +131,7 @@
* @param port the port I should connect to
* @param secure when <tt>true</tt>, connect via HTTPS (SSL)
*/
- public HttpConnection(String proxyHost, int proxyPort, String host,
+ public HttpConnection(String proxyHost, int proxyPort, String host,
int port, boolean secure) {
if (log.isDebugEnabled()){
log.debug("HttpConnectionManager.getConnection: creating "
@@ -311,13 +312,15 @@
* Set my {@link Socket}'s timeout, via {@link Socket#setSoTimeout}. If the
* connection is already open, the SO_TIMEOUT is changed. If no connection
* is open, then subsequent connections will use the timeout value.
+ * <p>
+ * Note: This is not a connection timeout but a timeout on network traffic!
*
* @param timeout the timeout value
* @throws SocketException - if there is an error in the underlying
* protocol, such as a TCP error.
* @throws IllegalStateException if I am not connected
*/
- public void setSoTimeout(int timeout)
+ public void setSoTimeout(int timeout)
throws SocketException, IllegalStateException {
log.debug("HttpConnection.setSoTimeout("+ timeout +")");
_so_timeout = timeout;
@@ -327,6 +330,16 @@
}
/**
+ * Sets the connection timeout. This is the maximum time that may be spent
+ * until a connection is established. The connection will fail after this
+ * amount of time.
+ * @param timeout The timeout in milliseconds. 0 means timeout is not used.
+ */
+ public void setConnectionTimeout(int timeout) {
+ this.connect_timeout = timeout;
+ }
+
+ /**
* Open this connection to the current host and port
* (via a proxy if so configured).
*
@@ -338,16 +351,38 @@
assertNotOpen(); // ??? is this worth doing?
try {
if (null == _socket) {
- String host = (null == _proxyHost) ? _host : _proxyHost;
- int port = (null == _proxyHost) ? _port : _proxyPort;
+ final String host = (null == _proxyHost) ? _host : _proxyHost;
+ final int port = (null == _proxyHost) ? _port : _proxyPort;
if (isSecure() && !isProxied()) {
if (sslSocketFactory == null) {
sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
}
- _socket = (new SocketCreator()).createSocket(host,port);
+ if (connect_timeout == 0) {
+ _socket = (new SocketCreator()).createSocket(host,port);
+ } else {
+ SocketTask task = new SocketTask() {
+ public void doit() throws IOException {
+ s = (new SocketCreator()).createSocket(host,port);
+ }
+ };
+ TimeoutController.execute(task, connect_timeout);
+ _socket = task.s;
+ if (task.exception != null) throw task.exception;
+ }
_usingSecureSocket = true;
} else {
- _socket = new Socket(host,port);
+ if (connect_timeout == 0) {
+ _socket = new Socket(host,port);
+ } else {
+ SocketTask task = new SocketTask() {
+ public void doit() throws IOException {
+ s = new Socket(host,port);
+ }
+ };
+ TimeoutController.execute(task, connect_timeout);
+ _socket = task.s;
+ if (task.exception != null) throw task.exception;
+ }
_usingSecureSocket = false;
}
}
@@ -360,6 +395,13 @@
// so close everything out
closeSocketAndStreams();
throw e;
+ } catch (TimeoutController.TimeoutException e) {
+ if (log.isWarnEnabled()) {
+ log.warn("The host "+ _host +":"+ _port +" (or proxy "+
+ _proxyHost +":"+ _proxyPort +") did not accept the connection "+
+ "within timeout of "+ connect_timeout +" milliseconds");
+ }
+ throw new ConnectionTimeoutException();
}
}
@@ -378,11 +420,11 @@
log.trace("enter HttpConnection.tunnelCreated()");
if (!isSecure() || !isProxied()) {
- throw new IllegalStateException("Connection must be secure and proxied to use this feature");
- }
+ throw new IllegalStateException("Connection must be secure and proxied to use this feature");
+ }
if (_usingSecureSocket) {
- throw new IllegalStateException("Already using a secure socket");
- }
+ throw new IllegalStateException("Already using a secure socket");
+ }
if (sslSocketFactory == null) {
sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
@@ -407,7 +449,7 @@
}
/**
- * Return a {@link RequestOutputStream} suitable for writing (possibly
+ * Return a {@link RequestOutputStream} suitable for writing (possibly
* chunked) bytes to my {@link OutputStream}.
*
* @throws IllegalStateException if I am not connected
@@ -422,7 +464,7 @@
}
/**
- * Return a {@link RequestOutputStream} suitable for writing (possibly
+ * Return a {@link RequestOutputStream} suitable for writing (possibly
* chunked) bytes to my {@link OutputStream}.
*
* @param useChunking when <tt>true</tt> the chunked transfer-encoding will
@@ -432,7 +474,7 @@
* @return a stream to write the request to
* @deprecated Use new ChunkedOutputStream(httpConnecion.getRequestOutputStream());
*/
- public OutputStream getRequestOutputStream(boolean useChunking)
+ public OutputStream getRequestOutputStream(boolean useChunking)
throws IOException, IllegalStateException {
log.trace("enter HttpConnection.getRequestOutputStream(boolean)");
@@ -445,7 +487,7 @@
}
/**
- * Return a {@link ResponseInputStream} suitable for reading (possibly
+ * Return a {@link ResponseInputStream} suitable for reading (possibly
* chunked) bytes from my {@link InputStream}.
* <p>
* If the given {@link HttpMethod} contains
@@ -457,15 +499,15 @@
* @throws IllegalStateException if I am not connected
* @throws IOException if an I/O problem occurs
* @return a stream to read the response from
- * @deprecated Use getResponseInputStream() instead.
+ * @deprecated Use getResponseInputStream() instead.
*/
- public InputStream getResponseInputStream(HttpMethod method)
+ public InputStream getResponseInputStream(HttpMethod method)
throws IOException, IllegalStateException {
log.trace("enter HttpConnection.getResponseInputStream(HttpMethod)");
return getResponseInputStream();
}
- public InputStream getResponseInputStream()
+ public InputStream getResponseInputStream()
throws IOException, IllegalStateException {
log.trace("enter HttpConnection.getResponseInputStream()");
assertOpen();
@@ -476,12 +518,12 @@
* Write the specified bytes to my output stream.
*
* @param data the data to be written
- * @throws HttpRecoverableException if a SocketException occurs
+ * @throws HttpRecoverableException if a SocketException occurs
* @throws IllegalStateException if not connected
* @throws IOException if an I/O problem occurs
- * @see #write(byte[],int,int)
+ * @see #write(byte[],int,int)
*/
- public void write(byte[] data)
+ public void write(byte[] data)
throws IOException, IllegalStateException, HttpRecoverableException {
log.trace("enter HttpConnection.write(byte[])");
this.write(data, 0, data.length);
@@ -489,8 +531,8 @@
/**
- * Write <i>length</i> bytes in <i>data</i> starting at
- * <i>offset</i> to my output stream.
+ * Write <i>length</i> bytes in <i>data</i> starting at
+ * <i>offset</i> to my output stream.
*
* The general contract for
* write(b, off, len) is that some of the bytes in the array b are written
@@ -500,11 +542,11 @@
* @param data array containing the data to be written.
* @param offset the start offset in the data.
* @param length the number of bytes to write.
- * @throws HttpRecoverableException if a SocketException occurs
+ * @throws HttpRecoverableException if a SocketException occurs
* @throws IllegalStateException if not connected
* @throws IOException if an I/O problem occurs
*/
- public void write(byte[] data, int offset, int length)
+ public void write(byte[] data, int offset, int length)
throws IOException, IllegalStateException, HttpRecoverableException {
log.trace("enter HttpConnection.write(byte[], int, int)");
@@ -546,13 +588,13 @@
* @throws IllegalStateException if I am not connected
* @throws IOException if an I/O problem occurs
*/
- public void writeLine(byte[] data)
+ public void writeLine(byte[] data)
throws IOException, IllegalStateException, HttpRecoverableException {
log.trace("enter HttpConnection.writeLine(byte[])");
assertOpen();
if(wireLog.isDebugEnabled() && (data.length > 0)) {
- String data_str = new String(data);
+ String data_str = new String(data);
wireLog.debug(">> \"" + data_str.trim() + "\" [\\r\\n]" );
}
try{
@@ -575,7 +617,7 @@
* @throws IllegalStateException if I am not connected
* @throws IOException if an I/O problem occurs
*/
- public void writeLine()
+ public void writeLine()
throws IOException, IllegalStateException, HttpRecoverableException {
log.trace("enter HttpConnection.writeLine()");
@@ -600,14 +642,14 @@
* @throws IllegalStateException if I am not connected
* @throws IOException if an I/O problem occurs
*/
- public void print(String data)
+ public void print(String data)
throws IOException, IllegalStateException, HttpRecoverableException {
log.trace("enter HttpConnection.print(String)");
write(data.getBytes());
}
/**
- * Write the specified String (as bytes), followed by
+ * Write the specified String (as bytes), followed by
* <tt>"\r\n".getBytes()</tt> to my output stream.
*
* @param data the data to be written
@@ -675,7 +717,7 @@
/**
* Shutdown my {@link Socket}'s output, via {@link Socket#shutdownOutput}.
*/
- public void shutdownOutput() {
+ public void shutdownOutput() {
log.trace("enter HttpConnection.shutdownOutput()");
try {
@@ -710,42 +752,42 @@
*/
protected void closeSocketAndStreams() {
log.trace("enter HttpConnection.closeSockedAndStreams()");
-
+
if (null != _input) {
- try {
- _input.close();
- } catch(Exception ex) {
- log.debug("Exception caught when closing input", ex);
- // ignored
- }
- _input = null;
- }
-
- if (null != _output) {
- try {
- _output.close();
- } catch(Exception ex) {
- log.debug("Exception caught when closing output", ex);
- // ignored
- }
- _output = null;
- }
-
- if (null != _socket) {
- try {
- _socket.close();
- } catch(Exception ex) {
- log.debug("Exception caught when closing socket", ex);
- // ignored
- }
- _socket = null;
- }
+ try {
+ _input.close();
+ } catch(Exception ex) {
+ log.debug("Exception caught when closing input", ex);
+ // ignored
+ }
+ _input = null;
+ }
+
+ if (null != _output) {
+ try {
+ _output.close();
+ } catch(Exception ex) {
+ log.debug("Exception caught when closing output", ex);
+ // ignored
+ }
+ _output = null;
+ }
+
+ if (null != _socket) {
+ try {
+ _socket.close();
+ } catch(Exception ex) {
+ log.debug("Exception caught when closing socket", ex);
+ // ignored
+ }
+ _socket = null;
+ }
_open = false;
_tunnelEstablished = false;
_usingSecureSocket = false;
}
- /**
+ /**
* Throw an {@link IllegalStateException} if I am connected.
*
* @throws IllegalStateException if connected
@@ -769,6 +811,31 @@
}
}
+ // -- Timeout Exception
+ /**
+ * Signals that a timeout occured while opening the socket.
+ */
+ public class ConnectionTimeoutException extends IOException {
+ public ConnectionTimeoutException() {
+ }
+ }
+
+ // -- Helper
+ private abstract class SocketTask implements Runnable {
+ public Socket s;
+ public IOException exception;
+
+ public abstract void doit() throws IOException;
+
+ public void run() {
+ try {
+ doit();
+ } catch(IOException e) {
+ exception = e;
+ }
+ }
+ }
+
// -- javax.net binary isolation
private class SocketCreator {
@@ -814,4 +881,6 @@
private boolean _usingSecureSocket = false;
/** Whether I am tunneling a proxy or not */
private boolean _tunnelEstablished = false;
+ /** Timeout until connection established (Socket created). 0 means no timeout. */
+ private int connect_timeout = 0;
}
1.27 +73 -74 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/PostMethod.java
Index: PostMethod.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/PostMethod.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- PostMethod.java 28 Oct 2002 14:20:30 -0000 1.26
+++ PostMethod.java 12 Nov 2002 09:58:23 -0000 1.27
@@ -91,7 +91,7 @@
* enclosed in the request as a new subordinate of the resource identified by
* the Request-URI in the Request-Line. POST is designed to allow a uniform
* method to cover the following functions:
- *
+ *
* <ul>
* <li>
* Annotation of existing resources;
@@ -108,9 +108,9 @@
* Extending a database through an append operation.
* </li>
* </ul>
- *
+ *
* </blockquote>
- *
+ *
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
@@ -138,7 +138,7 @@
private static final Log log = LogFactory.getLog(PostMethod.class);
/** The Content-Type header for www-form-urlcoded. */
- static final Header CONTENT_TYPE = new Header("Content-Type",
+ static final Header CONTENT_TYPE = new Header("Content-Type",
"application/x-www-form-urlencoded");
/** The buffered request body. */
@@ -162,7 +162,7 @@
/**
* No-arg constructor.
- *
+ *
* @since 1.0
*/
public PostMethod() {
@@ -172,9 +172,9 @@
/**
* Path-setting constructor.
- *
+ *
* @param path the path to request
- *
+ *
* @since 1.0
*/
public PostMethod(String path) {
@@ -184,10 +184,10 @@
/**
* Path and temp directory constructor.
- *
+ *
* @param path the path to request
* @param tempDir directory to store temp files in
- *
+ *
* @since 1.0
*/
public PostMethod(String path, String tempDir) {
@@ -197,11 +197,11 @@
/**
* Path, temp directory and temp file constructor.
- *
+ *
* @param path the path to request
* @param tempDir directory to store temp files in
* @param tempFile file to store temporary data in
- *
+ *
* @since 1.0
*/
public PostMethod(String path, String tempDir, String tempFile) {
@@ -216,10 +216,10 @@
/**
* A POST request can only be redirected if input is buffered. Overrides
* method of {@link org.apache.commons.httpclient.HttpMethodBase}.
- *
+ *
* @return true if request is buffered and <code>setFollowRedirects</code>
* was set to <code>true</code>.
- *
+ *
* @since 2.0
*/
public boolean getFollowRedirects() {
@@ -234,9 +234,9 @@
/**
* Returns <tt>"POST"</tt>.
- *
+ *
* @return <tt>"POST"</tt>
- *
+ *
* @since 2.0
*/
public String getName() {
@@ -246,13 +246,13 @@
/**
* Set the value of parameter with parameterName to parameterValue. Does
* not preserve the initial insertion order.
- *
+ *
* @param parameterName DOCUMENT ME!
* @param parameterValue DOCUMENT ME!
- *
+ *
* @throws IllegalStateException if my request body has already been
* generated.
- *
+ *
* @since 2.0
* @deprecated use {@link #removeParameter(String,String)} followed by
* {@link #addParameter(String,String)}.
@@ -271,12 +271,12 @@
/**
* Gets the parameter of the specified name. If there exists more than one
* parameter with the name paramName, then only the first one is returned.
- *
+ *
* @param paramName DOCUMENT ME!
- *
+ *
* @return If a parameter exists with the name argument, the coresponding
* NameValuePair is returned. Otherwise null.
- *
+ *
* @since 2.0
*/
public NameValuePair getParameter(String paramName) {
@@ -304,9 +304,9 @@
* parameters, a valid array is returned with zero elements. The returned
* array object contains an array of pointers to the internal data
* members. TODO: is it ok to return internal data?
- *
+ *
* @return An array of the current parameters
- *
+ *
* @since 2.0
* @see #getParameter(java.lang.String)
*/
@@ -326,16 +326,16 @@
/**
* Sets the request body to be the specified string.
- *
+ *
* <p>
* Once this method has been invoked, the request parameters cannot be
* altered until I am {@link #recycle recycled}.
* </p>
- *
+ *
* @param body Request content as a string
- *
+ *
* @throws IllegalStateException if request params have been added
- *
+ *
* @since 2.0
*/
public void setRequestBody(String body) {
@@ -354,8 +354,7 @@
byte[] tmp = null;
try {
tmp = body.getBytes(getRequestCharSet());
- }
- catch(UnsupportedEncodingException e) {
+ } catch(UnsupportedEncodingException e) {
if (log.isWarnEnabled()) {
log.warn("Unsupported request body charset: " + e.getMessage());
}
@@ -366,16 +365,16 @@
/**
* Sets the request body to be the specified inputstream.
- *
+ *
* <p>
* Once this method has been invoked, the request parameters cannot be
* altered until I am {@link #recycle recycled}.
* </p>
- *
+ *
* @param body DOCUMENT ME!
- *
+ *
* @throws IllegalStateException if request params have been added
- *
+ *
* @since 2.0
*/
public void setRequestBody(InputStream body) {
@@ -391,10 +390,10 @@
/**
* Gets the requestBody as it would be if it was executed.
- *
+ *
* @return The request body if it has been set. The generated request
* body from the paramters if they exist. Null otherwise.
- *
+ *
* @since 2.0
*/
public InputStream getRequestBody() {
@@ -411,10 +410,10 @@
/**
* DOCUMENT ME!
- *
+ *
* @return the request body as a string
* @throws IOException DOCUMENT ME!
- *
+ *
* @since 2.0
*/
public String getRequestBodyAsString() throws IOException {
@@ -434,7 +433,7 @@
/**
* Sets length information about the request body.
- *
+ *
* <p>
* Note: If you specify a content length the request is unbuffered. This
* prevents redirection and automatic retry if a request fails the first
@@ -442,7 +441,7 @@
* automatically but will throw an Exception. You will have to set the
* necessary 'Authorization' or 'Proxy-Authorization' headers manually.
* </p>
- *
+ *
* @param length size in bytes or any of CONTENT_LENGTH_AUTO,
* CONTENT_LENGTH_CHUNKED. If number of bytes or CONTENT_LENGTH_CHUNKED
* is specified the content will not be buffered internally and the
@@ -452,7 +451,7 @@
* before it is sent over the network.
* @throws RuntimeException if chunked transfer encoding is requested for
* a HTTP 1.0 request
- *
+ *
* @since 2.0
*/
public void setRequestContentLength(int length) {
@@ -468,14 +467,14 @@
/**
* Add a new parameter to be used in the POST request body.
- *
+ *
* @param paramName The parameter name to add.
* @param paramValue The parameter value to add.
- *
+ *
* @throws IllegalStateException if my request body has already been
* generated.
* @throws IllegalArgumentException if either argument is null
- *
+ *
* @since 1.0
*/
public void addParameter(String paramName, String paramValue) {
@@ -495,14 +494,14 @@
/**
* Add a new parameter to be used in the POST request body.
- *
+ *
* @param param The parameter to add.
- *
+ *
* @throws IllegalStateException if my request body has already been
* generated.
* @throws IllegalArgumentException if the argument is null or contains
* null values
- *
+ *
* @since 2.0
* @see #addParameter(String,String)
*/
@@ -524,12 +523,12 @@
/**
* Add an Array of parameters to be used in the POST request body. Logs a
* warning if the parameters argument is null.
- *
+ *
* @param parameters The array of parameters to add.
- *
+ *
* @throws IllegalStateException if my request body has already been
* generated.
- *
+ *
* @since 2.0
* @see #addParameter(org.apache.commons.httpclient.NameValuePair)
*/
@@ -552,7 +551,7 @@
/**
* Override method of {@link org.apache.commons.httpclient.HttpMethodBase}
* to clear my request body.
- *
+ *
* @since 1.0
*/
public void recycle() {
@@ -569,15 +568,15 @@
* one parameter with the given paramName, all of them are removed. If
* there is just one, it is removed. If there are none, then the request
* is ignored.
- *
+ *
* @param paramName The parameter name to remove.
- *
+ *
* @return true if at least one parameter was removed
- *
+ *
* @throws IllegalStateException if my request body has already been
* generated.
* @throws IllegalArgumentException When the parameter name passed is null
- *
+ *
* @since 2.0
*/
public boolean removeParameter(String paramName) {
@@ -611,16 +610,16 @@
* Removes all parameter with the given paramName and paramValue. If there
* is more than one parameter with the given paramName, only one is
* removed. If there are none, then the request is ignored.
- *
+ *
* @param paramName The parameter name to remove.
* @param paramValue The parameter value to remove.
- *
+ *
* @return true if a parameter was removed.
- *
+ *
* @throws IllegalStateException if my request body has already been
* generated.
* @throws IllegalArgumentException when param name or value are null
- *
+ *
* @since 2.0
*/
public boolean removeParameter(String paramName, String paramValue) {
@@ -655,9 +654,9 @@
/**
* Override method of {@link org.apache.commons.httpclient.HttpMethodBase}
* to return the length of the request body.
- *
+ *
* @return number of bytes in the request body
- *
+ *
* @since 2.0
*/
protected int getRequestContentLength() {
@@ -680,19 +679,19 @@
/**
* Override method of {@link org.apache.commons.httpclient.HttpMethodBase}
* to also add <tt>Content-Type</tt> header when appropriate.
- *
+ *
* @param state DOCUMENT ME!
* @param conn DOCUMENT ME!
* @throws IOException DOCUMENT ME!
* @throws HttpException DOCUMENT ME!
- *
+ *
* @since 2.0
*/
protected void addRequestHeaders(HttpState state, HttpConnection conn)
throws IOException, HttpException {
super.addRequestHeaders(state, conn);
- if (!parameters.isEmpty()) {
+ if (!parameters.isEmpty()) {
//there are some parameters, so set the contentType header
setRequestHeader(CONTENT_TYPE);
}
@@ -702,16 +701,16 @@
* Override method of {@link org.apache.commons.httpclient.HttpMethodBase}
* to write request parameters as the request body. The input stream will
* be truncated after the specified content length.
- *
+ *
* @param state DOCUMENT ME!
* @param conn DOCUMENT ME!
- *
+ *
* @return always returns true
- *
+ *
* @throws IOException if the stream ends before the specified content
* length. <p>
* @throws HttpException DOCUMENT ME!
- *
+ *
* @since 2.0
*/
protected boolean writeRequestBody(HttpState state, HttpConnection conn)
@@ -764,11 +763,11 @@
/**
* Encode the list of parameters into a query stream.
- *
+ *
* @param params the list of query name and value
- *
+ *
* @return the query stream
- *
+ *
* @since 1.0
*/
static InputStream generateRequestBody(List params) {
@@ -807,7 +806,7 @@
/**
* Buffers the request body and calculates the content length. If the
* method was called earlier it returns immediately.
- *
+ *
* @since 1.0
*/
private void bufferContent() {
1.1 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/TimeoutController.java
Index: TimeoutController.java
===================================================================
/*
* $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/TimeoutController.java,v 1.1 2002/11/12 09:58:23 oglueck Exp $
* $Revision: 1.1 $
* $Date: 2002/11/12 09:58:23 $
* ====================================================================
*
* 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
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.commons.httpclient.util;
/**
* <p>
* Executes a task with a specified timeout.
* </p>
* @author Ortwin Gl�ck
* @version $Revision: 1.1 $
* @since 2.0
*/
public final class TimeoutController {
/**
* Do not instantiate objects of this class. Methods are static.
*/
private TimeoutController() {
}
/**
* Executes <code>task</code>. Waits for <code>timeout</code>
* milliseconds for the task to end and returns. If the task does not return
* in time, the thread is interrupted and an Exception is thrown.
* The caller should override the Thread.interrupt() method to something that
* quickly makes the thread die or use Thread.isInterrupted().
* @param task The thread to execute
* @param timeout The timeout in milliseconds. 0 means to wait forever.
* @throws TimeoutException if the timeout passes and the thread does not return.
*/
public static void execute(Thread task, long timeout) throws TimeoutException {
task.start();
try {
task.join(timeout);
} catch(InterruptedException e) {
/* if somebody interrupts us he knows what he is doing */
}
if (task.isAlive()) {
task.interrupt();
throw new TimeoutException();
}
}
/**
* Executes <code>task</code> in a new deamon Thread and waits for the timeout.
* @param task The task to execute
* @param timeout The timeout in milliseconds. 0 means to wait forever.
* @throws TimeoutException if the timeout passes and the thread does not return.
*/
public static void execute(Runnable task, long timeout) throws TimeoutException {
Thread t = new Thread(task, "Timeout guard");
t.setDaemon(true);
execute(t, timeout);
}
/**
* Signals that the task timed out.
*/
public static class TimeoutException extends Exception {
public TimeoutException() {
}
}
}
1.2 +35 -22 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnection.java
Index: TestHttpConnection.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnection.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestHttpConnection.java 8 Sep 2002 05:43:27 -0000 1.1
+++ TestHttpConnection.java 12 Nov 2002 09:58:23 -0000 1.2
@@ -69,12 +69,12 @@
/**
*
- * Unit tests for {@link HttpConnection}.
+ * Unit tests for {@link HttpConnection}.
*
* @author Sean C. Sullivan
- *
+ *
* @version $Id$
- *
+ *
*/
public class TestHttpConnection extends TestCase {
// ----------------------------------------------------- Instance Variables
@@ -101,48 +101,61 @@
public void testConstructThenClose() {
HttpConnection conn = new HttpConnection("localhost", 8080);
- conn.close();
- assertTrue( ! conn.isOpen() );
+ conn.close();
+ assertTrue( ! conn.isOpen() );
+ }
+
+ public void testConnTimeout() {
+ HttpConnection conn = new HttpConnection("localhost", 8080);
+ // 1 ms is short enough to make this fail
+ conn.setConnectionTimeout(1);
+ try {
+ conn.open();
+ fail("Should have timed out");
+ } catch(IOException e) {
+ assertTrue(e instanceof HttpConnection.ConnectionTimeoutException);
+ /* should fail */
+ }
}
public void testForIllegalStateExceptions() {
HttpConnection conn = new HttpConnection("localhost", 8080);
-
+
try {
- OutputStream out = conn.getRequestOutputStream();
- fail("getRequestOutputStream did not throw the expected exception");
+ OutputStream out = conn.getRequestOutputStream();
+ fail("getRequestOutputStream did not throw the expected exception");
}
catch (IllegalStateException expected) {
- // this exception is expected
+ // this exception is expected
}
catch (IOException ex) {
- fail("getRequestOutputStream did not throw the expected exception");
+ fail("getRequestOutputStream did not throw the expected exception");
}
-
+
try {
- OutputStream out = conn.getRequestOutputStream(true);
- fail("getRequestOutputStream(true) did not throw the expected exception");
+ OutputStream out = conn.getRequestOutputStream(true);
+ fail("getRequestOutputStream(true) did not throw the expected exception");
}
catch (IllegalStateException expected) {
- // this exception is expected
+ // this exception is expected
}
catch (IOException ex) {
- fail("getRequestOutputStream(true) did not throw the expected exception");
+ fail("getRequestOutputStream(true) did not throw the expected exception");
}
-
+
try {
- InputStream in = conn.getResponseInputStream(new PostMethod());
- fail("getResponseInputStream() did not throw the expected exception");
+ InputStream in = conn.getResponseInputStream(new PostMethod());
+ fail("getResponseInputStream() did not throw the expected exception");
}
catch (IllegalStateException expected) {
- // this exception is expected
+ // this exception is expected
}
catch (IOException ex) {
- fail("getResponseInputStream() did not throw the expected exception");
+ fail("getResponseInputStream() did not throw the expected exception");
}
-
-
+
+
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>