# Changelog

## [1.0.0-alpha.7] - 2026-07-22

### Added

- `RedbManager` cache backend using redb for persistent, synchronous on-disk caching that requires no async runtime
- `manager-redb` feature flag for enabling `RedbManager`
- `StreamingCacheManager::update_metadata` for refreshing a stored entry's headers, policy, and user metadata without touching the body file. This is a required method, so existing implementations of the trait must add it.
- `CachedRequestMethod` and `CacheEntryToken` response extensions, used by the streaming orchestrator to tell a manager which request method produced a response and which stored entry a cached response was served from

### Changed

- MSRV bumped from 1.88.0 to 1.89.0
- Default cache manager changed from `manager-cacache` to `manager-redb`. `manager-cacache` (and `CACacheManager`) is now opt-in — enable the `manager-cacache` feature to keep using it. The `cacache` crate is no longer maintained upstream.
- `RedbManager` holds an exclusive file lock on its database: a second manager (or process) opening the same path fails at construction. Share one instance via `Arc` instead. This differs from the previous default `CACacheManager`, which allowed concurrent access to one cache directory.
- `RedbManager` stores are batched for durability: commits are flushed to disk every 64 writes (configurable via `from_database_with_flush_interval`) and on drop, so a crash can lose approximately the most recent 64 stores. Deletes commit durably, so invalidations survive a crash.
- `StreamingManager` metadata now includes a blake3 body checksum, verified while streaming; corrupt entries error the stream and self-heal to a miss. Existing streaming cache entries from earlier alphas fail to decode and are treated as misses (re-fetched once).
- `StreamingBody::from_file_with_size` now streams exactly `size` bytes and errors on a shorter file; it previously read to end of file, treating `size` as a hint.
- `StreamingManager` no longer prewarms its in-memory metadata cache at startup; hydration is lazy, so `entry_count()` reads 0 after a restart until keys are accessed.
- Non-cacheable responses on the streaming path are now passed through without buffering (`StreamingManager::Body` is `StreamingBody<UnsyncBoxBody<Bytes, StreamingError>>`). Upstream body failures on that path surface as stream errors while the body is read, not as a middleware error before the response is returned.
- Concurrent operations on the same cache key in `StreamingManager` are serialized with per-key locks, so racing gets/puts can no longer drop freshly written entries.
- `StreamingManager::put` writes the response body to disk one frame at a time instead of collecting it into memory first, so peak memory no longer scales with response size. It returns a body backed by the committed on-disk entry rather than an in-memory copy.
- Responses larger than `max_body_size` are no longer an error: caching is declined and the response is served in full, uncached. A declared `Content-Length` over the limit skips writing to disk entirely. HEAD responses are exempt, since their `Content-Length` describes the entity rather than the empty body.
- Responses whose received length does not match their declared `Content-Length` are served but not cached, so a truncated response is never stored (RFC 9111 s3.3). HEAD responses are exempt.
- Hop-by-hop headers are no longer written into cached entries. This covers `connection`, `transfer-encoding`, the rest of the RFC 9111 s3.1 set, and any field names listed in a `Connection` header. Live responses are unaffected.
- 304 revalidation on the streaming path updates the stored metadata in place instead of re-reading and rewriting the body file, so revalidating a large entry no longer costs a full read and write.
- `StreamingCacheManager::put` documents when a stored entry becomes visible: at or after the returned body has been fully consumed. The bundled `StreamingManager` makes it visible before `put` returns, but implementations are not required to.

## [1.0.0-alpha.6] - 2026-04-17

### Added

- `HttpStreamingCache::run` orchestrator for streaming cache operations, eliminating duplicated logic in downstream middleware crates
- `FetchRequest` enum for callback-based fetch dispatch in streaming paths
- `run_no_cache_from_parts` public method on `HttpCache` for cache-busting with pre-extracted request parts
- `CachedUserMetadata` for preserving user metadata through 304 re-cache operations
- `response_cache_mode_fn` evaluation in `conditional_fetch` 200 branch (both paths)

### Changed

