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) async {
  final (response, headers, timer, abort) = await _fetchResponse(request);
  // The timeouts cover the headers only.
  timer.cancel();
  final reader = response.body?.getReader();
  var cancelled = false;
  late final StreamController<List<int>> body;
  body = StreamController<List<int>>(
    onListen: () async {
      try {
        while (reader != null && !cancelled) {
          final chunk = await reader.read().toDart;
          if (chunk.done) {
            break;
          }
          final value = chunk.value;
          if (value != null && !cancelled) {
            body.add(value.toDart);
          }
        }
      } on Object catch (error) {
        if (!cancelled) {
          body.addError(
            HttpTransportException(
              'response broke: $error',
              request: request,
              cause: error,
            ),
          );
        }
      }
      if (!cancelled) {
        await body.close();
      }
    },
    onCancel: () {
      cancelled = true;
      abort.abort();
    },
  );
  return StreamedHttpResponse(
    response.status,
    headers: headers,
    body: body.stream,
    request: request,
  );
}