RFR: 8371903: HttpClient: improve handling of HTTP/2 GOAWAY frames with error code [v2]
Daniel Jeliński
djelinski at openjdk.org
Thu Dec 4 12:13:03 UTC 2025
On Thu, 4 Dec 2025 10:50:53 GMT, EunHyunsu <duke at openjdk.org> wrote:
>> ### Problem
>>
>> When the HTTP/2 client receives a GOAWAY frame with a non-zero error code, the current implementation discards both the error code and debug data. Users only see generic "Connection closed by peer" errors without any information about why the server terminated the connection.
>>
>> ### Solution
>>
>> Per [RFC 9113 §5.4.1](https://www.rfc-editor.org/rfc/rfc9113.html#section-5.4.1), a GOAWAY frame with a non-zero error code indicates a connection error requiring immediate closure. This fix:
>>
>> 1. **Distinguishes** graceful shutdown (NO_ERROR) from connection errors
>> 2. **Preserves** error code and debug data in exception messages
>> 3. **Categorizes** streams based on `lastStreamId`:
>> - Streams with ID > `lastStreamId`: Marked as unprocessed for automatic retry
>> - Streams with ID ≤ `lastStreamId`: Failed with detailed error information
>>
>> ### Changes
>>
>> **Core Implementation** (`Http2Connection.java`):
>> - Modified `handleGoAway()` to check error code and route appropriately
>> - Added `handleGoAwayWithError()` method that:
>> - Extracts error code and debug data from GOAWAY frame
>> - Creates meaningful error messages with error name, hex code, and debug data
>> - Properly categorizes streams for retry or failure
>>
>> **Test Infrastructure**:
>> - `Http2TestServerConnection.sendGoAway(int, int, byte[])`: Supports custom error codes
>> - `Http2TestExchangeImpl.getServerConnection()`: Accessor for test handlers
>> - `GoAwayWithErrorTest`: Verifies proper error propagation
>>
>> ### Example
>>
>> **Before:**
>> IOException: Connection closed by peer
>>
>> **After:**
>> IOException: Received GOAWAY with error code Protocol error (0x1): Invalid HEADERS frame
>>
>> ### Testing
>>
>> - New `GoAwayWithErrorTest` passes
>> - Existing HTTP/2 tests unaffected (NO_ERROR path unchanged)
>> - Backward compatible (no public API changes)
>
> EunHyunsu has updated the pull request incrementally with one additional commit since the last revision:
>
> 8371903: HTTP/2 client should preserve error information from GOAWAY frames
>
> Extracts error code and debug data from GOAWAY frames with non-zero
> error codes and includes them in exception messages. Streams above
> lastStreamId are marked as unprocessed for retry; others fail with
> the error details.
I'd really like to see some retried requests in the test. Please:
- change the requests to POST; idempotent requests like GET might be retried for other reasons, POST is only retried when unprocessed,
- send all 3 requests at once, so that there's at least a chance that they will be in progress when GOAWAY is sent,
- check that exactly one request fails. It doesn't have to be the first one, the client sometimes reorders the requests internally.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/28632#issuecomment-3611930254
More information about the net-dev
mailing list