Kestrel enforces non-default HTTP/2 limits before the Settings ack
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
At the start of a h2 connection the client and server advertise their non-default settings to each other. However, the client can start sending requests before it receives the settings. The server is supposed to assume default settings until the client ack's the settings (with a timeout), but Kestrel does not, it assumes its own initial settings.
Kestrel has two settings it sets to lower than the default, SETTINGS_MAX_HEADER_LIST_SIZE and SETTINGS_MAX_CONCURRENT_STREAMS. The trouble with both of these settings is that the spec default is infinite, allowing infinite for either would be untenable, even for a short period of time.
The good thing about SETTINGS_MAX_CONCURRENT_STREAMS is that they're rejected with REFUSE_STREAM, meaning they're explicitly re-tryable, and HttpClient does retry them. The resets don't arrive until after the settings frame, so the retry will always happen with knowledge of the expected settings. The stream limit issue also contributes to https://github.com/aspnet/AspNetCore/issues/17484.
SETTINGS_MAX_HEADER_LIST_SIZE is less of a concern because the request is going to fail whether the client knows about the limit or not, there's no automated way to make the request smaller.
Having now written this up, I don't think kestrel has any alternatives in these scenarios. Temporary infinite limits are untenable and a client could run into the same issues even if we used more forgiving temporary non-infinite limits.
Contributor guide
Assessment
This issue has not been assessed yet.