HTTPCLIENT-1311: made sure the current thread is re-interrupted if InterruptedException is caught and re-thrown as a different exception; tweaked connection manager API related to interruptable operations

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1441414 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2013-02-01 12:06:33 +00:00
parent 882dd890f1
commit f6f1d7af49
9 changed files with 32 additions and 18 deletions

View File

@ -1,6 +1,9 @@
Changes since 4.3 ALPHA1
-------------------
* [HTTPCLIENT-1311] Interrupt flag is not preserved where InterruptedException is caught.
Contributed by Oleg Kalnichevski <olegk at apache.org>
* [HTTPCLIENT-1312] Zero length content entities with a Content-Encoding header cause
an I/O error when an attempt is made to consume such entity.
Contributed by Oleg Kalnichevski <olegk at apache.org>

View File

@ -27,6 +27,7 @@
package org.apache.http.conn;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.http.HttpClientConnection;
@ -63,6 +64,6 @@ public interface ConnectionRequest extends Cancellable {
* if the calling thread is interrupted while waiting
*/
HttpClientConnection get(long timeout, TimeUnit tunit)
throws InterruptedException, ConnectionPoolTimeoutException;
throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException;
}

View File

@ -162,7 +162,8 @@ public class AutoRetryHttpClient implements HttpClient {
log.trace("Wait for " + nextInterval);
Thread.sleep(nextInterval);
} catch (final InterruptedException e) {
throw new InterruptedIOException(e.getMessage());
Thread.currentThread().interrupt();
throw new InterruptedIOException();
}
} else {
return response;

View File

@ -420,9 +420,8 @@ public class DefaultRequestDirector implements RequestDirector {
try {
managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS);
} catch(final InterruptedException interrupted) {
final InterruptedIOException iox = new InterruptedIOException();
iox.initCause(interrupted);
throw iox;
Thread.currentThread().interrupt();
throw new InterruptedIOException();
}
if (HttpConnectionParams.isStaleCheckingEnabled(params)) {

View File

@ -223,7 +223,7 @@ public class PoolingHttpClientConnectionManager
public HttpClientConnection get(
final long timeout,
final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException {
final TimeUnit tunit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException {
return leaseConnection(future, timeout, tunit);
}
@ -234,7 +234,7 @@ public class PoolingHttpClientConnectionManager
protected HttpClientConnection leaseConnection(
final Future<CPoolEntry> future,
final long timeout,
final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException {
final TimeUnit tunit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException {
CPoolEntry entry;
try {
entry = future.get(timeout, tunit);
@ -246,14 +246,6 @@ public class PoolingHttpClientConnectionManager
this.log.debug("Connection leased: " + format(entry) + formatStats(entry.getRoute()));
}
return CPoolProxy.newProxy(entry);
} catch (final ExecutionException ex) {
Throwable cause = ex.getCause();
if (cause == null) {
cause = ex;
}
final InterruptedException intex = new InterruptedException();
intex.initCause(cause);
throw intex;
} catch (final TimeoutException ex) {
throw new ConnectionPoolTimeoutException("Timeout waiting for connection from pool");
}

View File

@ -29,6 +29,7 @@ package org.apache.http.impl.execchain;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
@ -167,7 +168,14 @@ public class MainClientExec implements ClientExecChain {
final int timeout = config.getConnectionRequestTimeout();
managedConn = connRequest.get(timeout > 0 ? timeout : 0, TimeUnit.MILLISECONDS);
} catch(final InterruptedException interrupted) {
Thread.currentThread().interrupt();
throw new RequestAbortedException("Request aborted", interrupted);
} catch(final ExecutionException ex) {
Throwable cause = ex.getCause();
if (cause == null) {
cause = ex;
}
throw new RequestAbortedException("Request execution failed", cause);
}
context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn);

View File

@ -30,6 +30,7 @@ package org.apache.http.impl.execchain;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.URI;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
@ -128,7 +129,14 @@ public class MinimalClientExec implements ClientExecChain {
final int timeout = config.getConnectionRequestTimeout();
managedConn = connRequest.get(timeout > 0 ? timeout : 0, TimeUnit.MILLISECONDS);
} catch(final InterruptedException interrupted) {
Thread.currentThread().interrupt();
throw new RequestAbortedException("Request aborted", interrupted);
} catch(final ExecutionException ex) {
Throwable cause = ex.getCause();
if (cause == null) {
cause = ex;
}
throw new RequestAbortedException("Request execution failed", cause);
}
final ConnectionHolder releaseTrigger = new ConnectionHolder(log, connManager, managedConn);

View File

@ -82,7 +82,8 @@ public class ServiceUnavailableRetryExec implements ClientExecChain {
this.log.trace("Wait for " + nextInterval);
Thread.sleep(nextInterval);
} catch (final InterruptedException e) {
throw new InterruptedIOException(e.getMessage());
Thread.currentThread().interrupt();
throw new InterruptedIOException();
}
} else {
return response;

View File

@ -32,6 +32,7 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@ -82,14 +83,14 @@ public class TestConnectionManagement extends LocalServerTestBase {
final HttpClientConnectionManager mgr,
final HttpRoute route,
final long timeout,
final TimeUnit unit) throws ConnectionPoolTimeoutException, InterruptedException {
final TimeUnit unit) throws ConnectionPoolTimeoutException, ExecutionException, InterruptedException {
final ConnectionRequest connRequest = mgr.requestConnection(route, null);
return connRequest.get(timeout, unit);
}
private static HttpClientConnection getConnection(
final HttpClientConnectionManager mgr,
final HttpRoute route) throws ConnectionPoolTimeoutException, InterruptedException {
final HttpRoute route) throws ConnectionPoolTimeoutException, ExecutionException, InterruptedException {
final ConnectionRequest connRequest = mgr.requestConnection(route, null);
return connRequest.get(0, null);
}