Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8195457 | 11 | Chris Hegarty | P2 | Resolved | Fixed | b01 |
JDK-8197618 | 10u-cpu | Chris Hegarty | P2 | Resolved | Fixed | master |
JDK-8200828 | 10.0.2 | Unassigned | P2 | Resolved | Fixed | b01 |
JDK-8195893 | 10.0.1 | Chris Hegarty | P2 | Resolved | Fixed | b01 |
Push promises should be implicitly cancelled/rejected by the HTTP Client implementation when a client-initiated request does not provide a handler for push promises, rather than causing the initiating-request to fail.
The follow demonstrates the issue when getting a resource from an HTTP/2 server that issues a push promise for that resource:
$ cat Get.java
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.util.function.UnaryOperator;
import jdk.incubator.http.HttpClient;
import jdk.incubator.http.HttpRequest;
import jdk.incubator.http.HttpResponse;
class Get {
static final UnaryOperator<HttpResponse<?>> assert200ResponseCode = (response) -> {
System.out.println(response);
return response;
};
public static void main(String... args) {
HttpClient.newHttpClient()
.sendAsync(HttpRequest.newBuilder(URI.create(args[0])).build(), HttpResponse.BodyHandler.asString())
.thenApply(assert200ResponseCode)
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}
$/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
$ /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java --add-modules jdk.incubator.httpclient Get https://http2-server-push-demo.keksi.io/
WARNING: Using incubator modules: jdk.incubator.httpclient
Exception in thread "main" java.util.concurrent.CompletionException: java.lang.ClassCastException: jdk.incubator.httpclient/jdk.incubator.http.SSLTunnelConnection cannot be cast to jdk.incubator.httpclient/jdk.incubator.http.AsyncConnection
at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314)
at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1081)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1705)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.ClassCastException: jdk.incubator.httpclient/jdk.incubator.http.SSLTunnelConnection cannot be cast to jdk.incubator.httpclient/jdk.incubator.http.AsyncConnection
at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.<init>(Http2Connection.java:270)
at jdk.incubator.httpclient/jdk.incubator.http.Http2ClientImpl.getConnectionFor(Http2ClientImpl.java:108)
at jdk.incubator.httpclient/jdk.incubator.http.ExchangeImpl.get(ExchangeImpl.java:86)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.establishExchange(Exchange.java:257)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseAsyncImpl0(Exchange.java:331)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseAsyncImpl(Exchange.java:325)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseAsync(Exchange.java:310)
at jdk.incubator.httpclient/jdk.incubator.http.MultiExchange.responseAsyncImpl(MultiExchange.java:295)
at jdk.incubator.httpclient/jdk.incubator.http.MultiExchange.lambda$responseAsync0$1(MultiExchange.java:250)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072)
... 5 more
The follow demonstrates the issue when getting a resource from an HTTP/2 server that issues a push promise for that resource:
$ cat Get.java
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.util.function.UnaryOperator;
import jdk.incubator.http.HttpClient;
import jdk.incubator.http.HttpRequest;
import jdk.incubator.http.HttpResponse;
class Get {
static final UnaryOperator<HttpResponse<?>> assert200ResponseCode = (response) -> {
System.out.println(response);
return response;
};
public static void main(String... args) {
HttpClient.newHttpClient()
.sendAsync(HttpRequest.newBuilder(URI.create(args[0])).build(), HttpResponse.BodyHandler.asString())
.thenApply(assert200ResponseCode)
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}
$/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
$ /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java --add-modules jdk.incubator.httpclient Get https://http2-server-push-demo.keksi.io/
WARNING: Using incubator modules: jdk.incubator.httpclient
Exception in thread "main" java.util.concurrent.CompletionException: java.lang.ClassCastException: jdk.incubator.httpclient/jdk.incubator.http.SSLTunnelConnection cannot be cast to jdk.incubator.httpclient/jdk.incubator.http.AsyncConnection
at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314)
at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1081)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1705)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.ClassCastException: jdk.incubator.httpclient/jdk.incubator.http.SSLTunnelConnection cannot be cast to jdk.incubator.httpclient/jdk.incubator.http.AsyncConnection
at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.<init>(Http2Connection.java:270)
at jdk.incubator.httpclient/jdk.incubator.http.Http2ClientImpl.getConnectionFor(Http2ClientImpl.java:108)
at jdk.incubator.httpclient/jdk.incubator.http.ExchangeImpl.get(ExchangeImpl.java:86)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.establishExchange(Exchange.java:257)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseAsyncImpl0(Exchange.java:331)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseAsyncImpl(Exchange.java:325)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseAsync(Exchange.java:310)
at jdk.incubator.httpclient/jdk.incubator.http.MultiExchange.responseAsyncImpl(MultiExchange.java:295)
at jdk.incubator.httpclient/jdk.incubator.http.MultiExchange.lambda$responseAsync0$1(MultiExchange.java:250)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072)
... 5 more
- backported by
-
JDK-8195457 Unhandleable Push Promises should be cancelled
- Resolved
-
JDK-8195893 Unhandleable Push Promises should be cancelled
- Resolved
-
JDK-8197618 Unhandleable Push Promises should be cancelled
- Resolved
-
JDK-8200828 Unhandleable Push Promises should be cancelled
- Resolved