< prev index next >
src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java
Print this page
@@ -81,10 +81,14 @@
final Executor parentExecutor;
boolean upgrading; // to HTTP/2
final PushGroup<T> pushGroup;
final String dbgTag;
+ // Keeps track of the underlying connection when establishing an HTTP/2
+ // exchange so that it can be aborted/timed out mid setup.
+ final ConnectionAborter connectionAborter = new ConnectionAborter();
+
Exchange(HttpRequestImpl request, MultiExchange<T> multi) {
this.request = request;
this.upgrading = false;
this.client = multi.client();
this.multi = multi;
@@ -123,10 +127,31 @@
HttpClientImpl client() {
return client;
}
+ // Keeps track of the underlying connection when establishing an HTTP/2
+ // exchange so that it can be aborted/timed out mid setup.
+ static final class ConnectionAborter {
+ private volatile HttpConnection connection;
+
+ void connection(HttpConnection connection) {
+ this.connection = connection;
+ }
+
+ void closeConnection() {
+ HttpConnection connection = this.connection;
+ this.connection = null;
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+ }
+ }
public CompletableFuture<T> readBodyAsync(HttpResponse.BodyHandler<T> handler) {
// If we received a 407 while establishing the exchange
// there will be no body to read: bodyIgnored will be true,
// and exchImpl will be null (if we were trying to establish
@@ -177,10 +202,11 @@
cancel(new IOException("Request cancelled"));
}
}
public void cancel(IOException cause) {
+ if (debug.on()) debug.log("cancel exchImpl: %s, with \"%s\"", exchImpl, cause);
// If the impl is non null, propagate the exception right away.
// Otherwise record it so that it can be propagated once the
// exchange impl has been established.
ExchangeImpl<?> impl = exchImpl;
if (impl != null) {
@@ -188,10 +214,15 @@
if (debug.on()) debug.log("Cancelling exchImpl: %s", exchImpl);
impl.cancel(cause);
} else {
// no impl yet. record the exception
failed = cause;
+
+ // abort/close the connection if setting up the exchange. This can
+ // be important when setting up HTTP/2
+ connectionAborter.closeConnection();
+
// now call checkCancelled to recheck the impl.
// if the failed state is set and the impl is not null, reset
// the failed state and propagate the exception to the impl.
checkCancelled();
}
< prev index next >