RFR: 8263031: HttpClient throws Exception if it receives a Push Promise that is too large

Conor Cleary ccleary at openjdk.java.net
Fri Mar 4 14:52:32 UTC 2022


**Problem**
When a Continuation Frame is received by the httpclient using HTTP/2 after a Push Promise frame (can happen if the amount of headers to be sent in a single Push Promise frame exceeds the maximum frame size, so a Continuation frame is required), the following exception occurs:


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)
...

This exception occurs because there is no existing flow in `jdk/internal/net/http/Http2Connection.java` which accounts for the case where a PushPromiseFrame is received with the END_HEADERS flag set to 0x0. When this occurs, the only acceptable frame/s (as multiple continuations are also acceptable) that can be received by the client on the same stream is a continuation frame.

**Fix**
To ensure correct behavior, the following changes were made to `jdk/internal/net/http/Http2Connection.java`.

- The existing method `handlePushPromise()` was modified so that if the END_HEADERS flag is _unset_ (flags equal to 0x0), then a record used to track the state of the Push Promise containing a shared `HeaderDecoder` and the received `PushPromiseFrame` is initialised.
- When the subsequent `ContinuationFrame` is received in `processFrame()`, the method `handlePushContinuation()` is called instead of the default flow resulting in `stream.incoming(frame)` being called (the source of the incorrect behaviour originally).
- In `handlePushContinuation()`, the shared decoder is used to decode the received `ContinuationFrame` headers and if the `END_HEADERS` flag is set (flags equal to 0x4), the `HttpHeaders` object for the Push Promise as a whole is constructed which serves to combine the headers from both the `PushPromiseFrame` and the `ContinuationFrame`.

-------------

Commit messages:
 - 8263031: Created new flow for Push Promises followed by Continuations
 - 8263031: Setting END_HEADERS flag where appropriate
 - 8263031: Update test name and cleanup
 - 8263031: HttpClient throws Exception if it receives a Push Promise that is too large

Changes: https://git.openjdk.java.net/jdk/pull/7696/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=7696&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8263031
  Stats: 423 lines in 4 files changed: 336 ins; 67 del; 20 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7696.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7696/head:pull/7696

PR: https://git.openjdk.java.net/jdk/pull/7696


More information about the net-dev mailing list