intercept method

  1. @override
Future<HttpResponse> intercept(
  1. HttpRequest request,
  2. CancellationToken token,
  3. HttpRequestHandler next
)
override

Implementation

@override
Future<HttpResponse> intercept(HttpRequest request, CancellationToken token,
    HttpRequestHandler next) async {
  final safe = {HttpMethod.get, HttpMethod.head, HttpMethod.options}
      .contains(request.method);
  if ((!safe && !options.retryWrites) ||
      request.body?.isReplayable == false) {
    return next(request, token);
  }
  for (var attempt = 1;; attempt++) {
    token.throwIfCanceled();
    HttpResponse? response;
    try {
      response = await next(request.copyWith(), token);
    } catch (error) {
      if (token.isCanceled ||
          attempt >= options.maxAttempts ||
          (error is! NetworkException && error is! RequestTimeoutException)) {
        rethrow;
      }
    }
    if (response != null &&
        (!options.statuses.contains(response.statusCode) ||
            attempt >= options.maxAttempts)) {
      return response;
    }
    var duration = Duration(
        microseconds: (min(
                    options.maxDelay.inMicroseconds,
                    options.baseDelay.inMicroseconds *
                        pow(2, min(attempt - 1, 30))) *
                _random().clamp(0, 1))
            .round());
    if (response != null) {
      final values = response.headers['retry-after'];
      if (values.isNotEmpty) {
        final seconds = int.tryParse(values.first);
        final date = const HttpDateCodec().parse(values.first);
        final requested = seconds != null
            ? Duration(seconds: max(0, seconds))
            : date?.difference(_clock().toUtc());
        // Do not violate a server delay by retrying before its requested time.
        if (requested != null && requested > options.maxDelay) {
          return response;
        }
        if (requested != null && requested > duration) duration = requested;
      }
      await response.dispose();
    }
    await _delay(duration, token);
  }
}