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