transformResponse method

  1. @override
Future transformResponse(
  1. RequestOptions options,
  2. ResponseBody response
)
inherited

As an agreement, we return the response when the Options.responseType is ResponseType.stream.

Implementation

@override
Future<dynamic> transformResponse(
  RequestOptions options,
  ResponseBody response,
) async {
  if (options.responseType == ResponseType.stream) {
    return response;
  }
  int length = 0;
  int received = 0;
  final showDownloadProgress = options.onReceiveProgress != null;
  if (showDownloadProgress) {
    length = int.parse(
      response.headers[Headers.contentLengthHeader]?.first ?? '-1',
    );
  }
  final completer = Completer();
  final stream = response.stream.transform<Uint8List>(
    StreamTransformer.fromHandlers(
      handleData: (data, sink) {
        sink.add(data);
        if (showDownloadProgress) {
          received += data.length;
          options.onReceiveProgress?.call(received, length);
        }
      },
    ),
  );
  // Keep references to the data chunks and concatenate them later.
  final chunks = <Uint8List>[];
  int finalSize = 0;
  final StreamSubscription subscription = stream.listen(
    (chunk) {
      finalSize += chunk.length;
      chunks.add(chunk);
    },
    onError: (Object error, StackTrace stackTrace) {
      completer.completeError(error, stackTrace);
    },
    onDone: () => completer.complete(),
    cancelOnError: true,
  );
  options.cancelToken?.whenCancel.then((_) {
    return subscription.cancel();
  });
  await completer.future;
  // Copy all chunks into a final Uint8List.
  final responseBytes = Uint8List(finalSize);
  int chunkOffset = 0;
  for (final chunk in chunks) {
    responseBytes.setAll(chunkOffset, chunk);
    chunkOffset += chunk.length;
  }

  if (options.responseType == ResponseType.bytes) {
    return responseBytes;
  }

  final String? responseBody;
  if (options.responseDecoder != null) {
    responseBody = options.responseDecoder!(
      responseBytes,
      options,
      response..stream = Stream.empty(),
    );
  } else if (responseBytes.isNotEmpty) {
    responseBody = utf8.decode(responseBytes, allowMalformed: true);
  } else {
    responseBody = null;
  }
  if (responseBody != null &&
      responseBody.isNotEmpty &&
      options.responseType == ResponseType.json &&
      Transformer.isJsonMimeType(
        response.headers[Headers.contentTypeHeader]?.first,
      )) {
    return jsonDecodeCallback(responseBody);
  }
  return responseBody;
}