diff --git a/http-cache-quickcache/src/test.rs b/http-cache-quickcache/src/test.rs index f93057b..aa73d41 100644 --- a/http-cache-quickcache/src/test.rs +++ b/http-cache-quickcache/src/test.rs @@ -126,6 +126,7 @@ async fn default_mode_with_options() -> Result<()> { cache_bust: None, cache_status_headers: true, max_ttl: None, + modify_response: None, }, })) .build(); diff --git a/http-cache/src/lib.rs b/http-cache/src/lib.rs index f1b15e1..289c8f5 100644 --- a/http-cache/src/lib.rs +++ b/http-cache/src/lib.rs @@ -959,6 +959,9 @@ pub type CacheBust = Arc< + Sync, >; +/// A closure that takes a mutable reference to [`HttpResponse`] and modifies it before caching. +pub type ModifyResponse = Arc; + /// Configuration options for customizing HTTP cache behavior on a per-request basis. /// /// This struct allows you to override default caching behavior for individual requests @@ -1081,6 +1084,8 @@ pub struct HttpCacheOptions { pub response_cache_mode_fn: Option, /// Bust the caches of the returned keys. pub cache_bust: Option, + /// Modifies the response before storing it in the cache. + pub modify_response: Option, /// Determines if the cache status headers should be added to the response. pub cache_status_headers: bool, /// Maximum time-to-live for cached responses. @@ -1103,6 +1108,7 @@ impl Default for HttpCacheOptions { cache_mode_fn: None, response_cache_mode_fn: None, cache_bust: None, + modify_response: None, cache_status_headers: true, max_ttl: None, #[cfg(feature = "rate-limiting")] @@ -1124,6 +1130,7 @@ impl Debug for HttpCacheOptions { &"Fn(&request::Parts, &HttpResponse) -> Option", ) .field("cache_bust", &"Fn(&request::Parts) -> Vec") + .field("modify_response", &"Fn(&mut ModifyResponse)") .field("cache_status_headers", &self.cache_status_headers) .field("max_ttl", &self.max_ttl) .field("rate_limiter", &"Option") @@ -1141,6 +1148,7 @@ impl Debug for HttpCacheOptions { &"Fn(&request::Parts, &HttpResponse) -> Option", ) .field("cache_bust", &"Fn(&request::Parts) -> Vec") + .field("modify_response", &"Fn(&mut ModifyResponse)") .field("cache_status_headers", &self.cache_status_headers) .field("max_ttl", &self.max_ttl) .finish() @@ -1238,6 +1246,13 @@ impl HttpCacheOptions { original_mode } + /// Modifies the response before caching if a modifier function is provided + fn modify_response_before_caching(&self, response: &mut HttpResponse) { + if let Some(modify_response) = &self.modify_response { + modify_response(response); + } + } + /// Creates a cache policy for the given request and response fn create_cache_policy( &self, @@ -1600,6 +1615,7 @@ impl HttpCache { ); if is_cacheable { + self.options.modify_response_before_caching(&mut res); Ok(self .manager .put(self.options.create_cache_key(&parts, None), res, policy) @@ -1676,6 +1692,8 @@ impl HttpCache { cached_res.cache_status(HitOrMiss::HIT); cached_res.cache_lookup_status(HitOrMiss::HIT); } + self.options + .modify_response_before_caching(&mut cached_res); let res = self .manager .put( @@ -1695,6 +1713,7 @@ impl HttpCache { cond_res.cache_status(HitOrMiss::MISS); cond_res.cache_lookup_status(HitOrMiss::HIT); } + self.options.modify_response_before_caching(&mut cond_res); let res = self .manager .put(