consolidateHttpClientResponseBytes function Null safety
- HttpClientResponse response,
- {bool autoUncompress = true,
- BytesReceivedCallback? onBytesReceived}
Efficiently converts the response body of an HttpClientResponse into a Uint8List.
The future returned will forward any error emitted by response
.
The onBytesReceived
callback, if specified, will be invoked for every
chunk of bytes that is received while consolidating the response bytes.
If the callback throws an error, processing of the response will halt, and
the returned future will complete with the error that was thrown by the
callback. For more information on how to interpret the parameters to the
callback, see the documentation on BytesReceivedCallback.
If the response
is gzipped and the autoUncompress
parameter is true,
this will automatically un-compress the bytes in the returned list if it
hasn't already been done via HttpClient.autoUncompress. To get compressed
bytes from this method (assuming the response is sending compressed bytes),
set both HttpClient.autoUncompress to false and the autoUncompress
parameter to false.
Implementation
Future<Uint8List> consolidateHttpClientResponseBytes(
HttpClientResponse response, {
bool autoUncompress = true,
BytesReceivedCallback? onBytesReceived,
}) {
assert(autoUncompress != null);
final Completer<Uint8List> completer = Completer<Uint8List>.sync();
final _OutputBuffer output = _OutputBuffer();
ByteConversionSink sink = output;
int? expectedContentLength = response.contentLength;
if (expectedContentLength == -1) {
expectedContentLength = null;
}
switch (response.compressionState) {
case HttpClientResponseCompressionState.compressed:
if (autoUncompress) {
// We need to un-compress the bytes as they come in.
sink = gzip.decoder.startChunkedConversion(output);
}
break;
case HttpClientResponseCompressionState.decompressed:
// response.contentLength will not match our bytes stream, so we declare
// that we don't know the expected content length.
expectedContentLength = null;
break;
case HttpClientResponseCompressionState.notCompressed:
// Fall-through.
break;
}
int bytesReceived = 0;
late final StreamSubscription<List<int>> subscription;
subscription = response.listen((List<int> chunk) {
sink.add(chunk);
if (onBytesReceived != null) {
bytesReceived += chunk.length;
try {
onBytesReceived(bytesReceived, expectedContentLength);
} catch (error, stackTrace) {
completer.completeError(error, stackTrace);
subscription.cancel();
return;
}
}
}, onDone: () {
sink.close();
completer.complete(output.bytes);
}, onError: completer.completeError, cancelOnError: true);
return completer.future;
}