Skip to content

Commit

Permalink
Make StreameRequest.sink a StreamSink (#965)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
natebosch committed Jun 20, 2023
1 parent 8c25057 commit ff1fcfe
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 25 deletions.
10 changes: 7 additions & 3 deletions pkgs/http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
## 1.0.1
## 1.1.0-wip

* 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.

* Add better error messages for `SocketException`s when using `IOClient`.

## 1.0.0

* Requires Dart 3.0 or later.
Expand Down
9 changes: 6 additions & 3 deletions pkgs/http/lib/src/streamed_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ import 'byte_stream.dart';
/// ```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 {
Expand All @@ -32,7 +35,7 @@ class StreamedRequest extends BaseRequest {
/// 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].
Expand Down
2 changes: 1 addition & 1 deletion pkgs/http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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

Expand Down
7 changes: 4 additions & 3 deletions pkgs/http/test/html/client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -17,9 +19,8 @@ void main() {
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();
Expand Down
8 changes: 5 additions & 3 deletions pkgs/http/test/html/streamed_request_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -16,8 +18,8 @@ void main() {
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);

Expand All @@ -28,7 +30,7 @@ void main() {
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(),
Expand Down
11 changes: 5 additions & 6 deletions pkgs/http/test/io/client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@TestOn('vm')
library;

import 'dart:async';
import 'dart:convert';
import 'dart:io';

Expand Down Expand Up @@ -42,9 +43,8 @@ void main() {
..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;

Expand Down Expand Up @@ -81,9 +81,8 @@ void main() {
..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;

Expand Down
11 changes: 5 additions & 6 deletions pkgs/http/test/io/streamed_request_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@TestOn('vm')
library;

import 'dart:async';
import 'dart:convert';

import 'package:http/http.dart' as http;
Expand All @@ -22,9 +23,8 @@ void main() {
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),
Expand All @@ -35,8 +35,7 @@ void main() {
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')))));
Expand All @@ -47,7 +46,7 @@ void main() {
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'));
});
Expand Down

0 comments on commit ff1fcfe

Please sign in to comment.