requestURL method

Future<HttpResponse> requestURL(
  1. HttpClient? httpClient,
  2. HttpMethod method,
  3. String requestURL, {
  4. Credential? authorization,
  5. Map<String, String?>? queryParameters,
  6. Object? body,
  7. String? contentType,
  8. String? accept,
  9. OnCachedResponse? onStaleResponse,
  10. Duration? staleResponseDelay,
})

Does a cached request using httpClient and requestURL.

  • authorization a Credential for authorization.
  • queryParameters the request query parameters.
  • body the request body.
  • contentType the Content-Type header of the request body.
  • accept the Accept header.
  • onStaleResponse function to call when a stale response (already cached) is available to use while requesting a new response.
  • staleResponseDelay a delay to call onStaleResponse function. If the new response arrives before this delay, no call to onStaleResponse will be performed.

Implementation

Future<HttpResponse> requestURL(
    HttpClient? httpClient, HttpMethod method, String requestURL,
    {Credential? authorization,
    Map<String, String?>? queryParameters,
    Object? body,
    String? contentType,
    String? accept,
    OnCachedResponse? onStaleResponse,
    Duration? staleResponseDelay}) async {
  httpClient ??= HttpClient(requestURL);

  var cacheRequest = _CacheRequest(
      method, requestURL, queryParameters, body, contentType, accept);

  var cachedEntry = _getCacheEntry(cacheRequest);

  HttpResponse? cachedResponse;
  if (cachedEntry != null) {
    var cachedRequest = cachedEntry.key;
    cachedResponse = cachedEntry.value;

    if (cachedRequest.isValid(timeout.inMilliseconds)) {
      cachedRequest.updateAccessTime();

      _log('Cached request: $method > $requestURL > $cachedResponse');

      return cachedResponse;
    }
  }

  Completer<HttpResponse?>? cachedAvailableDelayed;
  if (onStaleResponse != null && cachedResponse != null) {
    if (staleResponseDelay != null && staleResponseDelay.inMilliseconds > 1) {
      cachedAvailableDelayed = Completer<HttpResponse?>();

      // ignore: unawaited_futures
      cachedAvailableDelayed.future.then((cachedResponse) {
        if (cachedResponse != null) {
          onStaleResponse(cachedResponse);
        }
      });

      Future.delayed(staleResponseDelay, () {
        if (!cachedAvailableDelayed!.isCompleted) {
          cachedAvailableDelayed.complete(cachedResponse);
        }
      });
    } else {
      onStaleResponse(cachedResponse);
    }
  }

  var ret = httpClient.requestURL(method, requestURL,
      authorization: authorization,
      queryParameters: queryParameters,
      body: body,
      contentType: contentType,
      accept: accept);

  var response = await ret;

  if (cachedAvailableDelayed != null && !cachedAvailableDelayed.isCompleted) {
    cachedAvailableDelayed.complete(null);
  }

  ensureCacheBelowMaxMemory(response.memorySize());

  _cache[cacheRequest] = response;

  var usedMemory = calculateCacheUsedMemory();

  _log('Used memory: $usedMemory / $maxCacheMemory');

  return response;
}