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