tower_http_cache_plus/cache/middleware/
request.rs1use super::{super::key::*, configuration::*, hooks::*};
2
3use {
4 http::*,
5 kutil::{http::*, transcoding::*},
6};
7
8pub trait CacheableEncodableRequest<RequestBodyT> {
14 fn should_skip_cache<CacheT, CacheKeyT>(
16 &self,
17 configuration: &MiddlewareCachingConfiguration<RequestBodyT, CacheT, CacheKeyT>,
18 ) -> bool;
19
20 fn cache_key_with_hook<CacheT, CacheKeyT>(
22 &self,
23 configuration: &MiddlewareCachingConfiguration<RequestBodyT, CacheT, CacheKeyT>,
24 ) -> CacheKeyT
25 where
26 CacheKeyT: CacheKey;
27
28 fn select_encoding(&self, configuration: &MiddlewareEncodingConfiguration) -> Encoding;
30}
31
32impl<RequestBodyT> CacheableEncodableRequest<RequestBodyT> for Request<RequestBodyT> {
33 fn should_skip_cache<CacheT, CacheKeyT>(
34 &self,
35 configuration: &MiddlewareCachingConfiguration<RequestBodyT, CacheT, CacheKeyT>,
36 ) -> bool {
37 let mut skip_cache = if !configuration.cache.is_none() {
38 let method = self.method();
39 if method.is_idempotent() {
40 false
41 } else {
42 tracing::debug!("skip (non-idempotent {})", method);
43 true
44 }
45 } else {
46 tracing::debug!("skip (disabled)");
47 true
48 };
49
50 if !skip_cache
51 && let Some(cacheable) = &configuration.cacheable_by_request
52 && !cacheable(CacheableHookContext::new(self.uri(), self.headers()))
53 {
54 tracing::debug!("skip (cacheable_by_request=false)");
55 skip_cache = true;
56 }
57
58 skip_cache
59 }
60
61 fn cache_key_with_hook<CacheT, CacheKeyT>(
62 &self,
63 configuration: &MiddlewareCachingConfiguration<RequestBodyT, CacheT, CacheKeyT>,
64 ) -> CacheKeyT
65 where
66 CacheKeyT: CacheKey,
67 {
68 let mut cache_key = self.cache_key();
69
70 if let Some(cache_key_hook) = &configuration.cache_key {
71 cache_key_hook(CacheKeyHookContext::new(&mut cache_key, self));
72 }
73
74 cache_key
75 }
76
77 fn select_encoding(&self, configuration: &MiddlewareEncodingConfiguration) -> Encoding {
78 let encoding = match &configuration.enabled_encodings_by_preference {
79 Some(enabled_encodings) => {
80 if !enabled_encodings.is_empty() {
81 self.headers()
82 .accept_encoding()
83 .best(enabled_encodings)
84 .cloned()
85 .unwrap_or_default()
86 .into()
87 } else {
88 return Encoding::Identity;
89 }
90 }
91
92 None => return Encoding::Identity,
93 };
94
95 if encoding != Encoding::Identity
96 && let Some(encodable) = &configuration.encodable_by_request
97 && !encodable(EncodableHookContext::new(
98 &encoding,
99 self.uri(),
100 self.headers(),
101 ))
102 {
103 tracing::debug!("not encoding to {} (encodable_by_request=false)", encoding);
104 return Encoding::Identity;
105 }
106
107 encoding
108 }
109}