Make StreameRequest.sink a StreamSink (#965)
Closes #727
This class was not designed for extension, but there is at least one
extending implementation. I don't see any overrides of this field, so no
existing usage should be broken.
Some new lints may surface for unawaited futures - the returned futures
should not be awaited.
diff --git a/pkgs/http/CHANGELOG.md b/pkgs/http/CHANGELOG.md
index 29d7761..a23d4c9 100644
--- a/pkgs/http/CHANGELOG.md
+++ b/pkgs/http/CHANGELOG.md
@@ -1,7 +1,11 @@
-## 1.0.1
+## 1.1.0-wip
-* Add better error messages for `SocketException`s when using `IOClient`.
-
+* Add better error messages for `SocketException`s when using `IOClient`.
+* Make `StreamedRequest.sink` a `StreamSink`. This makes `request.sink.close()`
+ return a `Future` instead of `void`, but the returned future should _not_ be
+ awaited. The Future returned from `sink.close()` may only complete after the
+ request has been sent.
+
## 1.0.0
* Requires Dart 3.0 or later.
diff --git a/pkgs/http/lib/src/streamed_request.dart b/pkgs/http/lib/src/streamed_request.dart
index 4651956..d10386e 100644
--- a/pkgs/http/lib/src/streamed_request.dart
+++ b/pkgs/http/lib/src/streamed_request.dart
@@ -20,9 +20,12 @@
/// ```dart
/// final request = http.StreamedRequest('POST', Uri.http('example.com', ''))
/// ..contentLength = 10
-/// ..sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
-/// ..sink.close(); // The sink must be closed to end the request.
+/// ..sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
///
+/// // The sink must be closed to end the request.
+/// // The Future returned from `close()` may not complete until after the
+/// // request is sent, and it should not be awaited.
+/// unawaited(request.sink.close());
/// final response = await request.send();
/// ```
class StreamedRequest extends BaseRequest {
@@ -32,7 +35,7 @@
/// buffered.
///
/// Closing this signals the end of the request.
- EventSink<List<int>> get sink => _controller.sink;
+ StreamSink<List<int>> get sink => _controller.sink;
/// The controller for [sink], from which [BaseRequest] will read data for
/// [finalize].
diff --git a/pkgs/http/pubspec.yaml b/pkgs/http/pubspec.yaml
index 30d8878..ac6f66f 100644
--- a/pkgs/http/pubspec.yaml
+++ b/pkgs/http/pubspec.yaml
@@ -1,5 +1,5 @@
name: http
-version: 1.0.1-wip
+version: 1.1.0-wip
description: A composable, multi-platform, Future-based API for HTTP requests.
repository: https://github.com/dart-lang/http/tree/master/pkgs/http
diff --git a/pkgs/http/test/html/client_test.dart b/pkgs/http/test/html/client_test.dart
index b56b228..1a6c634 100644
--- a/pkgs/http/test/html/client_test.dart
+++ b/pkgs/http/test/html/client_test.dart
@@ -5,6 +5,8 @@
@TestOn('browser')
library;
+import 'dart:async';
+
import 'package:http/browser_client.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
@@ -17,9 +19,8 @@
var request = http.StreamedRequest('POST', echoUrl);
var responseFuture = client.send(request);
- request.sink
- ..add('{"hello": "world"}'.codeUnits)
- ..close();
+ request.sink.add('{"hello": "world"}'.codeUnits);
+ unawaited(request.sink.close());
var response = await responseFuture;
var bytesString = await response.stream.bytesToString();
diff --git a/pkgs/http/test/html/streamed_request_test.dart b/pkgs/http/test/html/streamed_request_test.dart
index c767173..1668656 100644
--- a/pkgs/http/test/html/streamed_request_test.dart
+++ b/pkgs/http/test/html/streamed_request_test.dart
@@ -5,6 +5,8 @@
@TestOn('browser')
library;
+import 'dart:async';
+
import 'package:http/browser_client.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
@@ -16,8 +18,8 @@
test("works when it's set", () async {
var request = http.StreamedRequest('POST', echoUrl)
..contentLength = 10
- ..sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
- ..sink.close();
+ ..sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+ unawaited(request.sink.close());
final response = await BrowserClient().send(request);
@@ -28,7 +30,7 @@
test("works when it's not set", () async {
var request = http.StreamedRequest('POST', echoUrl);
request.sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
- request.sink.close();
+ unawaited(request.sink.close());
final response = await BrowserClient().send(request);
expect(await response.stream.toBytes(),
diff --git a/pkgs/http/test/io/client_test.dart b/pkgs/http/test/io/client_test.dart
index 9476f05..fd426a8 100644
--- a/pkgs/http/test/io/client_test.dart
+++ b/pkgs/http/test/io/client_test.dart
@@ -5,6 +5,7 @@
@TestOn('vm')
library;
+import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -42,9 +43,8 @@
..headers[HttpHeaders.userAgentHeader] = 'Dart';
var responseFuture = client.send(request);
- request
- ..sink.add('{"hello": "world"}'.codeUnits)
- ..sink.close();
+ request.sink.add('{"hello": "world"}'.codeUnits);
+ unawaited(request.sink.close());
var response = await responseFuture;
@@ -81,9 +81,8 @@
..headers[HttpHeaders.userAgentHeader] = 'Dart';
var responseFuture = client.send(request);
- request
- ..sink.add('{"hello": "world"}'.codeUnits)
- ..sink.close();
+ request.sink.add('{"hello": "world"}'.codeUnits);
+ unawaited(request.sink.close());
var response = await responseFuture;
diff --git a/pkgs/http/test/io/streamed_request_test.dart b/pkgs/http/test/io/streamed_request_test.dart
index 76efd6f..f0e990c 100644
--- a/pkgs/http/test/io/streamed_request_test.dart
+++ b/pkgs/http/test/io/streamed_request_test.dart
@@ -5,6 +5,7 @@
@TestOn('vm')
library;
+import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
@@ -22,9 +23,8 @@
test('controls the Content-Length header', () async {
var request = http.StreamedRequest('POST', serverUrl)
..contentLength = 10
- ..sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
- ..sink.close();
-
+ ..sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+ unawaited(request.sink.close());
var response = await request.send();
expect(
await utf8.decodeStream(response.stream),
@@ -35,8 +35,7 @@
test('defaults to sending no Content-Length', () async {
var request = http.StreamedRequest('POST', serverUrl);
request.sink.add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
- request.sink.close();
-
+ unawaited(request.sink.close());
var response = await request.send();
expect(await utf8.decodeStream(response.stream),
parse(containsPair('headers', isNot(contains('content-length')))));
@@ -47,7 +46,7 @@
test('.send() with a response with no content length', () async {
var request =
http.StreamedRequest('GET', serverUrl.resolve('/no-content-length'));
- request.sink.close();
+ unawaited(request.sink.close());
var response = await request.send();
expect(await utf8.decodeStream(response.stream), equals('body'));
});