send method

  1. @override
Future<StreamedResponse> send(
  1. BaseRequest request, {
  2. CancellationToken? cancellationToken,
})
override

Sends an HTTP request and asynchronously returns the response.

Implementers should call BaseRequest.finalize to get the body of the request as a ByteStream. They shouldn't make any assumptions about the state of the stream; it could have data written to it asynchronously at a later point, or it could already be closed when it's returned. Any internal HTTP errors should be wrapped as ClientExceptions.

Implementation

@override
Future<StreamedResponse> send(
  BaseRequest request, {
  CancellationToken? cancellationToken,
}) async {
  final splitter = StreamSplitter(request.finalize());

  var i = 0;
  for (;;) {
    StreamedResponse? response;
    try {
      response = await _inner.send(
        _copyRequest(request, splitter.split()),
        cancellationToken: cancellationToken,
      );
    } catch (error, stackTrace) {
      // Always rethrow cancellation errors
      if (cancellationToken?.isCancelled == true &&
          error == cancellationToken?.exception) rethrow;
      // Rethrow if this is the last attempt
      if (i == _retries) rethrow;
      // Rethrow if _whenError returns false, indicating we shouldn't retry
      if (!await CancellableFuture.from(
        () => _whenError(error, stackTrace),
        cancellationToken,
      )) rethrow;
    }

    if (response != null) {
      if (i == _retries ||
          !await CancellableFuture.from(
            () => _when(response!),
            cancellationToken,
          )) return response;

      // Make sure the response stream is listened to so that we don't leave
      // dangling connections.
      _unawaited(response.stream.listen((_) {}).cancel().catchError((_) {}));
    }

    await Future<void>.delayed(_delay(i)).asCancellable(cancellationToken);
    if (_onRetry != null) {
      await CancellableFuture.from(
        () => _onRetry!.call(request, response, i),
        cancellationToken,
      );
    }
    i++;
  }
}