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.11 diff -u -r1.11 HttpMethodDirector.java --- java/org/apache/commons/httpclient/HttpMethodDirector.java 10 Dec 2003 21:04:13 -0000 1.11 +++ java/org/apache/commons/httpclient/HttpMethodDirector.java 11 Jan 2004 20:09:30 -0000 @@ -299,17 +299,17 @@ // loop until the method is successfully processed, the retryHandler // returns false or a non-recoverable exception is thrown - while (true) { - execCount++; - requestSent = false; + try { + while (true) { + execCount++; + requestSent = false; - if (LOG.isTraceEnabled()) { - LOG.trace("Attempt number " + execCount + " to process request"); - } - if (!this.conn.isOpen()) { - // this connection must be opened before it can be used - // This has nothing to do with opening a secure tunnel - try { + if (LOG.isTraceEnabled()) { + LOG.trace("Attempt number " + execCount + " to process request"); + } + if (!this.conn.isOpen()) { + // this connection must be opened before it can be used + // This has nothing to do with opening a secure tunnel this.conn.open(); if (this.conn.isProxied() && this.conn.isSecure() && !(method instanceof ConnectMethod)) { @@ -319,49 +319,52 @@ return; } } - } catch (IOException e) { - releaseConnection = true; - throw e; - } catch (RuntimeException e) { - releaseConnection = true; - throw e; } - } - try { - method.execute(state, this.conn); - break; - } catch (HttpRecoverableException httpre) { - if (LOG.isDebugEnabled()) { + try { + method.execute(state, this.conn); + break; + } catch (HttpRecoverableException httpre) { LOG.debug("Closing the connection."); - } - this.conn.close(); - LOG.info("Recoverable exception caught when processing request"); - // update the recoverable exception count. - recoverableExceptionCount++; + this.conn.close(); + LOG.info("Recoverable exception caught when processing request"); + // update the recoverable exception count. + recoverableExceptionCount++; - // test if this method should be retried - MethodRetryHandler handler = method.getMethodRetryHandler(); - if (handler == null) { - handler = new DefaultMethodRetryHandler(); - } - if (!handler.retryMethod( - method, - this.conn, - httpre, - execCount, - requestSent) - ) { - LOG.warn( - "Recoverable exception caught but MethodRetryHandler.retryMethod() " - + "returned false, rethrowing exception" - ); - // this connection can no longer be used, it has been closed - releaseConnection = true; - throw httpre; + // test if this method should be retried + MethodRetryHandler handler = method.getMethodRetryHandler(); + if (handler == null) { + handler = new DefaultMethodRetryHandler(); + } + if (!handler.retryMethod( + method, + this.conn, + httpre, + execCount, + requestSent) + ) { + LOG.warn( + "Recoverable exception caught but MethodRetryHandler.retryMethod() " + + "returned false, rethrowing exception" + ); + throw httpre; + } } } + } catch (IOException e) { + if (this.conn.isOpen()) { + LOG.debug("Closing the connection."); + this.conn.close(); + } + releaseConnection = true; + throw e; + } catch (RuntimeException e) { + if (this.conn.isOpen()) { + LOG.debug("Closing the connection."); + this.conn.close(); + } + releaseConnection = true; + throw e; } - } /** Index: test/org/apache/commons/httpclient/TestHttpConnectionManager.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v retrieving revision 1.15 diff -u -r1.15 TestHttpConnectionManager.java --- test/org/apache/commons/httpclient/TestHttpConnectionManager.java 6 Jan 2004 20:08:56 -0000 1.15 +++ test/org/apache/commons/httpclient/TestHttpConnectionManager.java 11 Jan 2004 20:09:35 -0000 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v 1.15 2004/01/06 20:08:56 olegk Exp $ + * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v 1.15 2004/01/06 20:08:56 olegk Exp $ * $Revision: 1.15 $ * $Date: 2004/01/06 20:08:56 $ * ==================================================================== @@ -246,6 +246,40 @@ Object connectionManager = wr.get(); assertNull("connectionManager should be null", connectionManager); } + + public void testWriteRequestReleaseConnection() { + + MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); + connectionManager.getParams().setIntParameter( + HttpConnectionManagerParams.MAX_HOST_CONNECTIONS, 1); + + HttpClient client = createHttpClient(connectionManager); + + GetMethod get = new GetMethod("/") { + protected boolean writeRequestBody(HttpState state, HttpConnection conn) + throws IOException, HttpException { + throw new IOException("Oh no!!"); + } + }; + + try { + client.executeMethod(get); + fail("An exception should have occurred."); + } catch (HttpException e) { + e.printStackTrace(); + fail("HttpException should not have occurred: " + e); + } catch (IOException e) { + // expected + } + + try { + connectionManager.getConnectionWithTimeout(client.getHostConfiguration(), 1); + } catch (ConnectTimeoutException e) { + e.printStackTrace(); + fail("Connection was not released: " + e); + } + + } public void testReleaseConnection() {