- `StreamingManager` storage backend replaced with an embedded `redb` database (for metadata) plus raw `tokio::fs` files (for response bodies), fronted by `moka` as an in-memory hot cache. This replaces the previous `cacache`-based backend. Overwrites atomically replace prior content; there is no longer any background eviction-driven disk cleanup. Disk state is managed explicitly by `put`, `delete`, and `clear`. The on-disk format is not compatible with previous releases — users upgrading should delete the `metadata.redb` file, the `bodies/` subdirectory, and the `tmp/` subdirectory from their cache directory before the first run on this version.
- Only one `StreamingManager` instance may point at a given cache directory at a time (enforced via the database file lock on `metadata.redb`). Attempting to construct a second instance while another is alive returns an error.
- `StreamingManager::entry_count()` now returns the count of entries currently warm in the in-memory hot cache, not the total number of entries persisted on disk. When the cache has fewer entries than the configured capacity, this equals the previous value; once capacity is exceeded, cold entries remain reachable via `get` but are not counted here.
- Replaced `async_trait` with native async functions in traits (RPITIT) for `CacheManager`, `StreamingCacheManager`, and `Middleware` traits
- `CacheAwareRateLimiter::until_key_ready` now returns `Pin<Box<dyn Future>>` for dyn-compatibility
- Removed `async-trait` dependency
- Cache deserialization failure logs lowered from `warn` to `debug` level
- `modify_response_before_caching` is now `pub` on `HttpCacheOptions`

### Fixed

