Crate http_cache

Crate http_cache 

Source
Expand description

A caching middleware that follows HTTP caching rules, thanks to http-cache-semantics. By default, it uses cacache as the backend cache manager.

This crate provides the core HTTP caching functionality that can be used to build caching middleware for various HTTP clients and server frameworks. It implements RFC 7234 HTTP caching semantics, supporting features like:

  • Automatic cache invalidation for unsafe HTTP methods (PUT, POST, DELETE, PATCH)
  • Respect for HTTP cache-control headers
  • Conditional requests (ETag, Last-Modified)
  • Multiple cache storage backends
  • Streaming response support

§Basic Usage

The core types for building HTTP caches:

use http_cache::{CACacheManager, HttpCache, CacheMode, HttpCacheOptions};

// Create a cache manager with disk storage
let manager = CACacheManager::new("./cache".into(), true);

// Create an HTTP cache with default behavior
let cache = HttpCache {
    mode: CacheMode::Default,
    manager,
    options: HttpCacheOptions::default(),
};

§Cache Modes

Different cache modes provide different behaviors:

use http_cache::{CacheMode, HttpCache, CACacheManager, HttpCacheOptions};

let manager = CACacheManager::new("./cache".into(), true);

// Default mode: follows HTTP caching rules
let default_cache = HttpCache {
    mode: CacheMode::Default,
    manager: manager.clone(),
    options: HttpCacheOptions::default(),
};

// NoStore mode: never caches responses
let no_store_cache = HttpCache {
    mode: CacheMode::NoStore,
    manager: manager.clone(),
    options: HttpCacheOptions::default(),
};

// ForceCache mode: caches responses even if headers suggest otherwise
let force_cache = HttpCache {
    mode: CacheMode::ForceCache,
    manager,
    options: HttpCacheOptions::default(),
};

§Custom Cache Keys

You can customize how cache keys are generated:

use http_cache::{HttpCacheOptions, CACacheManager, HttpCache, CacheMode};
use std::sync::Arc;
use http::request::Parts;

let manager = CACacheManager::new("./cache".into(), true);

let options = HttpCacheOptions {
    cache_key: Some(Arc::new(|req: &Parts| {
        // Custom cache key that includes query parameters
        format!("{}:{}", req.method, req.uri)
    })),
    ..Default::default()
};

let cache = HttpCache {
    mode: CacheMode::Default,
    manager,
    options,
};

§Maximum TTL Control

Set a maximum time-to-live for cached responses, particularly useful with CacheMode::IgnoreRules:

use http_cache::{HttpCacheOptions, CACacheManager, HttpCache, CacheMode};
use std::time::Duration;

let manager = CACacheManager::new("./cache".into(), true);

// Limit cache duration to 5 minutes regardless of server headers
let options = HttpCacheOptions {
    max_ttl: Some(Duration::from_secs(300)), // 5 minutes
    ..Default::default()
};

let cache = HttpCache {
    mode: CacheMode::IgnoreRules, // Ignore server cache-control headers
    manager,
    options,
};

§Response-Based Cache Mode Override

Override cache behavior based on the response you receive. This is useful for scenarios like forcing cache for successful responses even when headers say not to cache, or never caching error responses like rate limits:

use http_cache::{HttpCacheOptions, CACacheManager, HttpCache, CacheMode};
use std::sync::Arc;

let manager = CACacheManager::new("./cache".into(), true);

let options = HttpCacheOptions {
    response_cache_mode_fn: Some(Arc::new(|_request_parts, response| {
        match response.status {
            // Force cache successful responses even if headers say not to cache
            200..=299 => Some(CacheMode::ForceCache),
            // Never cache rate-limited responses  
            429 => Some(CacheMode::NoStore),
            // Use default behavior for everything else
            _ => None,
        }
    })),
    ..Default::default()
};

let cache = HttpCache {
    mode: CacheMode::Default,
    manager,
    options,
};

§Content-Type Based Caching

You can implement selective caching based on response content types using response_cache_mode_fn. This is useful when you only want to cache certain types of content:

use http_cache::{HttpCacheOptions, CACacheManager, HttpCache, CacheMode};
use std::sync::Arc;

let manager = CACacheManager::new("./cache".into(), true);

let options = HttpCacheOptions {
    response_cache_mode_fn: Some(Arc::new(|_request_parts, response| {
        // Check the Content-Type header to decide caching behavior
        if let Some(content_type) = response.headers.get("content-type") {
            match content_type.as_str() {
                // Cache JSON APIs aggressively
                ct if ct.starts_with("application/json") => Some(CacheMode::ForceCache),
                // Cache images with default rules
                ct if ct.starts_with("image/") => Some(CacheMode::Default),
                // Cache static assets
                ct if ct.starts_with("text/css") => Some(CacheMode::ForceCache),
                ct if ct.starts_with("application/javascript") => Some(CacheMode::ForceCache),
                // Don't cache HTML pages (dynamic content)
                ct if ct.starts_with("text/html") => Some(CacheMode::NoStore),
                // Don't cache unknown content types
                _ => Some(CacheMode::NoStore),
            }
        } else {
            // No Content-Type header - don't cache
            Some(CacheMode::NoStore)
        }
    })),
    ..Default::default()
};

