send method

  1. @override
Future<StreamedResponse> send(
  1. BaseRequest request
)

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<http.StreamedResponse> send(http.BaseRequest request) async {
  final client = activeInnerClient;
  final key = request.url.toString();

  // Handle GET request caching
  if (request.method == 'GET') {
    final cached = _cache[key];
    if (cached != null && !cached.isExpired(ttl)) {
      stats.hits++;
      // Refresh position in LinkedHashMap to keep LRU order
      _cache.remove(key);
      _cache[key] = cached;

      onCacheHit?.call(key, stats);

      return http.StreamedResponse(
        Stream.value(cached.bytes),
        cached.statusCode,
        headers: cached.headers,
        contentLength: cached.bytes.length,
        request: request,
      );
    }
    stats.misses++;
  }

  final response = await client.send(request);

  // Cache successful GET responses
  if (request.method == 'GET' && response.statusCode == 200) {
    final bytes = await response.stream.toBytes();

    _putInCache(
      key,
      CachedHttpResponse(
        bytes: bytes,
        statusCode: response.statusCode,
        headers: response.headers,
        createdAt: DateTime.now(),
      ),
    );

    return http.StreamedResponse(
      Stream.value(bytes),
      response.statusCode,
      headers: response.headers,
      contentLength: response.contentLength,
      reasonPhrase: response.reasonPhrase,
      isRedirect: response.isRedirect,
      persistentConnection: response.persistentConnection,
      request: response.request,
    );
  }

  // Check if the request is a mutating operation
  if (isMutatingRequest(request) && response.statusCode < 400) {
    _applyInvalidation(request);
  }

  return response;
}