- `StreamingManager` now persists cache entries across service restarts (#159). Previously the key→content mapping was only kept in memory, so cached bodies on disk became unreachable orphans after restart.
- Multi-valued response headers (e.g. `Set-Cookie`, `Via`, `Link`) are now preserved correctly when merging headers from revalidation responses. Previously `HttpResponse::update_headers`, the streaming `conditional_fetch` Fresh/304 merges, and the streaming `handle_not_modified` path all lost or duplicated values for same-named headers.
- RFC 7234 s4.4: cache invalidation now gated on successful response status (2xx/3xx) for unsafe methods
- RFC 7234 s4.4: HEAD cache entries now invalidated alongside GET entries
- `conditional_fetch` 200 branch now checks `should_cache_response` before caching
- Streaming path now respects `matches` flag from `BeforeRequest::Stale`
- Streaming path now handles all cache modes (NoCache, ForceCache, OnlyIfCached, IgnoreRules)
- Streaming 304 path preserves original user metadata instead of regenerating
- `modify_response_before_caching` now called at correct point in streaming cache paths
- Cache status headers set in correct order relative to `modify_response` and `manager.put`
- Warning header cleanup (1xx removal) on cached responses in streaming path
- 5xx stale fallback with Warning 111 in streaming conditional fetch
- `OnlyIfCached` 504 body now empty (consistent between streaming and non-streaming)

## [1.0.0-alpha.5] - 2026-02-17

### Added

- `url-standard` feature flag as the new default URL implementation using the `url` crate
- Transparent bincode-to-postcard migration in `CACacheManager` and `MokaManager` (reads legacy bincode data, writes postcard)

### Changed

- `StreamingManager` rewritten to use cacache for disk storage with moka for metadata tracking and TinyLFU eviction
- MSRV bumped from 1.85.0 to 1.88.0
- Updated `http-cache-semantics` from 2.1.0 to 3.0.0
- Updated `foyer` to 0.22.3
- Updated `rand` to 0.10.0
- `url` crate is now optional behind `url-standard` feature (enabled by default)
- Removed `runtime` module, streaming no longer requires runtime-specific code

### Fixed

- Metadata handling with bincode serialization
- `CacheMode` enum variant matching logic
- Feature flag gates for doc tests

## [1.0.0-alpha.4] - 2026-01-19

### Added

- `empty_body` method to `StreamingCacheManager` trait for creating empty body responses
- `get_ref_count` method to `ContentRefCounter` for non-mutating reference count checks
- `FoyerManager` cache backend using foyer for hybrid in-memory and disk caching
- `manager-foyer` feature flag for enabling `FoyerManager`
- `manager-cacache-bincode` and `manager-moka-bincode` feature flags for legacy bincode serialization
- `url-ada` feature flag for using WHATWG-compliant ada-url as an alternative to the url crate
- `url_parse`, `url_set_path`, `url_set_query`, `url_hostname`, `url_host_str` helper functions for URL operations

### Changed

- `StreamingManager` now wraps `ContentRefCounter` in `Arc` to ensure all clones share the same state
- Atomic operations in streaming cache now use proper memory ordering (`Acquire`/`Release`/`AcqRel`) instead of `Relaxed`
- Default serialization format changed from bincode to postcard (cache data incompatible with previous versions)
- Removed `cacache-smol` and `cacache-tokio` features in favor of tokio-only runtime
- `cacache` dependency now uses `tokio-runtime` by default
- Removed async-std from dependency tree

### Fixed

- Race condition in `remove_ref` using atomic `compare_exchange` loop to prevent TOCTOU bugs
- Cache size and entry count divergence when `StreamingManager` is cloned
- Memory leak in `delete` where reference count was decremented but not restored on non-orphaned content
- Race condition in `delete` by using non-mutating `get_ref_count` instead of remove/add pattern

## [1.0.0-alpha.3] - 2026-01-18

### Added

- `modify_response` field to `HttpCacheOptions` for modifying responses before storing in cache
- `http-headers-compat` feature flag for header compatibility options
- `metadata` field to `HttpResponse` for storing arbitrary data with cached responses
- `metadata_provider` function to `HttpCacheOptions` for computing metadata on cache store

### Changed

- MSRV is now 1.85.0

### Fixed

- Serialize all header values instead of just the first value per header name
- `HttpHeaders` serialization and insert behavior for bincode compatibility
- Preserve all header values sharing the same name

## [1.0.0-alpha.2] - 2025-08-24

### Added

- `max_ttl` field to `HttpCacheOptions` for controlling maximum cache duration
- Support for `Duration` type in `max_ttl` field for better ergonomics and type safety
- Cache duration limiting functionality that overrides longer server-specified durations while respecting shorter ones
- Enhanced cache expiration control for `CacheMode::IgnoreRules` mode
- `rate_limiter` field to `HttpCacheOptions` for cache-aware rate limiting that only applies on cache misses
- `CacheAwareRateLimiter` trait for implementing rate limiting strategies
- `DomainRateLimiter` for per-domain rate limiting using governor
- `DirectRateLimiter` for global rate limiting using governor
- New `rate-limiting` feature flag for optional rate limiting functionality
- Rate limiting support for streaming cache operations with seamless integration
- Simple LRU eviction policy for the `StreamingManager` with configurable size and entry limits
- Multi-runtime async support (tokio/smol) with `RwLock` for better async performance
- Content deduplication using Blake3 hashing for efficient storage
- Atomic file operations using temporary files and rename for safe concurrent access
- Configurable streaming buffer size for optimal streaming performance
- Lock-free reference counting using DashMap for concurrent access
- LRU cache implementation using the `lru` crate

### Changed

- `max_ttl` implementation automatically enforces cache duration limits by modifying response cache-control headers
- Documentation updated with comprehensive examples for `max_ttl` usage across all cache modes
- `StreamingCacheConfig` simplified to essential configuration options:
  - `max_cache_size`: Optional cache size limit for LRU eviction
  - `max_entries`: Optional entry count limit for LRU eviction  
  - `streaming_buffer_size`: Buffer size for streaming operations (default: 8192)
- Enhanced error types and handling for streaming cache operations
- Simplified `StreamingManager` implementation focused on core functionality and maintainability
- Removed unused background cleanup and persistent reference counting infrastructure for cleaner codebase
- Improved async compatibility across tokio and smol runtimes
- Upgraded concurrent data structures to use DashMap and LRU cache
- Replaced custom implementations with established library solutions

### Fixed

- Race conditions in reference counting during concurrent access
- Resource leaks in streaming cache operations when metadata write fails
- Unsafe unwrap operations in cache entry manipulation
- Inefficient URL construction replaced with safer url crate methods
- Improved error handling and recovery in streaming operations

## [1.0.0-alpha.1] - 2025-07-27

### Added

- New streaming cache architecture for handling large HTTP responses without buffering entirely in memory
- `StreamingCacheManager` trait for streaming-aware cache backends
- `HttpCacheStreamInterface` trait for composable streaming middleware patterns
- `HttpStreamingCache` struct for managing streaming cache operations
- `StreamingManager` implementation using file-based storage
- `StreamingBody` type for handling both buffered and streaming scenarios
- `CacheAnalysis` struct for better separation of cache decision logic
- `response_cache_mode_fn` field to `HttpCacheOptions` for per-response cache mode overrides
- New streaming feature flags: `streaming`, `streaming-tokio`, `streaming-smol`

### Changed

- Refactored `Middleware` trait for better composability
- Cache manager interfaces now support both buffered and streaming operations
- Enhanced separation of concerns with discrete analysis/lookup/processing steps
- Renamed `cacache-async-std` feature to `cacache-smol` for consistency
- MSRV updated to 1.82.0

## [0.21.0] - 2025-06-25

### Added

- `remove_opts` field to `CACacheManager` struct. This field is an instance of `cacache::RemoveOpts` that allows for customization of the removal options when deleting items from the cache.

- MSRV is now 1.82.0

## [0.20.1] - 2025-01-30

### Changed

- Fixed missing implementation of CacheMode::Reload variant logic.

- MSRV is now 1.81.1

- Updated the minimum versions of the following dependencies:
  - async-trait [0.1.85]
  - cacache [13.1.0]
  - httpdate [1.0.2]
  - moka [0.12.10]
  - serde [1.0.217]
  - url [2.5.4]

## [0.20.0] - 2024-11-12

### Added

- `cache_status_headers` field to `HttpCacheOptions` struct. This field is a boolean that determines if the cache status headers should be added to the response.

## [0.19.0] - 2024-04-10

### Changed

- Updated the minimum versions of the following dependencies:
  - cacache [13.0.0]
  - http [1.1.0]
  - http-cache-semantics [2.1.0]

## [0.18.0] - 2024-01-15

### Added

- `overridden_cache_mode` method to `Middleware` trait. This method allows for overriding any cache mode set in the configuration, including `cache_mode_fn`.

- Derive `Default` for the `CacheMode` enum with the mode `Default` selected to be used.

## [0.17.0] - 2023-11-01

### Added

- `cache_mode_fn` field to `HttpCacheOptions` struct. This is a closure that takes a `&http::request::Parts` and returns a `CacheMode` enum variant. This allows for the overriding of cache mode on a per-request basis.

- `cache_bust` field to `HttpCacheOptions` struct. This is 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.

### Changed

- Updated the minimum versions of the following dependencies:
  - cacache [12.0.0]

## [0.16.0] - 2023-09-28

### Added

- `can_cache_request` method to `HttpCache` struct. This can be used by client implementations to determine if the request should be cached.

- `run_no_cache` method to `HttpCache` struct. This should be run by client implementations if the request is determined to not be cached.

### Changed

- MSRV is now 1.67.1

## [0.15.0] - 2023-09-26

### Added

- `IgnoreRules` variant to the `CacheMode` enum. This mode will ignore the HTTP headers and always store a response given it was a 200 response. It will also ignore the staleness when retrieving a response from the cache, so expiration of the cached response will need to be handled manually. If there was no cached response it will create a normal request, and will update the cache with the response.

### Changed

- Updated the minimum versions of the following dependencies:
  - moka [0.12.0]

## [0.14.0] - 2023-07-28

### Added

- `cacache-async-std` feature, which enables `async_std` runtime support in the `cacache` backend manager. This feature is enabled by default.

- `cacache-tokio` feature, which enables `tokio` runtime support in the `cacache` backend manager. This feature is disabled by default.

### Changed

- Updated the minimum versions of the following dependencies:
  - async-std [1.12.0]
  - async-trait [0.1.72]
  - serde [1.0.178]
  - tokio [1.29.1]

## [0.13.0] - 2023-07-19

### Added

- `CacheKey` type, a closure that takes [`http::request::Parts`] and returns a [`String`].

- `HttpCacheOptions` struct that contains the cache key (`CacheKey`) and the cache options (`CacheOptions`).

### Changed

- `CacheManager` trait `get`, `put`, and `delete` methods now require a `cache_key` argument rather than `method` and `url` arguments. This allows for custom keys to be specified.

- Both the `CACacheManager` trait and `MokaManager` implementation have been updated to reflect the above change.

- Updated the minimum versions of the following dependencies:
  - async-trait [0.1.71]
  - moka [0.11.2]
  - serde [1.0.171]

## [0.12.0] - 2023-06-05

### Changed

- MSRV is now 1.66.1
- `CACacheManager` field `path` has changed to `std::path::PathBuf`

- Updated the minimum versions of the following dependencies:
  - cacache [11.6.0]
  - moka [0.11.1]
  - serde [1.0.163]
  - url [2.4.0]

## [0.11.0] - 2023-03-29

### Added

- `BoxError` type alias for `Box<dyn std::error::Error + Send + Sync>`.

- `BadVersion` error type for unknown http versions.

- `BadHeader` error type for bad http header values.

### Removed

- `CacheError` enum.

- The following dependencies:
  - anyhow
  - thiserror
  - miette

### Changed

- `CacheError` enum has been replaced in function by `Box<dyn std::error::Error + Send + Sync>`.

- `Result` typedef is now `std::result::Result<T, BoxError>`.

- `Error` type for the TryFrom implentation for the `HttpVersion` struct is now `BoxError` containing a `BadVersion` error.

- `CacheManager` trait `put` method now returns `Result<(), BoxError>`.

- Updated the minimum versions of the following dependencies:
  - async-trait [0.1.68]
  - cacache [11.4.0]
  - moka [0.10.1]
  - serde [1.0.159]

## [0.10.1] - 2023-03-08

### Changed

- Set conditional check for `CacheError::Bincode` to `cfg(feature = "bincode")`

## [0.10.0] - 2023-03-08

### Changed

- MSRV is now 1.63.0

- Updated the minimum versions of the following dependencies:
  - async-trait [0.1.66]
  - cacache [11.3.0]
  - serde [1.0.154]
  - thiserror [1.0.39]

## [0.9.2] - 2023-02-23

### Changed

- Updated the minimum versions of the following dependencies:
  - cacache [11.1.0]

## [0.9.1] - 2023-02-17

### Changed

- Updated the minimum versions of the following dependencies:
  - http [0.2.9]

## [0.9.0] - 2023-02-16

### Changed

- MSRV is now 1.62.1

- Updated the minimum versions of the following dependencies:
  - moka [0.10.0]

## [0.8.0] - 2023-02-07

### Changed

- MSRV is now 1.60.0

- Updated the minimum versions of the following dependencies:
  - anyhow [1.0.69]
  - async-trait [0.1.64]
  - cacache [11.0.0]
  - miette [5.5.0]
  - moka [0.9.7]
  - serde [1.0.152]
  - thiserror [1.0.38]

## [0.7.2] - 2022-11-16

- Added derive `Eq` to `HttpVersion` enum.

### Changed

## [0.7.1] - 2022-11-06

### Changed

- Updated the minimum versions of the following dependencies:
  - anyhow [1.0.66]
  - async-trait [0.1.58]
  - miette [5.4.1]
  - moka [0.9.6]
  - serde [1.0.147]
  - thiserror [1.0.37]
  - url [2.3.1]

## [0.7.0] - 2022-06-17

### Changed

- The `CacheManager` trait is now implemented directly against the `MokaManager` struct rather than `Arc<MokaManager>`. The Arc is now internal to the `MokaManager` struct as part of the `cache` field.

- Updated the minimum versions of the following dependencies:
  - async-trait [0.1.56]
  - http [0.2.8]
  - miette [4.7.1]
  - moka [0.8.5]
  - serde [1.0.137]
  - thiserror [1.0.31]

## [0.6.5] - 2022-04-30

### Changed

- Updated the minimum versions of the following dependencies:
  - http [0.2.7]

## [0.6.4] - 2022-04-26

### Added

- This changelog to keep a record of notable changes to the project.
