feat(http2): configurable receive windows and frame size (#1999) * feat(http2): configurable client receive windows and frame size A client built on package:http2 moved at most 64 KiB per round trip: the connection receive window is fixed at the protocol's 65535 bytes, so streamWindowSize alone cannot raise throughput. With a 4 MiB body from a Go net/http server through 100 ms of added RTT, HTTP/1.1 (dart:io HttpClient) took about 350 ms and this package 7.1 s. - Settings.connectionWindowSize grants a larger connection window with a WINDOW_UPDATE on stream 0 after the initial SETTINGS. - Settings.maxFrameSize is sent as SETTINGS_MAX_FRAME_SIZE. - The initial streamWindowSize and maxFrameSize apply to this end's receive side from the moment they are sent: no stream exists yet and the peer reads the SETTINGS before any stream. Waiting for the ACK let a large frame on an early stream fail flow control, and capped every early response's first round trip at 64 KiB. - Above the default 65535-byte window, received data is acknowledged once per half window rather than once per DATA frame (the existing TODO in IncomingWindowHandler.dataProcessed); a default-sized window is still acknowledged at once. - The new settings are validated up front with the others. Defaults are unchanged. With streamWindowSize 6 MiB, connectionWindowSize 16 MiB and maxFrameSize 1 MiB, the same transfer takes about 340 ms (140 ms without added delay, against 155 ms for HTTP/1.1). test/flow_control_test.dart checks each behaviour frame by frame against a hand-driven peer; each test fails with its part removed. * fix(http2): address review on configurable receive windows - SettingsHandler applies the peer's SETTINGS_MAX_FRAME_SIZE, so frames sent to it use its limit, and rejects a value outside 16384..16777215 as a PROTOCOL_ERROR (RFC 9113 section 6.5.2). - The ACK of this end's own SETTINGS_INITIAL_WINDOW_SIZE no longer emits onInitialWindowSizeChange: only the peer's value sizes the send windows of open streams (RFC 9113 section 6.9.2). - connectionWindowSize must be at least 65535, the connection window's starting size; a smaller value was silently ignored. - IncomingWindowHandler.dataProcessed ignores 0 bytes, so an empty DATA frame never yields a WINDOW_UPDATE with an increment of 0 (RFC 9113 section 6.9). * fix(http2): pre-apply only a larger stream window; second review round - _setupConnection pre-applies streamWindowSize only when it does not shrink the window. A client may send on a stream before it has read the server's SETTINGS (RFC 9113 section 3.4), within the default 65535 bytes (section 6.9.2); a server with a smaller window pre-applied tore such a connection down with FLOW_CONTROL_ERROR. A smaller window applies on ACK, as on master. Regression test from the review in flow_control_test.dart. - WINDOW_UPDATEs are batched from twice the default window, so a window just above 65535 is no longer acknowledged less often than the default. - flow_control_test.dart checks that a frame was not sent after a PING round trip instead of a wall-clock sleep. - CHANGELOG condensed to the package's style. * test(http2): the ACK test exercises the peerSettings guard With a window above 65535 the pre-application already makes the ACK's difference 0, so the test passed without the guard. It now uses a window below 65535, which is not pre-applied, and checks that a further stream WINDOW_UPDATE is fully usable after the ACK (fails without the guard: 66535 sent instead of 131070). Doc on streamWindowSize: batching starts from 2 * 65535, inclusive.
A composable, Future-based library for making HTTP requests.
package:http contains a set of high-level functions and classes that make it easy to consume HTTP resources. It's multi-platform, and supports mobile, desktop, and the browser.
| Package | Description | Version |
|---|---|---|
| cronet_http | An Android Flutter plugin that provides access to the Cronet HTTP client. | |
| cupertino_http | A macOS/iOS Flutter plugin that provides access to the Foundation URL Loading System. | |
| flutter_http_example | An Flutter app that demonstrates how to configure and use package:http. | — |
| http | A composable, multi-platform, Future-based API for HTTP requests. | |
| http2 | A HTTP/2 implementation in Dart. | |
| http_client_conformance_tests | A library that tests whether implementations of package:http's Client class behave as expected. | |
| http_multi_server | A dart:io HttpServer wrapper that handles requests from multiple servers. | |
| http_parser | A platform-independent package for parsing and serializing HTTP formats. | |
| http_profile | A library used by HTTP client authors to integrate with the DevTools Network View. | |
| ok_http | An Android Flutter plugin that provides access to the OkHttp HTTP client and the OkHttp WebSocket API. | |
| web_socket | Any easy-to-use library for communicating with WebSockets that has multiple implementations. | |
| web_socket_channel | StreamChannel wrappers for WebSockets. Provides a cross-platform WebSocketChannel API. | |
| web_socket_conformance_tests | A library that tests whether implementations of package:web_socket's WebSocket class behave as expected. |
If you'd like to contribute to any of these packages, see the Contributing Guide.