sendStreamed method
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);
}
}