diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/tower-http/src/content_encoding.rs | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/tower-http/src/content_encoding.rs')
| -rw-r--r-- | vendor/tower-http/src/content_encoding.rs | 605 |
1 files changed, 0 insertions, 605 deletions
diff --git a/vendor/tower-http/src/content_encoding.rs b/vendor/tower-http/src/content_encoding.rs deleted file mode 100644 index 91c21d45..00000000 --- a/vendor/tower-http/src/content_encoding.rs +++ /dev/null @@ -1,605 +0,0 @@ -pub(crate) trait SupportedEncodings: Copy { - fn gzip(&self) -> bool; - fn deflate(&self) -> bool; - fn br(&self) -> bool; - fn zstd(&self) -> bool; -} - -// This enum's variants are ordered from least to most preferred. -#[derive(Copy, Clone, Debug, Ord, PartialOrd, PartialEq, Eq)] -pub(crate) enum Encoding { - #[allow(dead_code)] - Identity, - #[cfg(any(feature = "fs", feature = "compression-deflate"))] - Deflate, - #[cfg(any(feature = "fs", feature = "compression-gzip"))] - Gzip, - #[cfg(any(feature = "fs", feature = "compression-br"))] - Brotli, - #[cfg(any(feature = "fs", feature = "compression-zstd"))] - Zstd, -} - -impl Encoding { - #[allow(dead_code)] - fn to_str(self) -> &'static str { - match self { - #[cfg(any(feature = "fs", feature = "compression-gzip"))] - Encoding::Gzip => "gzip", - #[cfg(any(feature = "fs", feature = "compression-deflate"))] - Encoding::Deflate => "deflate", - #[cfg(any(feature = "fs", feature = "compression-br"))] - Encoding::Brotli => "br", - #[cfg(any(feature = "fs", feature = "compression-zstd"))] - Encoding::Zstd => "zstd", - Encoding::Identity => "identity", - } - } - - #[cfg(feature = "fs")] - pub(crate) fn to_file_extension(self) -> Option<&'static std::ffi::OsStr> { - match self { - Encoding::Gzip => Some(std::ffi::OsStr::new(".gz")), - Encoding::Deflate => Some(std::ffi::OsStr::new(".zz")), - Encoding::Brotli => Some(std::ffi::OsStr::new(".br")), - Encoding::Zstd => Some(std::ffi::OsStr::new(".zst")), - Encoding::Identity => None, - } - } - - #[allow(dead_code)] - pub(crate) fn into_header_value(self) -> http::HeaderValue { - http::HeaderValue::from_static(self.to_str()) - } - - #[cfg(any( - feature = "compression-gzip", - feature = "compression-br", - feature = "compression-deflate", - feature = "compression-zstd", - feature = "fs", - ))] - fn parse(s: &str, _supported_encoding: impl SupportedEncodings) -> Option<Encoding> { - #[cfg(any(feature = "fs", feature = "compression-gzip"))] - if (s.eq_ignore_ascii_case("gzip") || s.eq_ignore_ascii_case("x-gzip")) - && _supported_encoding.gzip() - { - return Some(Encoding::Gzip); - } - - #[cfg(any(feature = "fs", feature = "compression-deflate"))] - if s.eq_ignore_ascii_case("deflate") && _supported_encoding.deflate() { - return Some(Encoding::Deflate); - } - - #[cfg(any(feature = "fs", feature = "compression-br"))] - if s.eq_ignore_ascii_case("br") && _supported_encoding.br() { - return Some(Encoding::Brotli); - } - - #[cfg(any(feature = "fs", feature = "compression-zstd"))] - if s.eq_ignore_ascii_case("zstd") && _supported_encoding.zstd() { - return Some(Encoding::Zstd); - } - - if s.eq_ignore_ascii_case("identity") { - return Some(Encoding::Identity); - } - - None - } - - #[cfg(any( - feature = "compression-gzip", - feature = "compression-br", - feature = "compression-zstd", - feature = "compression-deflate", - ))] - // based on https://github.com/http-rs/accept-encoding - pub(crate) fn from_headers( - headers: &http::HeaderMap, - supported_encoding: impl SupportedEncodings, - ) -> Self { - Encoding::preferred_encoding(encodings(headers, supported_encoding)) - .unwrap_or(Encoding::Identity) - } - - #[cfg(any( - feature = "compression-gzip", - feature = "compression-br", - feature = "compression-zstd", - feature = "compression-deflate", - feature = "fs", - ))] - pub(crate) fn preferred_encoding( - accepted_encodings: impl Iterator<Item = (Encoding, QValue)>, - ) -> Option<Self> { - accepted_encodings - .filter(|(_, qvalue)| qvalue.0 > 0) - .max_by_key(|&(encoding, qvalue)| (qvalue, encoding)) - .map(|(encoding, _)| encoding) - } -} - -// Allowed q-values are numbers between 0 and 1 with at most 3 digits in the fractional part. They -// are presented here as an unsigned integer between 0 and 1000. -#[cfg(any( - feature = "compression-gzip", - feature = "compression-br", - feature = "compression-zstd", - feature = "compression-deflate", - feature = "fs", -))] -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) struct QValue(u16); - -#[cfg(any( - feature = "compression-gzip", - feature = "compression-br", - feature = "compression-zstd", - feature = "compression-deflate", - feature = "fs", -))] -impl QValue { - #[inline] - pub(crate) fn one() -> Self { - Self(1000) - } - - // Parse a q-value as specified in RFC 7231 section 5.3.1. - fn parse(s: &str) -> Option<Self> { - let mut c = s.chars(); - // Parse "q=" (case-insensitively). - match c.next() { - Some('q' | 'Q') => (), - _ => return None, - }; - match c.next() { - Some('=') => (), - _ => return None, - }; - - // Parse leading digit. Since valid q-values are between 0.000 and 1.000, only "0" and "1" - // are allowed. - let mut value = match c.next() { - Some('0') => 0, - Some('1') => 1000, - _ => return None, - }; - - // Parse optional decimal point. - match c.next() { - Some('.') => (), - None => return Some(Self(value)), - _ => return None, - }; - - // Parse optional fractional digits. The value of each digit is multiplied by `factor`. - // Since the q-value is represented as an integer between 0 and 1000, `factor` is `100` for - // the first digit, `10` for the next, and `1` for the digit after that. - let mut factor = 100; - loop { - match c.next() { - Some(n @ '0'..='9') => { - // If `factor` is less than `1`, three digits have already been parsed. A - // q-value having more than 3 fractional digits is invalid. - if factor < 1 { - return None; - } - // Add the digit's value multiplied by `factor` to `value`. - value += factor * (n as u16 - '0' as u16); - } - None => { - // No more characters to parse. Check that the value representing the q-value is - // in the valid range. - return if value <= 1000 { - Some(Self(value)) - } else { - None - }; - } - _ => return None, - }; - factor /= 10; - } - } -} - -#[cfg(any( - feature = "compression-gzip", - feature = "compression-br", - feature = "compression-zstd", - feature = "compression-deflate", - feature = "fs", -))] -// based on https://github.com/http-rs/accept-encoding -pub(crate) fn encodings<'a>( - headers: &'a http::HeaderMap, - supported_encoding: impl SupportedEncodings + 'a, -) -> impl Iterator<Item = (Encoding, QValue)> + 'a { - headers - .get_all(http::header::ACCEPT_ENCODING) - .iter() - .filter_map(|hval| hval.to_str().ok()) - .flat_map(|s| s.split(',')) - .filter_map(move |v| { - let mut v = v.splitn(2, ';'); - - let encoding = match Encoding::parse(v.next().unwrap().trim(), supported_encoding) { - Some(encoding) => encoding, - None => return None, // ignore unknown encodings - }; - - let qval = if let Some(qval) = v.next() { - QValue::parse(qval.trim())? - } else { - QValue::one() - }; - - Some((encoding, qval)) - }) -} - -#[cfg(all( - test, - feature = "compression-gzip", - feature = "compression-deflate", - feature = "compression-br", - feature = "compression-zstd", -))] -mod tests { - use super::*; - - #[derive(Copy, Clone, Default)] - struct SupportedEncodingsAll; - - impl SupportedEncodings for SupportedEncodingsAll { - fn gzip(&self) -> bool { - true - } - - fn deflate(&self) -> bool { - true - } - - fn br(&self) -> bool { - true - } - - fn zstd(&self) -> bool { - true - } - } - - #[test] - fn no_accept_encoding_header() { - let encoding = Encoding::from_headers(&http::HeaderMap::new(), SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - } - - #[test] - fn accept_encoding_header_single_encoding() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Gzip, encoding); - } - - #[test] - fn accept_encoding_header_two_encodings() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip,br"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_gzip_x_gzip() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip,x-gzip"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Gzip, encoding); - } - - #[test] - fn accept_encoding_header_x_gzip_deflate() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("deflate,x-gzip"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Gzip, encoding); - } - - #[test] - fn accept_encoding_header_three_encodings() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip,deflate,br"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_two_encodings_with_one_qvalue() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5,br"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_three_encodings_with_one_qvalue() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5,deflate,br"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn two_accept_encoding_headers_with_one_qvalue() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5"), - ); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("br"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn two_accept_encoding_headers_three_encodings_with_one_qvalue() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5,deflate"), - ); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("br"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn three_accept_encoding_headers_with_one_qvalue() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5"), - ); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("deflate"), - ); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("br"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_two_encodings_with_two_qvalues() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5,br;q=0.8"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.8,br;q=0.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Gzip, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.995,br;q=0.999"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_three_encodings_with_three_qvalues() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5,deflate;q=0.6,br;q=0.8"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.8,deflate;q=0.6,br;q=0.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Gzip, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.6,deflate;q=0.8,br;q=0.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Deflate, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.995,deflate;q=0.997,br;q=0.999"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_invalid_encdoing() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("invalid,gzip"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Gzip, encoding); - } - - #[test] - fn accept_encoding_header_with_qvalue_zero() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0."), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0,br;q=0.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_with_uppercase_letters() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gZiP"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Gzip, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5,br;Q=0.8"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_with_allowed_spaces() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static(" gzip\t; q=0.5 ,\tbr ;\tq=0.8\t"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Brotli, encoding); - } - - #[test] - fn accept_encoding_header_with_invalid_spaces() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q =0.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q= 0.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - } - - #[test] - fn accept_encoding_header_with_invalid_quvalues() { - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=-0.1"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=00.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=0.5000"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=.5"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=1.01"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - - let mut headers = http::HeaderMap::new(); - headers.append( - http::header::ACCEPT_ENCODING, - http::HeaderValue::from_static("gzip;q=1.001"), - ); - let encoding = Encoding::from_headers(&headers, SupportedEncodingsAll); - assert_eq!(Encoding::Identity, encoding); - } -} |
