stream method

  1. @override
Future<StreamedHttpResponse> stream(
  1. HttpRequest request
)
override

Sends request and completes as soon as the status and headers have arrived. The body is then read from StreamedHttpResponse.body as it comes.

Use it for responses that are long or never end: server-sent events, large downloads. The request's timeout and readTimeout cover only the wait for the headers, so a stream may then stay quiet as long as it likes. A failure before the headers throws an HttpTransportException; a failure later arrives as an HttpTransportException error on the body stream.

Implementation

@override
Future<StreamedHttpResponse> stream(HttpRequest request) =>
    _exchange(request, (incoming, outgoing) async {
      late final StreamSubscription<List<int>> subscription;
      late final StreamController<List<int>> body;
      body = StreamController<List<int>>(
        onListen: () => subscription = incoming.listen(
          body.add,
          onError: (Object error, StackTrace stackTrace) => body.addError(
            error is io.IOException
                ? HttpTransportException(
                    'response broke: $error',
                    request: request,
                    cause: error,
                  )
                : error,
            stackTrace,
          ),
          onDone: body.close,
        ),
        onPause: () => subscription.pause(),
        onResume: () => subscription.resume(),
        // Cancelling alone would keep the connection open to drain it.
        onCancel: () async {
          await subscription.cancel();
          outgoing.abort();
        },
      );
      return StreamedHttpResponse(
        incoming.statusCode,
        headers: _headers(incoming),
        body: body.stream,
        request: request,
      );
    });