1pub use crate::HeaderMap;
3#[doc(hidden)]
4pub use crate::map::{AsName, Either, GetAll, Iter, Value};
5pub use crate::value::{HeaderValue, InvalidHeaderValue, ToStrError};
6
7pub use http::header::{
8 ACCEPT, ACCEPT_CHARSET, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES,
9 ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS,
10 ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE,
11 ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, AGE, ALLOW, ALT_SVC,
12 AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING,
13 CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION, CONTENT_RANGE, CONTENT_SECURITY_POLICY,
14 CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, DATE, DNT, ETAG, EXPECT, EXPIRES,
15 FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE,
16 IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK, LOCATION, MAX_FORWARDS, ORIGIN, PRAGMA,
17 PROXY_AUTHENTICATE, PROXY_AUTHORIZATION, PUBLIC_KEY_PINS, PUBLIC_KEY_PINS_REPORT_ONLY, RANGE,
18 REFERER, REFERRER_POLICY, REFRESH, RETRY_AFTER, SEC_WEBSOCKET_ACCEPT, SEC_WEBSOCKET_EXTENSIONS,
19 SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL, SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE,
20 STRICT_TRANSPORT_SECURITY, TE, TRAILER, TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS,
21 USER_AGENT, VARY, VIA, WARNING, WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS,
22 X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS, X_XSS_PROTECTION,
23};
24pub use http::header::{HeaderName, InvalidHeaderName};
25
26#[derive(Copy, Clone, PartialEq, Eq, Debug)]
28pub enum ContentEncoding {
29 Auto,
31 Br,
33 Deflate,
35 Gzip,
37 Zstd,
39 Identity,
41}
42
43impl ContentEncoding {
44 #[inline]
45 pub fn is_compressed(self) -> bool {
47 !matches!(self, ContentEncoding::Identity | ContentEncoding::Auto)
48 }
49
50 #[inline]
51 pub fn as_str(self) -> &'static str {
53 match self {
54 ContentEncoding::Br => "br",
55 ContentEncoding::Gzip => "gzip",
56 ContentEncoding::Deflate => "deflate",
57 ContentEncoding::Zstd => "zstd",
58 ContentEncoding::Identity | ContentEncoding::Auto => "identity",
59 }
60 }
61
62 #[inline]
63 pub fn quality(self) -> f64 {
65 match self {
66 ContentEncoding::Br => 1.1,
67 ContentEncoding::Zstd => 1.05,
68 ContentEncoding::Gzip => 1.0,
69 ContentEncoding::Deflate => 0.9,
70 ContentEncoding::Identity | ContentEncoding::Auto => 0.1,
71 }
72 }
73}
74
75impl<'a> From<&'a str> for ContentEncoding {
76 fn from(s: &'a str) -> ContentEncoding {
77 let s = s.trim();
78
79 if s.eq_ignore_ascii_case("br") {
80 ContentEncoding::Br
81 } else if s.eq_ignore_ascii_case("gzip") || s.eq_ignore_ascii_case("x-gzip") {
82 ContentEncoding::Gzip
83 } else if s.eq_ignore_ascii_case("deflate") {
84 ContentEncoding::Deflate
85 } else if s.eq_ignore_ascii_case("zstd") {
86 ContentEncoding::Zstd
87 } else {
88 ContentEncoding::Identity
89 }
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn encoding() {
99 assert!(ContentEncoding::Br.is_compressed());
100 assert!(!ContentEncoding::Identity.is_compressed());
101 assert!(!ContentEncoding::Auto.is_compressed());
102 assert_eq!(format!("{:?}", ContentEncoding::Identity), "Identity");
103
104 assert!(ContentEncoding::Zstd.is_compressed());
105 assert_eq!(ContentEncoding::Zstd.as_str(), "zstd");
106 assert_eq!(ContentEncoding::from(" ZStd "), ContentEncoding::Zstd);
107 assert_eq!(ContentEncoding::from("X-Gzip"), ContentEncoding::Gzip);
108 assert_eq!(ContentEncoding::from("x-zstd"), ContentEncoding::Identity);
109 assert!(ContentEncoding::Br.quality() > ContentEncoding::Zstd.quality());
110 assert!(ContentEncoding::Zstd.quality() > ContentEncoding::Gzip.quality());
111 }
112}