let cache = HttpCache {
    mode: CacheMode::Default, // This gets overridden by response_cache_mode_fn
    manager,
    options,
};

§Streaming Support

For handling large responses without full buffering, use the StreamingManager:

use http_cache::{StreamingBody, HttpStreamingCache, StreamingManager};
use bytes::Bytes;
use std::path::PathBuf;
use http_body::Body;
use http_body_util::Full;

// Create a file-based streaming cache manager
let manager = StreamingManager::new(PathBuf::from("./streaming-cache"));

// StreamingBody can handle both buffered and streaming scenarios
let body: StreamingBody<Full<Bytes>> = StreamingBody::buffered(Bytes::from("cached content"));
println!("Body size: {:?}", body.size_hint());

Note: Streaming support requires the StreamingManager with the streaming feature. Other cache managers (CACacheManager, MokaManager, QuickManager) do not support streaming and will buffer response bodies in memory.

§Features

The following features are available. By default manager-cacache and cacache-smol are enabled.

  • manager-cacache (default): enable cacache, a disk cache, backend manager.
  • cacache-smol (default): enable smol runtime support for cacache.
  • cacache-tokio (disabled): enable tokio runtime support for cacache.
  • manager-moka (disabled): enable moka, an in-memory cache, backend manager.
  • streaming (disabled): enable the StreamingManager for streaming cache support.
  • streaming-tokio (disabled): enable streaming with tokio runtime support.
  • streaming-smol (disabled): enable streaming with smol runtime support.
  • with-http-types (disabled): enable http-types type conversion support

Note: Only StreamingManager (via the streaming feature) provides streaming support. Other managers will buffer response bodies in memory even when used with StreamingManager.

§Integration

This crate is designed to be used as a foundation for HTTP client and server middleware. See the companion crates for specific integrations:

Structs§

BadHeader
Error type for bad header values
BadRequest
Error type for request parsing failure
BadVersion
Error type for unknown http versions
CACacheManager
Implements CacheManager with cacache as the backend.
CacheAnalysis
Analysis result for a request, containing cache key and caching decisions
CacheOptions
Options struct provided by http-cache-semantics. Configuration options which control behavior of the cache. Use with CachePolicy::new_options().
HttpCache
Caches requests according to http spec.
HttpCacheOptions
Configuration options for customizing HTTP cache behavior on a per-request basis.
HttpResponse
A basic generic type that represents an HTTP response
HttpStreamingCache
Streaming version of HTTP cache that supports streaming request/response bodies without buffering them in memory.
StreamingError
Error type for streaming operations

Enums§

CacheMode
Cache mode determines how the HTTP cache behaves for requests.
ClientStreamingError
Streaming error type specifically for client-specific streaming operations
HitOrMiss
Represents a basic cache status Used in the custom headers x-cache and x-cache-lookup
HttpCacheError
Unified error type for HTTP cache operations that works across all client libraries.
HttpVersion
Represents an HTTP version
StreamingBody
A body type that can represent either buffered data from cache or streaming body from upstream.

Constants§

XCACHE
x-cache header: Value will be HIT if the response was served from cache, MISS if not
XCACHELOOKUP
x-cache-lookup header: Value will be HIT if a response existed in cache, MISS if not

Traits§

CacheManager
A trait providing methods for storing, reading, and removing cache records.
HttpCacheInterface
An interface for HTTP caching that works with composable middleware patterns like Tower. This trait separates the concerns of request analysis, cache lookup, and response processing into discrete steps.
HttpCacheStreamInterface
Streaming version of the HTTP cache interface that supports streaming request/response bodies without buffering them in memory. This is ideal for large responses or when memory usage is a concern.
Middleware
Describes the functionality required for interfacing with HTTP client middleware
StreamingCacheManager
A streaming cache manager that supports streaming request/response bodies without buffering them in memory. This is ideal for large responses.

Type Aliases§

BoxError
Generic error type for the HttpCache middleware.
CacheBust
A closure that takes http::request::Parts, Option<CacheKey>, the default cache key (&str) and returns Vec<String> of keys to bust the cache for. An empty vector means that no cache busting will be performed.
CacheKey
A closure that takes http::request::Parts and returns a String. By default, the cache key is a combination of the request method and uri with a colon in between.
CacheModeFn
A closure that takes http::request::Parts and returns a CacheMode
HttpCacheResult
A Result type alias for HTTP cache operations using HttpCacheError
ResponseCacheModeFn
A closure that takes http::request::Parts, HttpResponse and returns a CacheMode to override caching behavior based on the response
Result
A Result typedef to use with the BoxError type