sendStreamed method

  1. @override
Future<RawHttpStreamedResponse> sendStreamed(
  1. RawHttpRequest request
)
override

Streams the response without going through Dio.fetch.

Dio re-emits adapter streams through a controller that never pauses the socket, so a slow consumer would make Dio buffer the whole body. Calling the HttpClientAdapter directly keeps the HTTP client's own stream, and async* in _guardBody propagates the consumer's pauses to it.

Implementation

@override
Future<RawHttpStreamedResponse> sendStreamed(RawHttpRequest request) async {
  final binding = _Binding(request.cancellationToken);
  try {
    final options = await _compose(request, binding, ResponseType.stream);
    final body = await _dio.httpClientAdapter.fetch(
      options,
      _requestStream(options, request),
      binding.cancelToken?.whenCancel,
    );
    var stream = body.stream;
    final receive = request.timeout?.receive;
    if (receive != null) {
      stream = stream.timeout(
        receive,
        onTimeout: (sink) => sink
          ..addError(
            RawHttpException(
              message: 'Receiving the response timed out',
              type: RawHttpFailureType.timeout,
              uri: request.uri,
            ),
          )
          ..close(),
      );
    }
    return RawHttpStreamedResponse(
      statusCode: body.statusCode,
      headers: _copyHeaders(body.headers),
      body: _guardBody(stream, request, binding),
      redirected: _followedRedirect(
        body.statusCode,
        isRedirect: body.isRedirect,
        redirectCount: body.redirects?.length ?? 0,
      ),
    );
  } on DioException catch (error) {
    binding.release();
    throw _toRawException(error, request.uri);
  } on RawHttpException {
    binding.release();
    rethrow;
  } on Object catch (error) {
    binding.release();
    throw _toRawFromUnknown(error, request);
  }
}