diff --git a/pkgs/http/CHANGELOG.md b/pkgs/http/CHANGELOG.md index 5ff32e430f..8b56ac48d5 100644 --- a/pkgs/http/CHANGELOG.md +++ b/pkgs/http/CHANGELOG.md @@ -8,6 +8,11 @@ * Preserve header cases in `IOClient`. * Fix a [bug](https://github.com/dart-lang/http/issues/1934) to release the underlying connection when an `AbortableRequest` is aborted before its body is read. +* Stop `IOClient` from sending bodyless GET/HEAD requests with + `Transfer-Encoding: chunked` when `BaseRequest.contentLength` is `null`; + `dart:io`'s per-method default framing is used instead. A GET or HEAD request + that streams a non-empty body while leaving `contentLength` `null` now throws + instead of being sent chunked. ## 1.6.0 diff --git a/pkgs/http/lib/src/io_client.dart b/pkgs/http/lib/src/io_client.dart index a00ef9dd03..dc32f23b83 100644 --- a/pkgs/http/lib/src/io_client.dart +++ b/pkgs/http/lib/src/io_client.dart @@ -114,8 +114,10 @@ class IOClient extends BaseClient { var ioRequest = (await _inner!.openUrl(request.method, request.url)) ..followRedirects = request.followRedirects ..maxRedirects = request.maxRedirects - ..contentLength = (request.contentLength ?? -1) ..persistentConnection = request.persistentConnection; + if (request.contentLength case final contentLength?) { + ioRequest.contentLength = contentLength; + } request.headers.forEach((name, value) { ioRequest.headers.set(name, value, preserveHeaderCase: true); }); diff --git a/pkgs/http/test/io/streamed_request_test.dart b/pkgs/http/test/io/streamed_request_test.dart index f0e990c767..c39437c2bc 100644 --- a/pkgs/http/test/io/streamed_request_test.dart +++ b/pkgs/http/test/io/streamed_request_test.dart @@ -40,6 +40,19 @@ void main() { expect(await utf8.decodeStream(response.stream), parse(containsPair('headers', isNot(contains('content-length'))))); }); + + test('defaults to sending a bodyless GET without framing headers', + () async { + var request = http.StreamedRequest('GET', serverUrl); + unawaited(request.sink.close()); + var response = await request.send(); + expect( + await utf8.decodeStream(response.stream), + parse(containsPair( + 'headers', + allOf(isNot(contains('transfer-encoding')), + isNot(contains('content-length')))))); + }); }); // Regression test.