Index: java/org/apache/commons/httpclient/ConnectTimeoutException.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectTimeoutException.java,v retrieving revision 1.4 diff -u -r1.4 ConnectTimeoutException.java --- java/org/apache/commons/httpclient/ConnectTimeoutException.java 13 May 2004 04:03:25 -0000 1.4 +++ java/org/apache/commons/httpclient/ConnectTimeoutException.java 2 Jul 2004 15:23:04 -0000 @@ -29,6 +29,10 @@ package org.apache.commons.httpclient; +import java.io.InterruptedIOException; + +import org.apache.commons.httpclient.util.ExceptionUtil; + /** * A timeout while connecting to an HTTP server or waiting for an * available connection from an HttpConnectionManager. @@ -37,7 +41,7 @@ * * @since 3.0 */ -public class ConnectTimeoutException extends HttpTimeoutException { +public class ConnectTimeoutException extends InterruptedIOException { /** * Creates a ConnectTimeoutException with a null detail message. @@ -63,7 +67,9 @@ * if the cause is unavailable, unknown, or not a Throwable */ public ConnectTimeoutException(String message, Throwable cause) { - super(message, cause); + super(message); + // If we're running on JDK 1.4 or later, tell Throwable what the cause was + ExceptionUtil.initCause(this, cause); } } Index: java/org/apache/commons/httpclient/DefaultMethodRetryHandler.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/DefaultMethodRetryHandler.java,v retrieving revision 1.3 diff -u -r1.3 DefaultMethodRetryHandler.java --- java/org/apache/commons/httpclient/DefaultMethodRetryHandler.java 18 Apr 2004 23:51:34 -0000 1.3 +++ java/org/apache/commons/httpclient/DefaultMethodRetryHandler.java 2 Jul 2004 15:23:04 -0000 @@ -56,6 +56,9 @@ * if the given method should be retried. * * @see MethodRetryHandler#retryMethod(HttpMethod, HttpConnection, HttpRecoverableException, int, boolean) + * @see HttpMethod#isRequestSent + * + * @deprecated use #retryMethod(HttpMethod, HttpConnection, HttpRecoverableException, int, boolean) */ public boolean retryMethod( HttpMethod method, @@ -65,6 +68,26 @@ boolean requestSent ) { return ((!requestSent || requestSentRetryEnabled) && (executionCount <= retryCount)); + } + + /** + * Used retryCount and requestSentRetryEnabled to determine + * if the given method should be retried. + * + * @see MethodRetryHandler#retryMethod(HttpMethod, HttpConnection, HttpRecoverableException, int) + * @see HttpMethod#isRequestSent + */ + public boolean retryMethod( + HttpMethod method, + HttpConnection connection, + HttpRecoverableException recoverableException, + int executionCount + ) { + if (method == null) { + throw new IllegalArgumentException("Method may not be null"); + } + return ((!method.isRequestSent() || requestSentRetryEnabled) + && (executionCount <= retryCount)); } /** * @return true if this handler will retry methods that have 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.95 diff -u -r1.95 HttpConnection.java --- java/org/apache/commons/httpclient/HttpConnection.java 25 Jun 2004 03:34:56 -0000 1.95 +++ java/org/apache/commons/httpclient/HttpConnection.java 2 Jul 2004 15:23:05 -0000 @@ -484,7 +484,7 @@ socket.setSoTimeout(this.params.getSoTimeout()); } } - } catch (IOTimeoutException e) { + } catch (InterruptedIOException e) { // aha - the connection is NOT stale - continue on! } catch (IOException e) { // oops - the connection is stale, the read or soTimeout failed. @@ -687,16 +687,13 @@ socket.setReceiveBufferSize(rcvBufSize); } inputStream = new PushbackInputStream( - new WrappedInputStream(socket.getInputStream())); + socket.getInputStream()); outputStream = new BufferedOutputStream( new WrappedOutputStream(socket.getOutputStream()), socket.getSendBufferSize() ); isOpen = true; used = false; - } catch (InterruptedIOException e) { - closeSocketAndStreams(); - throw new ConnectTimeoutException("Open connection interrupted", e); } catch (IOException e) { // Connection wasn't opened properly // so close everything out @@ -741,7 +738,7 @@ socket.setReceiveBufferSize(rcvBufSize); } inputStream = new PushbackInputStream( - new WrappedInputStream(socket.getInputStream())); + socket.getInputStream()); outputStream = new BufferedOutputStream( new WrappedOutputStream(socket.getOutputStream()), socket.getSendBufferSize() @@ -849,7 +846,7 @@ } else { LOG.debug("Input data not available"); } - } catch (IOTimeoutException e) { + } catch (InterruptedIOException e) { if (LOG.isDebugEnabled()) { LOG.debug("Input data not available after " + timeout + " ms"); } @@ -1265,9 +1262,7 @@ // keep the original value of used, as it will be set to false by close(). boolean isRecoverable = HttpConnection.this.used; HttpConnection.this.close(); - if (ioe instanceof InterruptedIOException) { - return new IOTimeoutException(ioe.getMessage(), ioe); - } else if (isRecoverable) { + if (!(ioe instanceof InterruptedIOException) && isRecoverable) { LOG.debug( "Output exception occurred on a used connection. Will treat as recoverable.", ioe @@ -1316,75 +1311,6 @@ try { out.write(b); HttpConnection.this.used = true; - } catch (IOException ioe) { - throw handleException(ioe); - } - } - - } - - /** - * A wrapper for input streams that converts to HTTPClient - * specific exceptions as appropriable when an IOException occurs. - */ - private class WrappedInputStream extends InputStream { - - /** the actual inpuit stream */ - private InputStream in; - - /** - * @param in the input stream to wrap - */ - public WrappedInputStream(InputStream in) { - this.in = in; - } - - /** - * Conditionally converts exception to HttpClient specific - * exception. - * @param ioe the exception that occurred - * @return the exception to be thrown - */ - private IOException handleException(final IOException ioe) { - if (ioe instanceof InterruptedIOException) { - return new IOTimeoutException(ioe.getMessage(), ioe); - } else { - return ioe; - } - } - - public int read() throws IOException { - try { - return in.read(); - } catch (IOException ioe) { - throw handleException(ioe); - } - } - - public void close() throws IOException { - in.close(); - } - - public int read(byte[] b, int off, int len) throws IOException { - try { - return in.read(b, off, len); - } catch (IOException ioe) { - throw handleException(ioe); - } - } - - public int read(byte[] b) throws IOException { - try { - return in.read(b); - } catch (IOException ioe) { - throw handleException(ioe); - } - } - - public int available() throws IOException - { - try { - return in.available(); } catch (IOException ioe) { throw handleException(ioe); } 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.23 diff -u -r1.23 HttpConnectionManager.java --- java/org/apache/commons/httpclient/HttpConnectionManager.java 17 May 2004 21:46:03 -0000 1.23 +++ java/org/apache/commons/httpclient/HttpConnectionManager.java 2 Jul 2004 15:23:05 -0000 @@ -101,7 +101,7 @@ * * @return an HttpConnection for the given configuraiton * - * @throws ConnectTimeoutException if no connection becomes available before the + * @throws ConnectionPoolTimeoutException if no connection becomes available before the * timeout expires * * @see HttpConnection#setHttpConnectionManager(HttpConnectionManager) @@ -109,7 +109,7 @@ * @since 3.0 */ HttpConnection getConnectionWithTimeout(HostConfiguration hostConfiguration, long timeout) - throws ConnectTimeoutException; + throws ConnectionPoolTimeoutException; /** * Releases the given HttpConnection for use by other requests. 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.40 diff -u -r1.40 HttpMethod.java --- java/org/apache/commons/httpclient/HttpMethod.java 13 Jun 2004 20:22:18 -0000 1.40 +++ java/org/apache/commons/httpclient/HttpMethod.java 2 Jul 2004 15:23:05 -0000 @@ -579,4 +579,14 @@ */ public AuthState getProxyAuthState(); + /** + * Returns true if the HTTP has been transmitted to the target + * server in its entirety, false otherwise. This flag can be useful + * for recovery logic. If the request has not been transmitted in its entirety, + * it is safe to retry the failed method. + * + * @return true if the request has been sent, false otherwise + */ + boolean isRequestSent(); + } 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.209 diff -u -r1.209 HttpMethodBase.java --- java/org/apache/commons/httpclient/HttpMethodBase.java 24 Jun 2004 21:39:52 -0000 1.209 +++ java/org/apache/commons/httpclient/HttpMethodBase.java 2 Jul 2004 15:23:06 -0000 @@ -33,6 +33,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import org.apache.commons.httpclient.auth.AuthState; import org.apache.commons.httpclient.cookie.CookiePolicy; @@ -171,6 +172,9 @@ /** Whether the execution of this method has been aborted */ private transient boolean aborted = false; + /** Whether the HTTP request has been transmitted to the target + * server it its entirety */ + private boolean requestSent = false; // ----------------------------------------------------------- Constructors /** @@ -971,9 +975,8 @@ this.effectiveVersion = this.params.getVersion(); } - boolean requestSent = false; writeRequest(state, conn); - requestSent = true; + this.requestSent = true; readResponse(state, conn); // the method has successfully executed used = true; @@ -1040,6 +1043,7 @@ connectionCloseForced = false; hostAuthState.invalidate(); proxyAuthState.invalidate(); + requestSent = false; } /** @@ -1897,7 +1901,7 @@ } else { return; } - } catch (IOTimeoutException e) { + } catch (InterruptedIOException e) { // Most probably Expect header is not recongnized // Remove the header to signal the method // that it's okay to go ahead with sending data @@ -2328,5 +2332,18 @@ */ public boolean isAborted() { return this.aborted; - } + } + + /** + * Returns true if the HTTP has been transmitted to the target + * server in its entirety, false otherwise. This flag can be useful + * for recovery logic. If the request has not been transmitted in its entirety, + * it is safe to retry the failed method. + * + * @return true if the request has been sent, false otherwise + */ + public boolean isRequestSent() { + return this.requestSent; + } + } Index: java/org/apache/commons/httpclient/HttpMethodDirector.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java,v retrieving revision 1.27 diff -u -r1.27 HttpMethodDirector.java --- java/org/apache/commons/httpclient/HttpMethodDirector.java 25 Jun 2004 03:34:56 -0000 1.27 +++ java/org/apache/commons/httpclient/HttpMethodDirector.java 2 Jul 2004 15:23:07 -0000 @@ -338,15 +338,11 @@ /** How many times did this transparently handle a recoverable exception? */ int recoverableExceptionCount = 0; int execCount = 0; - // TODO: how do we get requestSent? - boolean requestSent = false; - // loop until the method is successfully processed, the retryHandler // returns false or a non-recoverable exception is thrown try { while (true) { execCount++; - requestSent = false; if (LOG.isTraceEnabled()) { LOG.trace("Attempt number " + execCount + " to process request"); @@ -394,13 +390,7 @@ if (handler == null) { handler = new DefaultMethodRetryHandler(); } - if (!handler.retryMethod( - method, - this.conn, - httpre, - execCount, - requestSent) - ) { + if (!handler.retryMethod(method, this.conn, httpre, execCount)) { LOG.warn( "Recoverable exception caught but MethodRetryHandler.retryMethod() " + "returned false, rethrowing exception" Index: java/org/apache/commons/httpclient/HttpTimeoutException.java =================================================================== RCS file: java/org/apache/commons/httpclient/HttpTimeoutException.java diff -N java/org/apache/commons/httpclient/HttpTimeoutException.java --- java/org/apache/commons/httpclient/HttpTimeoutException.java 13 May 2004 04:03:25 -0000 1.5 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,70 +0,0 @@ -/* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpTimeoutException.java,v 1.5 2004/05/13 04:03:25 mbecke Exp $ - * $Revision: 1.5 $ - * $Date: 2004/05/13 04:03:25 $ - * - * ==================================================================== - * - * Copyright 1999-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package org.apache.commons.httpclient; - -/** - * A timeout while processing an HTTP request: for example a network - * timeout or a timeout while waiting for an HttpConnection to become - * available. - * - * @author Laura Werner - * - * @since 3.0 - */ -public class HttpTimeoutException extends HttpRecoverableException { - - /** - * Creates a new HttpTimeoutException with a null detail message. - */ - public HttpTimeoutException() { - super(); - } - - /** - * Creates a new HttpTimeoutException with the specified detail message. - * - * @param message The exception detail message - */ - public HttpTimeoutException(String message) { - super(message); - } - - /** - * Creates a new HttpTimeoutException with the specified detail message and cause. - * - * @param message the exception detail message - * @param cause the Throwable that caused this exception, or null - * if the cause is unavailable, unknown, or not a Throwable - */ - public HttpTimeoutException(String message, Throwable cause) { - super(message, cause); - } - -} Index: java/org/apache/commons/httpclient/IOTimeoutException.java =================================================================== RCS file: java/org/apache/commons/httpclient/IOTimeoutException.java diff -N java/org/apache/commons/httpclient/IOTimeoutException.java --- java/org/apache/commons/httpclient/IOTimeoutException.java 13 May 2004 04:03:25 -0000 1.4 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,68 +0,0 @@ -/* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/IOTimeoutException.java,v 1.4 2004/05/13 04:03:25 mbecke Exp $ - * $Revision: 1.4 $ - * $Date: 2004/05/13 04:03:25 $ - * - * ==================================================================== - * - * Copyright 1999-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package org.apache.commons.httpclient; - -/** - * A I/O or network timeout while communicating with an HTTP server. - * - * @author Laura Werner - * - * @since 3.0 - */ -public class IOTimeoutException extends HttpTimeoutException { - - /** - * Creates a IOTimeoutException with a null detail message. - */ - public IOTimeoutException() { - super(); - } - - /** - * Creates a IOTimeoutException with a specified message. - * - * @param message The exception detail message - */ - public IOTimeoutException(String message) { - super(message); - } - - /** - * Creates a new IOTimeoutException with the specified detail message and cause. - * - * @param message the exception detail message - * @param cause the Throwable that caused this exception, or null - * if the cause is unavailable, unknown, or not a Throwable - */ - public IOTimeoutException(String message, Throwable cause) { - super(message, cause); - } - -} Index: java/org/apache/commons/httpclient/MethodRetryHandler.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MethodRetryHandler.java,v retrieving revision 1.4 diff -u -r1.4 MethodRetryHandler.java --- java/org/apache/commons/httpclient/MethodRetryHandler.java 18 Apr 2004 23:51:35 -0000 1.4 +++ java/org/apache/commons/httpclient/MethodRetryHandler.java 2 Jul 2004 15:23:07 -0000 @@ -53,6 +53,10 @@ * * @return true if the method should be retried, false * otherwise + * + * @deprecated use #retryMethod(HttpMethod, HttpConnection, HttpRecoverableException, int) + * + * @see HttpMethod#isRequestSent */ boolean retryMethod( HttpMethod method, @@ -61,4 +65,22 @@ int executionCount, boolean requestSent); + /** + * Determines if a method should be retried after an HttpRecoverableException + * occurs during execution. + * + * @param method the method being executed + * @param connection the connection the method is using + * @param recoverableException the exception that occurred + * @param executionCount the number of times this method has been + * unsuccessfully executed + * + * @return true if the method should be retried, false + * otherwise + */ + boolean retryMethod( + HttpMethod method, + HttpConnection connection, + HttpRecoverableException recoverableException, + int executionCount); } Index: java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v retrieving revision 1.40 diff -u -r1.40 MultiThreadedHttpConnectionManager.java --- java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 25 Jun 2004 03:34:56 -0000 1.40 +++ java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 2 Jul 2004 15:23:11 -0000 @@ -356,7 +356,7 @@ while (true) { try { return getConnectionWithTimeout(hostConfiguration, 0); - } catch (ConnectTimeoutException e) { + } catch (ConnectionPoolTimeoutException e) { // we'll go ahead and log this, but it should never happen. HttpExceptions // are only thrown when the timeout occurs and since we have no timeout // it should never happen. @@ -374,7 +374,7 @@ * @since 3.0 */ public HttpConnection getConnectionWithTimeout(HostConfiguration hostConfiguration, - long timeout) throws ConnectTimeoutException { + long timeout) throws ConnectionPoolTimeoutException { LOG.trace("enter HttpConnectionManager.getConnectionWithTimeout(HostConfiguration, long)"); @@ -405,7 +405,7 @@ LOG.trace("enter HttpConnectionManager.getConnection(HostConfiguration, long)"); try { return getConnectionWithTimeout(hostConfiguration, timeout); - } catch(ConnectTimeoutException e) { + } catch(ConnectionPoolTimeoutException e) { throw new HttpException(e.getMessage()); } } @@ -426,7 +426,7 @@ * 'timeout' milliseconds */ private HttpConnection doGetConnection(HostConfiguration hostConfiguration, - long timeout) throws ConnectTimeoutException { + long timeout) throws ConnectionPoolTimeoutException { HttpConnection connection = null; @@ -487,7 +487,7 @@ try { if (useTimeout && timeToWait <= 0) { - throw new ConnectTimeoutException("Timeout waiting for connection"); + throw new ConnectionPoolTimeoutException("Timeout waiting for connection"); } if (LOG.isDebugEnabled()) { Index: test/org/apache/commons/httpclient/NoHostHttpConnectionManager.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/NoHostHttpConnectionManager.java,v retrieving revision 1.6 diff -u -r1.6 NoHostHttpConnectionManager.java --- test/org/apache/commons/httpclient/NoHostHttpConnectionManager.java 25 Apr 2004 21:49:35 -0000 1.6 +++ test/org/apache/commons/httpclient/NoHostHttpConnectionManager.java 2 Jul 2004 15:23:12 -0000 @@ -110,7 +110,7 @@ public HttpConnection getConnectionWithTimeout( HostConfiguration hostConfiguration, long timeout) - throws ConnectTimeoutException { + throws ConnectionPoolTimeoutException { return getConnection(hostConfiguration); } Index: test/org/apache/commons/httpclient/TestIdleConnectionTimeout.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestIdleConnectionTimeout.java,v retrieving revision 1.2 diff -u -r1.2 TestIdleConnectionTimeout.java --- test/org/apache/commons/httpclient/TestIdleConnectionTimeout.java 4 May 2004 21:24:51 -0000 1.2 +++ test/org/apache/commons/httpclient/TestIdleConnectionTimeout.java 2 Jul 2004 15:23:13 -0000 @@ -147,7 +147,7 @@ } public HttpConnection getConnectionWithTimeout(HostConfiguration hostConfiguration, - long timeout) throws ConnectTimeoutException { + long timeout) throws ConnectionPoolTimeoutException { return null; } Index: java/org/apache/commons/httpclient/ConnectionPoolTimeoutException.java =================================================================== RCS file: java/org/apache/commons/httpclient/ConnectionPoolTimeoutException.java diff -N java/org/apache/commons/httpclient/ConnectionPoolTimeoutException.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ java/org/apache/commons/httpclient/ConnectionPoolTimeoutException.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,69 @@ +/* + * $Header$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Copyright 1999-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.httpclient; + +/** + * A timeout while connecting waiting for an available connection + * from an HttpConnectionManager. + * + * @author Laura Werner + * + * @since 3.0 + */ +public class ConnectionPoolTimeoutException extends ConnectTimeoutException { + + /** + * Creates a ConnectTimeoutException with a null detail message. + */ + public ConnectionPoolTimeoutException() { + super(); + } + + /** + * Creates a ConnectTimeoutException with the specified detail message. + * + * @param message The exception detail message + */ + public ConnectionPoolTimeoutException(String message) { + super(message); + } + + /** + * Creates a new ConnectTimeoutException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public ConnectionPoolTimeoutException(String message, Throwable cause) { + super(message, cause); + } + +}