From 3f3a1ec80053507dd321cfff73177e63775f5a8e Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sat, 17 Feb 2024 14:45:46 +0100 Subject: [PATCH] Optimize encoding selection for compression middleware --- tower-http/src/content_encoding.rs | 22 +++++++++---------- tower-http/src/services/fs/serve_dir/mod.rs | 5 +++-- .../src/services/fs/serve_dir/open_file.rs | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tower-http/src/content_encoding.rs b/tower-http/src/content_encoding.rs index 11860726..a0e60a3c 100644 --- a/tower-http/src/content_encoding.rs +++ b/tower-http/src/content_encoding.rs @@ -100,7 +100,7 @@ impl Encoding { headers: &http::HeaderMap, supported_encoding: impl SupportedEncodings, ) -> Self { - Encoding::preferred_encoding(&encodings(headers, supported_encoding)) + Encoding::preferred_encoding(encodings(headers, supported_encoding)) .unwrap_or(Encoding::Identity) } @@ -111,12 +111,13 @@ impl Encoding { feature = "compression-deflate", feature = "fs", ))] - pub(crate) fn preferred_encoding(accepted_encodings: &[(Encoding, QValue)]) -> Option { + pub(crate) fn preferred_encoding( + accepted_encodings: impl Iterator, + ) -> Option { accepted_encodings - .iter() .filter(|(_, qvalue)| qvalue.0 > 0) - .max_by_key(|(encoding, qvalue)| (qvalue, encoding)) - .map(|(encoding, _)| *encoding) + .max_by_key(|&(encoding, qvalue)| (qvalue, encoding)) + .map(|(encoding, _)| encoding) } } @@ -212,16 +213,16 @@ impl QValue { feature = "fs", ))] // based on https://github.com/http-rs/accept-encoding -pub(crate) fn encodings( - headers: &http::HeaderMap, - supported_encoding: impl SupportedEncodings, -) -> Vec<(Encoding, QValue)> { +pub(crate) fn encodings<'a>( + headers: &'a http::HeaderMap, + supported_encoding: impl SupportedEncodings + 'a, +) -> impl Iterator + 'a { headers .get_all(http::header::ACCEPT_ENCODING) .iter() .filter_map(|hval| hval.to_str().ok()) .flat_map(|s| s.split(',')) - .filter_map(|v| { + .filter_map(move |v| { let mut v = v.splitn(2, ';'); let encoding = match Encoding::parse(v.next().unwrap().trim(), supported_encoding) { @@ -237,7 +238,6 @@ pub(crate) fn encodings( Some((encoding, qval)) }) - .collect::>() } #[cfg(all( diff --git a/tower-http/src/services/fs/serve_dir/mod.rs b/tower-http/src/services/fs/serve_dir/mod.rs index ed643d56..61b956d1 100644 --- a/tower-http/src/services/fs/serve_dir/mod.rs +++ b/tower-http/src/services/fs/serve_dir/mod.rs @@ -365,10 +365,11 @@ impl ServeDir { .and_then(|value| value.to_str().ok()) .map(|s| s.to_owned()); - let negotiated_encodings = encodings( + let negotiated_encodings: Vec<_> = encodings( req.headers(), self.precompressed_variants.unwrap_or_default(), - ); + ) + .collect(); let variant = self.variant.clone(); diff --git a/tower-http/src/services/fs/serve_dir/open_file.rs b/tower-http/src/services/fs/serve_dir/open_file.rs index 57d85d44..1bf27062 100644 --- a/tower-http/src/services/fs/serve_dir/open_file.rs +++ b/tower-http/src/services/fs/serve_dir/open_file.rs @@ -176,7 +176,7 @@ fn preferred_encoding( path: &mut PathBuf, negotiated_encoding: &[(Encoding, QValue)], ) -> Option { - let preferred_encoding = Encoding::preferred_encoding(negotiated_encoding); + let preferred_encoding = Encoding::preferred_encoding(negotiated_encoding.iter().copied()); if let Some(file_extension) = preferred_encoding.and_then(|encoding| encoding.to_file_extension())