-
Bug
-
Resolution: Fixed
-
P4
-
11, 17
-
b18
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8342313 | 17.0.14 | Martin Balao Alonso | P4 | Resolved | Fixed | b01 |
JDK-8342250 | 17.0.13 | Martin Balao Alonso | P4 | Resolved | Fixed | b11 |
JDK-8342349 | 11.0.26 | Alexey Bakhtin | P4 | Resolved | Fixed | b01 |
JDK-8342263 | 11.0.25 | Alexey Bakhtin | P4 | Resolved | Fixed | b09 |
ADDITIONAL SYSTEM INFORMATION :
Version: openjdk 11.0.9.1 2020-11-04
A DESCRIPTION OF THE PROBLEM :
Whenever HttpClient.send() sends a request to a Webservice that returns a Push Promise that exceeds the size of a single Push Promise Frame (Push Promise Frame + Continuation frames, for example because it adds a lot of headers to the Push Promise) the following Exception is thrown by the HttpClient (even if handling of Push Promises is not enabled):
java.io.IOException: no statuscode in response
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:565)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119)
at matthias.test.MinimalTest.clientTest(MinimalTest.java:237)
at matthias.test.MinimalTest.httpClientFailsWhenTooManyHeadersInPushPromise(MinimalTest.java:252)
at matthias.test.MinimalTest.main(MinimalTest.java:276)
Caused by: java.io.IOException: no statuscode in response
at java.net.http/jdk.internal.net.http.Stream.lambda$handleResponse$4(Stream.java:442)
at java.base/java.util.OptionalLong.orElseThrow(OptionalLong.java:271)
at java.net.http/jdk.internal.net.http.Stream.handleResponse(Stream.java:442)
at java.net.http/jdk.internal.net.http.Stream.incoming(Stream.java:402)
at java.net.http/jdk.internal.net.http.Http2Connection.processFrame(Http2Connection.java:785)
at java.net.http/jdk.internal.net.http.frame.FramesDecoder.decode(FramesDecoder.java:155)
at java.net.http/jdk.internal.net.http.Http2Connection$FramesController.processReceivedData(Http2Connection.java:232)
at java.net.http/jdk.internal.net.http.Http2Connection.asyncReceive(Http2Connection.java:649)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.processQueue(Http2Connection.java:1275)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.runOrSchedule(Http2Connection.java:1293)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1319)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1253)
at java.net.http/jdk.internal.net.http.common.SSLTube$DelegateWrapper.onNext(SSLTube.java:202)
at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:484)
at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:287)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:318)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:261)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:234)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:200)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:403)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:264)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use HttpClient to send a request to a Webservice that returns a large push promise.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A HttpResponse is received.
ACTUAL -
'java.io.IOException: no statuscode in response' is thrown
---------- BEGIN SOURCE ----------
A simple Servlet running on Tomcat9:
@WebServlet("/serverpush1")
public class Http2TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
PushBuilder pushBuilder = req.newPushBuilder();
for(int i=0; i<=100; i++) {
pushBuilder.addHeader("x-additionalHeader"+i, "headervalue"+i);
}
pushBuilder
.path("resources/images/tile-0.png")
.push();
try(PrintWriter respWriter = resp.getWriter();){
respWriter.write("<html>" +
"<img src='resources/images/tile-0.png'>" +
"</html>");
}
}
}
A simple client that connects to it:
URI target = URI.create("https://localhost:9443/serverpush1");
HttpRequest httpRequest = HttpRequest.newBuilder().uri(target).build();
HttpClient httpClient = HttpClient.newBuilder().version(Version.HTTP_2).build();
try {
HttpResponse<String> response = httpClient.send(httpRequest, BodyHandlers.ofString());
System.out.println(response.body());
} catch(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
---------- END SOURCE ----------
FREQUENCY : always
Version: openjdk 11.0.9.1 2020-11-04
A DESCRIPTION OF THE PROBLEM :
Whenever HttpClient.send() sends a request to a Webservice that returns a Push Promise that exceeds the size of a single Push Promise Frame (Push Promise Frame + Continuation frames, for example because it adds a lot of headers to the Push Promise) the following Exception is thrown by the HttpClient (even if handling of Push Promises is not enabled):
java.io.IOException: no statuscode in response
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:565)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119)
at matthias.test.MinimalTest.clientTest(MinimalTest.java:237)
at matthias.test.MinimalTest.httpClientFailsWhenTooManyHeadersInPushPromise(MinimalTest.java:252)
at matthias.test.MinimalTest.main(MinimalTest.java:276)
Caused by: java.io.IOException: no statuscode in response
at java.net.http/jdk.internal.net.http.Stream.lambda$handleResponse$4(Stream.java:442)
at java.base/java.util.OptionalLong.orElseThrow(OptionalLong.java:271)
at java.net.http/jdk.internal.net.http.Stream.handleResponse(Stream.java:442)
at java.net.http/jdk.internal.net.http.Stream.incoming(Stream.java:402)
at java.net.http/jdk.internal.net.http.Http2Connection.processFrame(Http2Connection.java:785)
at java.net.http/jdk.internal.net.http.frame.FramesDecoder.decode(FramesDecoder.java:155)
at java.net.http/jdk.internal.net.http.Http2Connection$FramesController.processReceivedData(Http2Connection.java:232)
at java.net.http/jdk.internal.net.http.Http2Connection.asyncReceive(Http2Connection.java:649)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.processQueue(Http2Connection.java:1275)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.runOrSchedule(Http2Connection.java:1293)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1319)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1253)
at java.net.http/jdk.internal.net.http.common.SSLTube$DelegateWrapper.onNext(SSLTube.java:202)
at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:484)
at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:287)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:318)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:261)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:234)
at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:200)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:403)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:264)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use HttpClient to send a request to a Webservice that returns a large push promise.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A HttpResponse is received.
ACTUAL -
'java.io.IOException: no statuscode in response' is thrown
---------- BEGIN SOURCE ----------
A simple Servlet running on Tomcat9:
@WebServlet("/serverpush1")
public class Http2TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
PushBuilder pushBuilder = req.newPushBuilder();
for(int i=0; i<=100; i++) {
pushBuilder.addHeader("x-additionalHeader"+i, "headervalue"+i);
}
pushBuilder
.path("resources/images/tile-0.png")
.push();
try(PrintWriter respWriter = resp.getWriter();){
respWriter.write("<html>" +
"<img src='resources/images/tile-0.png'>" +
"</html>");
}
}
}
A simple client that connects to it:
URI target = URI.create("https://localhost:9443/serverpush1");
HttpRequest httpRequest = HttpRequest.newBuilder().uri(target).build();
HttpClient httpClient = HttpClient.newBuilder().version(Version.HTTP_2).build();
try {
HttpResponse<String> response = httpClient.send(httpRequest, BodyHandlers.ofString());
System.out.println(response.body());
} catch(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
---------- END SOURCE ----------
FREQUENCY : always
- backported by
-
JDK-8342250 HttpClient throws Exception if it receives a Push Promise that is too large
- Resolved
-
JDK-8342263 HttpClient throws Exception if it receives a Push Promise that is too large
- Resolved
-
JDK-8342313 HttpClient throws Exception if it receives a Push Promise that is too large
- Resolved
-
JDK-8342349 HttpClient throws Exception if it receives a Push Promise that is too large
- Resolved
- links to
-
Commit openjdk/jdk/4d2cd26a
-
Review openjdk/jdk/7696
-
Review(master) openjdk/jdk17u/400
(2 links to)