From 324e94702d05caa8940eb1e2b378c2eca49089b9 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Mon, 7 Feb 2022 01:16:00 +0100 Subject: [PATCH 1/9] init typed headers --- src/headers/header.rs | 20 ++++---------------- src/headers/headers.rs | 36 +++++++++++------------------------- src/lib.rs | 3 +++ 3 files changed, 18 insertions(+), 41 deletions(-) diff --git a/src/headers/header.rs b/src/headers/header.rs index df2f07bc..0679adec 100644 --- a/src/headers/header.rs +++ b/src/headers/header.rs @@ -4,32 +4,20 @@ use crate::headers::{HeaderName, HeaderValue, Headers}; /// A trait representing a [`HeaderName`] and [`HeaderValue`] pair. pub trait Header { - /// Access the header's name. + /// The header's name. fn header_name(&self) -> HeaderName; /// Access the header's value. fn header_value(&self) -> HeaderValue; - - /// Insert the header name and header value into something that looks like a - /// [`Headers`] map. - fn apply_header>(&self, mut headers: H) { - let name = self.header_name(); - let value = self.header_value(); - - // The value should already have been validated when it was created, so this should - // possibly be done with an unsafe call - headers.as_mut().insert(name, value).unwrap(); - } } -impl<'a, 'b> Header for (&'a str, &'b str) { +impl Header for (HeaderName, HeaderValue) { fn header_name(&self) -> HeaderName { - HeaderName::from(self.0) + self.0 } fn header_value(&self) -> HeaderValue { - HeaderValue::from_bytes(self.1.to_owned().into_bytes()) - .expect("String slice should be valid ASCII") + self.1 } } diff --git a/src/headers/headers.rs b/src/headers/headers.rs index a7a9d90e..25198e42 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -8,7 +8,7 @@ use std::ops::Index; use std::str::FromStr; use crate::headers::{ - HeaderName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, + Header, HeaderName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, }; /// A collection of HTTP Headers. @@ -29,7 +29,7 @@ use crate::headers::{ /// ``` #[derive(Clone)] pub struct Headers { - pub(crate) headers: HashMap, + pub(crate) headers: HashMap>, } impl Headers { @@ -45,35 +45,21 @@ impl Headers { /// Not that this will replace all header values for a given header name. /// If you wish to add header values for a header name that already exists /// use `Headers::append` - pub fn insert( - &mut self, - name: impl Into, - values: impl ToHeaderValues, - ) -> crate::Result> { - let name = name.into(); - let values: HeaderValues = values.to_header_values()?.collect(); - Ok(self.headers.insert(name, values)) + pub fn insert(&mut self, header: H) -> Option { + let name = header.header_name(); + let value = header.header_value(); + self.headers.insert(name, value) } /// Append a header to the headers. /// /// Unlike `insert` this function will not override the contents of a header, but insert a /// header if there aren't any. Or else append to the existing list of headers. - pub fn append( - &mut self, - name: impl Into, - values: impl ToHeaderValues, - ) -> crate::Result<()> { - let name = name.into(); - match self.get_mut(&name) { - Some(headers) => { - let mut values: HeaderValues = values.to_header_values()?.collect(); - headers.append(&mut values); - } - None => { - self.insert(name, values)?; - } - } + pub fn append(&mut self, header: H) -> crate::Result<()> { + let name = header.header_name(); + let value = header.header_value(); + let mut headers = self.headers.entry(name).or_default(); + headers.push(value); Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index c8821a41..eb24affb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -155,6 +155,9 @@ pub use version::Version; #[doc(inline)] pub use crate::url::Url; +#[doc(inline)] +pub use crate::headers::Header; + pub mod security; pub mod trailers; From c99a9e06062867896c50b209ca92b85f197fd1dc Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Mon, 7 Feb 2022 01:54:58 +0100 Subject: [PATCH 2/9] done for the day next up: try to use a typemap for the headers --- Cargo.toml | 2 +- src/auth/authorization.rs | 2 +- src/auth/basic_auth.rs | 2 +- src/auth/www_authenticate.rs | 2 +- src/cache/age.rs | 2 +- src/cache/cache_control/mod.rs | 2 +- src/cache/expires.rs | 2 +- src/conditional/etag.rs | 4 ++-- src/conditional/if_modified_since.rs | 2 +- src/conditional/if_unmodified_since.rs | 2 +- src/conditional/last_modified.rs | 2 +- src/content/accept.rs | 10 ++++----- src/content/accept_encoding.rs | 10 ++++----- src/content/content_length.rs | 2 +- src/content/content_location.rs | 2 +- src/content/content_type.rs | 2 +- src/headers/header.rs | 18 +++++++++++++-- src/headers/headers.rs | 27 +++++++---------------- src/other/date.rs | 2 +- src/other/expect.rs | 2 +- src/other/referer.rs | 2 +- src/other/retry_after.rs | 4 ++-- src/other/source_map.rs | 2 +- src/security/strict_transport_security.rs | 2 +- src/security/timing_allow_origin.rs | 6 ++--- src/server/allow.rs | 2 +- src/trace/server_timing/mod.rs | 4 ++-- src/transfer/te.rs | 10 ++++----- 28 files changed, 67 insertions(+), 64 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e63b41ec..267e3700 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ keywords = ["http", "types", "request", "response", "h2"] categories = ["asynchronous", "web-programming", "web-programming::http-client", "web-programming::http-server", "web-programming::websocket"] authors = ["Yoshua Wuyts "] readme = "README.md" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] features = ["docs"] diff --git a/src/auth/authorization.rs b/src/auth/authorization.rs index cf2f2ddb..525a8806 100644 --- a/src/auth/authorization.rs +++ b/src/auth/authorization.rs @@ -117,7 +117,7 @@ mod test { let authz = Authorization::new(scheme, credentials.into()); let mut headers = Headers::new(); - authz.apply_header(&mut headers); + headers.insert(authz); let authz = Authorization::from_headers(headers)?.unwrap(); diff --git a/src/auth/basic_auth.rs b/src/auth/basic_auth.rs index 664cfcb5..3dae6127 100644 --- a/src/auth/basic_auth.rs +++ b/src/auth/basic_auth.rs @@ -123,7 +123,7 @@ mod test { let authz = BasicAuth::new(username, password); let mut headers = Headers::new(); - authz.apply_header(&mut headers); + headers.insert(authz); let authz = BasicAuth::from_headers(headers)?.unwrap(); diff --git a/src/auth/www_authenticate.rs b/src/auth/www_authenticate.rs index bf9d7a05..d777a7fc 100644 --- a/src/auth/www_authenticate.rs +++ b/src/auth/www_authenticate.rs @@ -139,7 +139,7 @@ mod test { let authz = WwwAuthenticate::new(scheme, realm.into()); let mut headers = Headers::new(); - authz.apply_header(&mut headers); + headers.insert(authz); assert_eq!( headers["WWW-Authenticate"], diff --git a/src/cache/age.rs b/src/cache/age.rs index 0ee78a00..0b3aa0cb 100644 --- a/src/cache/age.rs +++ b/src/cache/age.rs @@ -92,7 +92,7 @@ mod test { let age = Age::new(Duration::from_secs(12)); let mut headers = Headers::new(); - age.apply_header(&mut headers); + headers.insert(age); let age = Age::from_headers(headers)?.unwrap(); assert_eq!(age, Age::new(Duration::from_secs(12))); diff --git a/src/cache/cache_control/mod.rs b/src/cache/cache_control/mod.rs index f9150363..6eecf275 100644 --- a/src/cache/cache_control/mod.rs +++ b/src/cache/cache_control/mod.rs @@ -25,7 +25,7 @@ mod test { entries.push(CacheDirective::NoStore); let mut headers = Headers::new(); - entries.apply_header(&mut headers); + headers.insert(entries); let entries = CacheControl::from_headers(headers)?.unwrap(); let mut entries = entries.iter(); diff --git a/src/cache/expires.rs b/src/cache/expires.rs index 89c4e6f4..a82aff16 100644 --- a/src/cache/expires.rs +++ b/src/cache/expires.rs @@ -94,7 +94,7 @@ mod test { let expires = Expires::new_at(time); let mut headers = Headers::new(); - expires.apply_header(&mut headers); + headers.insert(expires); let expires = Expires::from_headers(headers)?.unwrap(); diff --git a/src/conditional/etag.rs b/src/conditional/etag.rs index c7245f86..1122cedc 100644 --- a/src/conditional/etag.rs +++ b/src/conditional/etag.rs @@ -142,7 +142,7 @@ mod test { let etag = ETag::new("0xcafebeef".to_string()); let mut headers = Headers::new(); - etag.apply_header(&mut headers); + headers.insert(etag); let etag = ETag::from_headers(headers)?.unwrap(); assert_eq!(etag, ETag::Strong(String::from("0xcafebeef"))); @@ -154,7 +154,7 @@ mod test { let etag = ETag::new_weak("0xcafebeef".to_string()); let mut headers = Headers::new(); - etag.apply_header(&mut headers); + headers.insert(etag); let etag = ETag::from_headers(headers)?.unwrap(); assert_eq!(etag, ETag::Weak(String::from("0xcafebeef"))); diff --git a/src/conditional/if_modified_since.rs b/src/conditional/if_modified_since.rs index e5566a12..b0cc6cf4 100644 --- a/src/conditional/if_modified_since.rs +++ b/src/conditional/if_modified_since.rs @@ -91,7 +91,7 @@ mod test { let expires = IfModifiedSince::new(time); let mut headers = Headers::new(); - expires.apply_header(&mut headers); + headers.insert(expires); let expires = IfModifiedSince::from_headers(headers)?.unwrap(); diff --git a/src/conditional/if_unmodified_since.rs b/src/conditional/if_unmodified_since.rs index 2d964271..65fa48c7 100644 --- a/src/conditional/if_unmodified_since.rs +++ b/src/conditional/if_unmodified_since.rs @@ -91,7 +91,7 @@ mod test { let expires = IfUnmodifiedSince::new(time); let mut headers = Headers::new(); - expires.apply_header(&mut headers); + headers.insert(expires); let expires = IfUnmodifiedSince::from_headers(headers)?.unwrap(); diff --git a/src/conditional/last_modified.rs b/src/conditional/last_modified.rs index dc71fc1b..c7fbd88e 100644 --- a/src/conditional/last_modified.rs +++ b/src/conditional/last_modified.rs @@ -90,7 +90,7 @@ mod test { let last_modified = LastModified::new(time); let mut headers = Headers::new(); - last_modified.apply_header(&mut headers); + last_headers.insert(modified); let last_modified = LastModified::from_headers(headers)?.unwrap(); diff --git a/src/content/accept.rs b/src/content/accept.rs index 87dad909..6fb8f880 100644 --- a/src/content/accept.rs +++ b/src/content/accept.rs @@ -298,7 +298,7 @@ mod test { accept.push(mime::HTML); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = Accept::from_headers(headers)?.unwrap(); assert_eq!(accept.iter().next().unwrap(), mime::HTML); @@ -311,7 +311,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = Accept::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -325,7 +325,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = Accept::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -340,7 +340,7 @@ mod test { accept.push(mime::XML); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = Accept::from_headers(headers)?.unwrap(); let mut accept = accept.iter(); @@ -357,7 +357,7 @@ mod test { accept.push(MediaTypeProposal::new(mime::PLAIN, Some(0.8))?); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let mut accept = Accept::from_headers(headers)?.unwrap(); accept.sort(); diff --git a/src/content/accept_encoding.rs b/src/content/accept_encoding.rs index 5c469a40..2de56356 100644 --- a/src/content/accept_encoding.rs +++ b/src/content/accept_encoding.rs @@ -291,7 +291,7 @@ mod test { accept.push(Encoding::Gzip); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); assert_eq!(accept.iter().next().unwrap(), Encoding::Gzip); @@ -304,7 +304,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -318,7 +318,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -333,7 +333,7 @@ mod test { accept.push(Encoding::Brotli); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); let mut accept = accept.iter(); @@ -350,7 +350,7 @@ mod test { accept.push(EncodingProposal::new(Encoding::Brotli, Some(0.8))?); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let mut accept = AcceptEncoding::from_headers(headers)?.unwrap(); accept.sort(); diff --git a/src/content/content_length.rs b/src/content/content_length.rs index 4bae42f2..1de66b1c 100644 --- a/src/content/content_length.rs +++ b/src/content/content_length.rs @@ -84,7 +84,7 @@ mod test { let content_len = ContentLength::new(12); let mut headers = Headers::new(); - content_len.apply_header(&mut headers); + content_headers.insert(len); let content_len = ContentLength::from_headers(headers)?.unwrap(); assert_eq!(content_len.len(), 12); diff --git a/src/content/content_location.rs b/src/content/content_location.rs index 61c09135..816d240b 100644 --- a/src/content/content_location.rs +++ b/src/content/content_location.rs @@ -103,7 +103,7 @@ mod test { let content_location = ContentLocation::new(Url::parse("https://example.net/test.json")?); let mut headers = Headers::new(); - content_location.apply_header(&mut headers); + content_headers.insert(location); let content_location = ContentLocation::from_headers(Url::parse("https://example.net/").unwrap(), headers)? diff --git a/src/content/content_type.rs b/src/content/content_type.rs index 9397165c..3be34e1b 100644 --- a/src/content/content_type.rs +++ b/src/content/content_type.rs @@ -114,7 +114,7 @@ mod test { let ct = ContentType::new(Mime::from_str("text/*")?); let mut headers = Headers::new(); - ct.apply_header(&mut headers); + headers.insert(ct); let ct = ContentType::from_headers(headers)?.unwrap(); assert_eq!( diff --git a/src/headers/header.rs b/src/headers/header.rs index 0679adec..c5bdb890 100644 --- a/src/headers/header.rs +++ b/src/headers/header.rs @@ -1,14 +1,20 @@ use std::ops::Deref; -use crate::headers::{HeaderName, HeaderValue, Headers}; +use crate::headers::{HeaderName, HeaderValue}; /// A trait representing a [`HeaderName`] and [`HeaderValue`] pair. -pub trait Header { +pub trait Header +where + Self: Sized, +{ /// The header's name. fn header_name(&self) -> HeaderName; /// Access the header's value. fn header_value(&self) -> HeaderValue; + + /// Create an instance from a header value. + fn from_parts(name: HeaderName, value: HeaderValue) -> crate::Result; } impl Header for (HeaderName, HeaderValue) { @@ -19,6 +25,10 @@ impl Header for (HeaderName, HeaderValue) { fn header_value(&self) -> HeaderValue { self.1 } + + fn from_parts(name: HeaderName, value: HeaderValue) -> crate::Result { + Ok((name, value)) + } } impl<'a, T: Header> Header for &'a T { @@ -29,6 +39,10 @@ impl<'a, T: Header> Header for &'a T { fn header_value(&self) -> HeaderValue { self.deref().header_value() } + + fn from_parts(name: HeaderName, value: HeaderValue) -> crate::Result { + T::from_parts(name, value) + } } #[cfg(test)] diff --git a/src/headers/headers.rs b/src/headers/headers.rs index 25198e42..dd4e32ee 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -11,6 +11,8 @@ use crate::headers::{ Header, HeaderName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, }; +use super::HeaderValue; + /// A collection of HTTP Headers. /// /// Headers are never manually constructed, but are part of `Request`, @@ -29,7 +31,7 @@ use crate::headers::{ /// ``` #[derive(Clone)] pub struct Headers { - pub(crate) headers: HashMap>, + pub(crate) headers: HashMap, } impl Headers { @@ -43,29 +45,16 @@ impl Headers { /// Insert a header into the headers. /// /// Not that this will replace all header values for a given header name. - /// If you wish to add header values for a header name that already exists - /// use `Headers::append` - pub fn insert(&mut self, header: H) -> Option { + pub fn insert(&mut self, header: H) -> Option { let name = header.header_name(); let value = header.header_value(); self.headers.insert(name, value) } - /// Append a header to the headers. - /// - /// Unlike `insert` this function will not override the contents of a header, but insert a - /// header if there aren't any. Or else append to the existing list of headers. - pub fn append(&mut self, header: H) -> crate::Result<()> { - let name = header.header_name(); - let value = header.header_value(); - let mut headers = self.headers.entry(name).or_default(); - headers.push(value); - Ok(()) - } - /// Get a reference to a header. - pub fn get(&self, name: impl Into) -> Option<&HeaderValues> { - self.headers.get(&name.into()) + pub fn get(&self, name: HeaderName) -> Option { + let value = self.headers.get(&name)?; + H::from_parts(name, value.clone()).ok() } /// Get a mutable reference to a header. @@ -74,7 +63,7 @@ impl Headers { } /// Remove a header. - pub fn remove(&mut self, name: impl Into) -> Option { + pub fn remove(&mut self, name: HeaderName) -> Option { self.headers.remove(&name.into()) } diff --git a/src/other/date.rs b/src/other/date.rs index 1e381ffe..c2f332f8 100644 --- a/src/other/date.rs +++ b/src/other/date.rs @@ -117,7 +117,7 @@ mod test { let date = Date::new(now); let mut headers = Headers::new(); - date.apply_header(&mut headers); + headers.insert(date); let date = Date::from_headers(headers)?.unwrap(); diff --git a/src/other/expect.rs b/src/other/expect.rs index 086c0d09..7aa3387c 100644 --- a/src/other/expect.rs +++ b/src/other/expect.rs @@ -77,7 +77,7 @@ mod test { let expect = Expect::new(); let mut headers = Headers::new(); - expect.apply_header(&mut headers); + headers.insert(expect); let expect = Expect::from_headers(headers)?.unwrap(); assert_eq!(expect, Expect::new()); diff --git a/src/other/referer.rs b/src/other/referer.rs index 5a860ab9..f21f4ccd 100644 --- a/src/other/referer.rs +++ b/src/other/referer.rs @@ -109,7 +109,7 @@ mod test { let referer = Referer::new(Url::parse("https://example.net/test.json")?); let mut headers = Headers::new(); - referer.apply_header(&mut headers); + headers.insert(referer); let base_url = Url::parse("https://example.net/")?; let referer = Referer::from_headers(base_url, headers)?.unwrap(); diff --git a/src/other/retry_after.rs b/src/other/retry_after.rs index 21404598..68091b86 100644 --- a/src/other/retry_after.rs +++ b/src/other/retry_after.rs @@ -133,7 +133,7 @@ mod test { let retry = RetryAfter::new(Duration::from_secs(10)); let mut headers = Headers::new(); - retry.apply_header(&mut headers); + headers.insert(retry); // `SystemTime::now` uses sub-second precision which means there's some // offset that's not encoded. @@ -152,7 +152,7 @@ mod test { let retry = RetryAfter::new_at(now + Duration::from_secs(10)); let mut headers = Headers::new(); - retry.apply_header(&mut headers); + headers.insert(retry); // `SystemTime::now` uses sub-second precision which means there's some // offset that's not encoded. diff --git a/src/other/source_map.rs b/src/other/source_map.rs index 5412c6e1..1d6746e3 100644 --- a/src/other/source_map.rs +++ b/src/other/source_map.rs @@ -106,7 +106,7 @@ mod test { let source_map = SourceMap::new(Url::parse("https://example.net/test.json")?); let mut headers = Headers::new(); - source_map.apply_header(&mut headers); + source_headers.insert(map); let base_url = Url::parse("https://example.net/")?; let source_map = SourceMap::from_headers(base_url, headers)?.unwrap(); diff --git a/src/security/strict_transport_security.rs b/src/security/strict_transport_security.rs index f512fa17..089d79ae 100644 --- a/src/security/strict_transport_security.rs +++ b/src/security/strict_transport_security.rs @@ -170,7 +170,7 @@ mod test { let stc = StrictTransportSecurity::new(duration); let mut headers = Response::new(200); - stc.apply_header(&mut headers); + headers.insert(stc); let stc = StrictTransportSecurity::from_headers(headers)?.unwrap(); diff --git a/src/security/timing_allow_origin.rs b/src/security/timing_allow_origin.rs index 443427fb..77417cb6 100644 --- a/src/security/timing_allow_origin.rs +++ b/src/security/timing_allow_origin.rs @@ -266,7 +266,7 @@ mod test { origins.push(Url::parse("https://example.com")?); let mut headers = Headers::new(); - origins.apply_header(&mut headers); + headers.insert(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); let origin = origins.iter().next().unwrap(); @@ -281,7 +281,7 @@ mod test { origins.push(Url::parse("https://mozilla.org/")?); let mut headers = Headers::new(); - origins.apply_header(&mut headers); + headers.insert(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); let mut origins = origins.iter(); @@ -310,7 +310,7 @@ mod test { origins.set_wildcard(true); let mut headers = Headers::new(); - origins.apply_header(&mut headers); + headers.insert(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); assert!(origins.wildcard()); diff --git a/src/server/allow.rs b/src/server/allow.rs index 9377a3f6..0e4f914f 100644 --- a/src/server/allow.rs +++ b/src/server/allow.rs @@ -184,7 +184,7 @@ mod test { allow.insert(Method::Post); let mut headers = Headers::new(); - allow.apply_header(&mut headers); + headers.insert(allow); let allow = Allow::from_headers(headers)?.unwrap(); assert!(allow.contains(Method::Put)); diff --git a/src/trace/server_timing/mod.rs b/src/trace/server_timing/mod.rs index ddd6c79a..aaabed97 100644 --- a/src/trace/server_timing/mod.rs +++ b/src/trace/server_timing/mod.rs @@ -225,7 +225,7 @@ mod test { timings.push(Metric::new("server".to_owned(), None, None)?); let mut headers = Headers::new(); - timings.apply_header(&mut headers); + headers.insert(timings); let timings = ServerTiming::from_headers(headers)?.unwrap(); let entry = timings.iter().next().unwrap(); @@ -239,7 +239,7 @@ mod test { timings.push(Metric::new("server".to_owned(), None, None)?); let mut headers = Headers::new(); - timings.apply_header(&mut headers); + headers.insert(timings); let timings = ServerTiming::from_headers(headers)?.unwrap(); let entry = timings.iter().next().unwrap(); diff --git a/src/transfer/te.rs b/src/transfer/te.rs index acd1af80..5da44707 100644 --- a/src/transfer/te.rs +++ b/src/transfer/te.rs @@ -289,7 +289,7 @@ mod test { accept.push(Encoding::Gzip); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = TE::from_headers(headers)?.unwrap(); assert_eq!(accept.iter().next().unwrap(), Encoding::Gzip); @@ -302,7 +302,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = TE::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -316,7 +316,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = TE::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -331,7 +331,7 @@ mod test { accept.push(Encoding::Brotli); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let accept = TE::from_headers(headers)?.unwrap(); let mut accept = accept.iter(); @@ -348,7 +348,7 @@ mod test { accept.push(EncodingProposal::new(Encoding::Brotli, Some(0.8))?); let mut headers = Response::new(200); - accept.apply_header(&mut headers); + headers.insert(accept); let mut accept = TE::from_headers(headers)?.unwrap(); accept.sort(); From d9120102b227831c604aec51a16625b0f80a1c4a Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sat, 18 Jun 2022 15:39:13 +0200 Subject: [PATCH 3/9] Replace the use of "header" terminology with "field" From https://www.rfc-editor.org/rfc/rfc9110.html#section-6.3: > 6.3. Header Fields > Fields (Section 5) that are sent or received before the content are referred to as "header fields" (or just "headers", colloquially). > The "header section" of a message consists of a sequence of header field lines. Each header field might modify or extend message semantics, describe the sender, define the content, or provide additional context. > Note: We refer to named fields specifically as a "header field" when they are only allowed to be sent in the header section. This means that our use of "header" is currently wrong. Because "fields" can be sent in both the headers and trailers section, solely referring to them as "headers" is wrong. We can work around confusion by linking to "headers" using a doc alias. --- src/auth/authorization.rs | 10 +- src/auth/basic_auth.rs | 12 +- src/auth/www_authenticate.rs | 12 +- src/cache/age.rs | 10 +- src/cache/cache_control/cache_control.rs | 14 +- src/cache/cache_control/cache_directive.rs | 6 +- src/cache/cache_control/mod.rs | 2 +- src/cache/clear_site_data/mod.rs | 12 +- src/cache/expires.rs | 10 +- src/conditional/etag.rs | 10 +- src/conditional/if_match.rs | 12 +- src/conditional/if_modified_since.rs | 10 +- src/conditional/if_none_match.rs | 12 +- src/conditional/if_unmodified_since.rs | 10 +- src/conditional/last_modified.rs | 10 +- src/conditional/vary.rs | 36 ++--- src/content/accept.rs | 14 +- src/content/accept_encoding.rs | 14 +- src/content/content_encoding.rs | 10 +- src/content/content_length.rs | 10 +- src/content/content_location.rs | 10 +- src/content/content_type.rs | 12 +- src/content/encoding.rs | 6 +- src/content/encoding_proposal.rs | 8 +- src/content/media_type_proposal.rs | 8 +- src/headers/constants.rs | 150 ++++++++++----------- src/headers/header.rs | 45 ++++--- src/headers/header_name.rs | 56 ++++---- src/headers/header_value.rs | 36 ++--- src/headers/header_values.rs | 46 +++---- src/headers/headers.rs | 36 ++--- src/headers/into_iter.rs | 6 +- src/headers/iter.rs | 6 +- src/headers/iter_mut.rs | 6 +- src/headers/mod.rs | 6 +- src/headers/names.rs | 6 +- src/headers/to_header_values.rs | 26 ++-- src/headers/values.rs | 8 +- src/lib.rs | 2 +- src/mime/mod.rs | 6 +- src/other/date.rs | 10 +- src/other/expect.rs | 12 +- src/other/referer.rs | 10 +- src/other/retry_after.rs | 10 +- src/other/source_map.rs | 10 +- src/proxies/forwarded.rs | 22 +-- src/request.rs | 25 ++-- src/response.rs | 25 ++-- src/security/mod.rs | 6 +- src/security/strict_transport_security.rs | 10 +- src/security/timing_allow_origin.rs | 10 +- src/server/allow.rs | 10 +- src/trace/server_timing/metric.rs | 18 +-- src/trace/server_timing/mod.rs | 12 +- src/trace/trace_context.rs | 10 +- src/trailers.rs | 16 +-- src/transfer/encoding.rs | 6 +- src/transfer/encoding_proposal.rs | 8 +- src/transfer/te.rs | 12 +- src/transfer/transfer_encoding.rs | 8 +- 60 files changed, 485 insertions(+), 486 deletions(-) diff --git a/src/auth/authorization.rs b/src/auth/authorization.rs index 525a8806..930ae84c 100644 --- a/src/auth/authorization.rs +++ b/src/auth/authorization.rs @@ -1,6 +1,6 @@ use crate::auth::AuthenticationScheme; use crate::bail_status as bail; -use crate::headers::{Header, HeaderName, HeaderValue, Headers, AUTHORIZATION}; +use crate::headers::{Field, FieldName, FieldValue, Headers, AUTHORIZATION}; /// Credentials to authenticate a user agent with a server. /// @@ -92,16 +92,16 @@ impl Authorization { } } -impl Header for Authorization { - fn header_name(&self) -> HeaderName { +impl Field for Authorization { + fn field_name(&self) -> FieldName { AUTHORIZATION } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = format!("{} {}", self.scheme, self.credentials); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/auth/basic_auth.rs b/src/auth/basic_auth.rs index 3dae6127..68ff5713 100644 --- a/src/auth/basic_auth.rs +++ b/src/auth/basic_auth.rs @@ -1,8 +1,8 @@ -use crate::headers::{HeaderName, HeaderValue, Headers, AUTHORIZATION}; +use crate::headers::{FieldName, FieldValue, Headers, AUTHORIZATION}; use crate::Status; use crate::{ auth::{AuthenticationScheme, Authorization}, - headers::Header, + headers::Field, }; use crate::{bail_status as bail, ensure_status as ensure}; @@ -98,16 +98,16 @@ impl BasicAuth { } } -impl Header for BasicAuth { - fn header_name(&self) -> HeaderName { +impl Field for BasicAuth { + fn field_name(&self) -> FieldName { AUTHORIZATION } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let scheme = AuthenticationScheme::Basic; let credentials = base64::encode(format!("{}:{}", self.username, self.password)); let auth = Authorization::new(scheme, credentials); - auth.header_value() + auth.field_value() } } diff --git a/src/auth/www_authenticate.rs b/src/auth/www_authenticate.rs index d777a7fc..876a4643 100644 --- a/src/auth/www_authenticate.rs +++ b/src/auth/www_authenticate.rs @@ -1,6 +1,6 @@ use crate::bail_status as bail; -use crate::headers::{HeaderName, HeaderValue, Headers, WWW_AUTHENTICATE}; -use crate::{auth::AuthenticationScheme, headers::Header}; +use crate::headers::{FieldName, FieldValue, Headers, WWW_AUTHENTICATE}; +use crate::{auth::AuthenticationScheme, headers::Field}; /// Define the authentication method that should be used to gain access to a /// resource. @@ -114,16 +114,16 @@ impl WwwAuthenticate { } } -impl Header for WwwAuthenticate { - fn header_name(&self) -> HeaderName { +impl Field for WwwAuthenticate { + fn field_name(&self) -> FieldName { WWW_AUTHENTICATE } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = format!(r#"{} realm="{}", charset="UTF-8""#, self.scheme, self.realm); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/cache/age.rs b/src/cache/age.rs index 0b3aa0cb..b8499b5d 100644 --- a/src/cache/age.rs +++ b/src/cache/age.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, AGE}; +use crate::headers::{Field, FieldName, FieldValue, Headers, AGE}; use crate::Status; use std::fmt::Debug; @@ -69,16 +69,16 @@ impl Age { } } -impl Header for Age { - fn header_name(&self) -> HeaderName { +impl Field for Age { + fn field_name(&self) -> FieldName { AGE } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = self.dur.as_secs().to_string(); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/cache/cache_control/cache_control.rs b/src/cache/cache_control/cache_control.rs index deffd6bd..c9d89ce2 100644 --- a/src/cache/cache_control/cache_control.rs +++ b/src/cache/cache_control/cache_control.rs @@ -1,6 +1,6 @@ -use headers::Header; +use headers::Field; -use crate::headers::{HeaderName, HeaderValue, Headers, CACHE_CONTROL}; +use crate::headers::{FieldName, FieldValue, Headers, CACHE_CONTROL}; use crate::{cache::CacheDirective, headers}; use std::fmt::{self, Debug, Write}; @@ -81,14 +81,14 @@ impl CacheControl { } } -impl Header for CacheControl { - fn header_name(&self) -> HeaderName { +impl Field for CacheControl { + fn field_name(&self) -> FieldName { CACHE_CONTROL } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, directive) in self.entries.iter().enumerate() { - let directive: HeaderValue = directive.clone().into(); + let directive: FieldValue = directive.clone().into(); match n { 0 => write!(output, "{}", directive).unwrap(), _ => write!(output, ", {}", directive).unwrap(), @@ -96,7 +96,7 @@ impl Header for CacheControl { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/cache/cache_control/cache_directive.rs b/src/cache/cache_control/cache_directive.rs index 5e8b0b98..afcdb8b0 100644 --- a/src/cache/cache_control/cache_directive.rs +++ b/src/cache/cache_control/cache_directive.rs @@ -1,4 +1,4 @@ -use crate::headers::HeaderValue; +use crate::headers::FieldValue; use crate::Status; use std::time::Duration; @@ -127,10 +127,10 @@ impl CacheDirective { } } -impl From for HeaderValue { +impl From for FieldValue { fn from(directive: CacheDirective) -> Self { use CacheDirective::*; - let h = |s: String| unsafe { HeaderValue::from_bytes_unchecked(s.into_bytes()) }; + let h = |s: String| unsafe { FieldValue::from_bytes_unchecked(s.into_bytes()) }; match directive { Immutable => h("immutable".to_string()), diff --git a/src/cache/cache_control/mod.rs b/src/cache/cache_control/mod.rs index 6eecf275..3958c490 100644 --- a/src/cache/cache_control/mod.rs +++ b/src/cache/cache_control/mod.rs @@ -16,7 +16,7 @@ pub use cache_directive::CacheDirective; #[cfg(test)] mod test { use super::*; - use crate::headers::{Header, Headers, CACHE_CONTROL}; + use crate::headers::{Field, Headers, CACHE_CONTROL}; #[test] fn smoke() -> crate::Result<()> { diff --git a/src/cache/clear_site_data/mod.rs b/src/cache/clear_site_data/mod.rs index bb38ab80..e56dc867 100644 --- a/src/cache/clear_site_data/mod.rs +++ b/src/cache/clear_site_data/mod.rs @@ -1,7 +1,7 @@ //! Clear browsing data (cookies, storage, cache) associated with the //! requesting website -use crate::headers::{self, HeaderName, HeaderValue, Headers, CLEAR_SITE_DATA}; +use crate::headers::{self, FieldName, FieldValue, Headers, CLEAR_SITE_DATA}; use std::fmt::{self, Debug, Write}; use std::iter::Iterator; @@ -12,7 +12,7 @@ use std::str::FromStr; mod directive; pub use directive::ClearDirective; -use headers::Header; +use headers::Field; /// Clear browsing data (cookies, storage, cache) associated with the /// requesting website. @@ -211,12 +211,12 @@ impl Debug for ClearSiteData { } } -impl Header for ClearSiteData { - fn header_name(&self) -> HeaderName { +impl Field for ClearSiteData { + fn field_name(&self) -> FieldName { CLEAR_SITE_DATA } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { match n { @@ -233,7 +233,7 @@ impl Header for ClearSiteData { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/cache/expires.rs b/src/cache/expires.rs index a82aff16..cd3c55e5 100644 --- a/src/cache/expires.rs +++ b/src/cache/expires.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, EXPIRES}; +use crate::headers::{Field, FieldName, FieldValue, Headers, EXPIRES}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -71,15 +71,15 @@ impl Expires { } } -impl Header for Expires { - fn header_name(&self) -> HeaderName { +impl Field for Expires { + fn field_name(&self) -> FieldName { EXPIRES } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/conditional/etag.rs b/src/conditional/etag.rs index 1122cedc..7ca75fc9 100644 --- a/src/conditional/etag.rs +++ b/src/conditional/etag.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, ETAG}; +use crate::headers::{Field, FieldName, FieldValue, Headers, ETAG}; use crate::{Error, StatusCode}; use std::fmt::{self, Debug, Display}; @@ -112,14 +112,14 @@ impl ETag { } } -impl Header for ETag { - fn header_name(&self) -> HeaderName { +impl Field for ETag { + fn field_name(&self) -> FieldName { ETAG } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let s = self.to_string(); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(s.into()) } + unsafe { FieldValue::from_bytes_unchecked(s.into()) } } } diff --git a/src/conditional/if_match.rs b/src/conditional/if_match.rs index 5f84c2bd..0d7a6c98 100644 --- a/src/conditional/if_match.rs +++ b/src/conditional/if_match.rs @@ -1,7 +1,7 @@ //! Apply the HTTP method if the ETag matches. -use crate::headers::{HeaderName, HeaderValue, Headers, IF_MATCH}; -use crate::{conditional::ETag, headers::Header}; +use crate::headers::{FieldName, FieldValue, Headers, IF_MATCH}; +use crate::{conditional::ETag, headers::Field}; use std::fmt::{self, Debug, Write}; use std::iter::Iterator; @@ -103,11 +103,11 @@ impl IfMatch { } } -impl Header for IfMatch { - fn header_name(&self) -> HeaderName { +impl Field for IfMatch { + fn field_name(&self) -> FieldName { IF_MATCH } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { match n { @@ -124,7 +124,7 @@ impl Header for IfMatch { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/conditional/if_modified_since.rs b/src/conditional/if_modified_since.rs index b0cc6cf4..fedc2c86 100644 --- a/src/conditional/if_modified_since.rs +++ b/src/conditional/if_modified_since.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, IF_MODIFIED_SINCE}; +use crate::headers::{Field, FieldName, FieldValue, Headers, IF_MODIFIED_SINCE}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -67,15 +67,15 @@ impl IfModifiedSince { } } -impl Header for IfModifiedSince { - fn header_name(&self) -> HeaderName { +impl Field for IfModifiedSince { + fn field_name(&self) -> FieldName { IF_MODIFIED_SINCE } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/conditional/if_none_match.rs b/src/conditional/if_none_match.rs index b4b37af9..d5a53d6c 100644 --- a/src/conditional/if_none_match.rs +++ b/src/conditional/if_none_match.rs @@ -3,8 +3,8 @@ //! This is used to update caches or to prevent uploading a new resource when //! one already exists. -use crate::headers::{HeaderName, HeaderValue, Headers, IF_NONE_MATCH}; -use crate::{conditional::ETag, headers::Header}; +use crate::headers::{FieldName, FieldValue, Headers, IF_NONE_MATCH}; +use crate::{conditional::ETag, headers::Field}; use std::fmt::{self, Debug, Write}; use std::iter::Iterator; @@ -109,11 +109,11 @@ impl IfNoneMatch { } } -impl Header for IfNoneMatch { - fn header_name(&self) -> HeaderName { +impl Field for IfNoneMatch { + fn field_name(&self) -> FieldName { IF_NONE_MATCH } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { match n { @@ -130,7 +130,7 @@ impl Header for IfNoneMatch { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/conditional/if_unmodified_since.rs b/src/conditional/if_unmodified_since.rs index 65fa48c7..c8d21687 100644 --- a/src/conditional/if_unmodified_since.rs +++ b/src/conditional/if_unmodified_since.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, IF_UNMODIFIED_SINCE}; +use crate::headers::{Field, FieldName, FieldValue, Headers, IF_UNMODIFIED_SINCE}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -67,15 +67,15 @@ impl IfUnmodifiedSince { } } -impl Header for IfUnmodifiedSince { - fn header_name(&self) -> HeaderName { +impl Field for IfUnmodifiedSince { + fn field_name(&self) -> FieldName { IF_UNMODIFIED_SINCE } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/conditional/last_modified.rs b/src/conditional/last_modified.rs index c7fbd88e..c3abf1c7 100644 --- a/src/conditional/last_modified.rs +++ b/src/conditional/last_modified.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, LAST_MODIFIED}; +use crate::headers::{Field, FieldName, FieldValue, Headers, LAST_MODIFIED}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -66,15 +66,15 @@ impl LastModified { } } -impl Header for LastModified { - fn header_name(&self) -> HeaderName { +impl Field for LastModified { + fn field_name(&self) -> FieldName { LAST_MODIFIED } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/conditional/vary.rs b/src/conditional/vary.rs index 9023811a..8a036250 100644 --- a/src/conditional/vary.rs +++ b/src/conditional/vary.rs @@ -1,6 +1,6 @@ //! Apply the HTTP method if the ETag matches. -use crate::headers::{Header, HeaderName, HeaderValue, Headers, VARY}; +use crate::headers::{Field, FieldName, FieldValue, Headers, VARY}; use std::fmt::{self, Debug, Write}; use std::iter::Iterator; @@ -37,7 +37,7 @@ use std::str::FromStr; /// # Ok(()) } /// ``` pub struct Vary { - entries: Vec, + entries: Vec, wildcard: bool, } @@ -66,7 +66,7 @@ impl Vary { wildcard = true; continue; } - let entry = HeaderName::from_str(part.trim())?; + let entry = FieldName::from_str(part.trim())?; entries.push(entry); } } @@ -85,7 +85,7 @@ impl Vary { } /// Push a directive into the list of entries. - pub fn push(&mut self, directive: impl Into) -> crate::Result<()> { + pub fn push(&mut self, directive: impl Into) -> crate::Result<()> { self.entries.push(directive.into()); Ok(()) } @@ -105,15 +105,15 @@ impl Vary { } } -impl Header for Vary { - fn header_name(&self) -> HeaderName { +impl Field for Vary { + fn field_name(&self) -> FieldName { VARY } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, name) in self.entries.iter().enumerate() { - let directive: HeaderValue = name + let directive: FieldValue = name .as_str() .parse() .expect("Could not convert a HeaderName into a HeaderValue"); @@ -131,12 +131,12 @@ impl Header for Vary { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } impl IntoIterator for Vary { - type Item = HeaderName; + type Item = FieldName; type IntoIter = IntoIter; #[inline] @@ -148,7 +148,7 @@ impl IntoIterator for Vary { } impl<'a> IntoIterator for &'a Vary { - type Item = &'a HeaderName; + type Item = &'a FieldName; type IntoIter = Iter<'a>; #[inline] @@ -158,7 +158,7 @@ impl<'a> IntoIterator for &'a Vary { } impl<'a> IntoIterator for &'a mut Vary { - type Item = &'a mut HeaderName; + type Item = &'a mut FieldName; type IntoIter = IterMut<'a>; #[inline] @@ -170,11 +170,11 @@ impl<'a> IntoIterator for &'a mut Vary { /// A borrowing iterator over entries in `Vary`. #[derive(Debug)] pub struct IntoIter { - inner: std::vec::IntoIter, + inner: std::vec::IntoIter, } impl Iterator for IntoIter { - type Item = HeaderName; + type Item = FieldName; fn next(&mut self) -> Option { self.inner.next() @@ -189,11 +189,11 @@ impl Iterator for IntoIter { /// A lending iterator over entries in `Vary`. #[derive(Debug)] pub struct Iter<'a> { - inner: slice::Iter<'a, HeaderName>, + inner: slice::Iter<'a, FieldName>, } impl<'a> Iterator for Iter<'a> { - type Item = &'a HeaderName; + type Item = &'a FieldName; fn next(&mut self) -> Option { self.inner.next() @@ -208,11 +208,11 @@ impl<'a> Iterator for Iter<'a> { /// A mutable iterator over entries in `Vary`. #[derive(Debug)] pub struct IterMut<'a> { - inner: slice::IterMut<'a, HeaderName>, + inner: slice::IterMut<'a, FieldName>, } impl<'a> Iterator for IterMut<'a> { - type Item = &'a mut HeaderName; + type Item = &'a mut FieldName; fn next(&mut self) -> Option { self.inner.next() diff --git a/src/content/accept.rs b/src/content/accept.rs index 6fb8f880..fe5bf07a 100644 --- a/src/content/accept.rs +++ b/src/content/accept.rs @@ -1,11 +1,11 @@ //! Client header advertising which media types the client is able to understand. -use crate::headers::{HeaderName, HeaderValue, Headers, ACCEPT}; +use crate::headers::{FieldName, FieldValue, Headers, ACCEPT}; use crate::mime::Mime; use crate::utils::sort_by_weight; use crate::{ content::{ContentType, MediaTypeProposal}, - headers::Header, + headers::Field, }; use crate::{Error, StatusCode}; @@ -161,14 +161,14 @@ impl Accept { } } -impl Header for Accept { - fn header_name(&self) -> HeaderName { +impl Field for Accept { + fn field_name(&self) -> FieldName { ACCEPT } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, directive) in self.entries.iter().enumerate() { - let directive: HeaderValue = directive.clone().into(); + let directive: FieldValue = directive.clone().into(); match n { 0 => write!(output, "{}", directive).unwrap(), _ => write!(output, ", {}", directive).unwrap(), @@ -183,7 +183,7 @@ impl Header for Accept { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/content/accept_encoding.rs b/src/content/accept_encoding.rs index 2de56356..4961671a 100644 --- a/src/content/accept_encoding.rs +++ b/src/content/accept_encoding.rs @@ -1,10 +1,10 @@ //! Client header advertising available compression algorithms. -use crate::headers::{HeaderName, HeaderValue, Headers, ACCEPT_ENCODING}; +use crate::headers::{FieldName, FieldValue, Headers, ACCEPT_ENCODING}; use crate::utils::sort_by_weight; use crate::{ content::{ContentEncoding, Encoding, EncodingProposal}, - headers::Header, + headers::Field, }; use crate::{Error, StatusCode}; @@ -153,15 +153,15 @@ impl AcceptEncoding { } } -impl Header for AcceptEncoding { - fn header_name(&self) -> HeaderName { +impl Field for AcceptEncoding { + fn field_name(&self) -> FieldName { ACCEPT_ENCODING } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, directive) in self.entries.iter().enumerate() { - let directive: HeaderValue = (*directive).into(); + let directive: FieldValue = (*directive).into(); match n { 0 => write!(output, "{}", directive).unwrap(), _ => write!(output, ", {}", directive).unwrap(), @@ -176,7 +176,7 @@ impl Header for AcceptEncoding { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/content/content_encoding.rs b/src/content/content_encoding.rs index bbab123c..c2706b3e 100644 --- a/src/content/content_encoding.rs +++ b/src/content/content_encoding.rs @@ -1,9 +1,9 @@ //! Specify the compression algorithm. -use crate::headers::{HeaderName, HeaderValue, Headers, CONTENT_ENCODING}; +use crate::headers::{FieldName, FieldValue, Headers, CONTENT_ENCODING}; use crate::{ content::{Encoding, EncodingProposal}, - headers::Header, + headers::Field, }; use std::fmt::{self, Debug}; @@ -67,11 +67,11 @@ impl ContentEncoding { } } -impl Header for ContentEncoding { - fn header_name(&self) -> HeaderName { +impl Field for ContentEncoding { + fn field_name(&self) -> FieldName { CONTENT_ENCODING } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { self.inner.into() } } diff --git a/src/content/content_length.rs b/src/content/content_length.rs index 1de66b1c..c27a364d 100644 --- a/src/content/content_length.rs +++ b/src/content/content_length.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, CONTENT_LENGTH}; +use crate::headers::{Field, FieldName, FieldValue, Headers, CONTENT_LENGTH}; use crate::Status; /// The size of the entity-body, in bytes, sent to the recipient. @@ -62,15 +62,15 @@ impl ContentLength { } } -impl Header for ContentLength { - fn header_name(&self) -> HeaderName { +impl Field for ContentLength { + fn field_name(&self) -> FieldName { CONTENT_LENGTH } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = format!("{}", self.length); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/content/content_location.rs b/src/content/content_location.rs index 816d240b..ac834bad 100644 --- a/src/content/content_location.rs +++ b/src/content/content_location.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, CONTENT_LOCATION}; +use crate::headers::{Field, FieldName, FieldValue, Headers, CONTENT_LOCATION}; use crate::{bail_status as bail, Status, Url}; use std::convert::TryInto; @@ -81,15 +81,15 @@ impl ContentLocation { } } -impl Header for ContentLocation { - fn header_name(&self) -> HeaderName { +impl Field for ContentLocation { + fn field_name(&self) -> FieldName { CONTENT_LOCATION } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = self.url.to_string(); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/content/content_type.rs b/src/content/content_type.rs index 3be34e1b..b44b27b4 100644 --- a/src/content/content_type.rs +++ b/src/content/content_type.rs @@ -1,6 +1,6 @@ use std::{convert::TryInto, str::FromStr}; -use crate::headers::{Header, HeaderName, HeaderValue, Headers, CONTENT_TYPE}; +use crate::headers::{Field, FieldName, FieldValue, Headers, CONTENT_TYPE}; use crate::mime::Mime; /// Indicate the media type of a resource's content. @@ -75,14 +75,14 @@ impl ContentType { } } -impl Header for ContentType { - fn header_name(&self) -> HeaderName { +impl Field for ContentType { + fn field_name(&self) -> FieldName { CONTENT_TYPE } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = format!("{}", self.media_type); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } @@ -118,7 +118,7 @@ mod test { let ct = ContentType::from_headers(headers)?.unwrap(); assert_eq!( - ct.header_value(), + ct.field_value(), format!("{}", Mime::from_str("text/*")?).as_str() ); Ok(()) diff --git a/src/content/encoding.rs b/src/content/encoding.rs index 992194ef..05d836cd 100644 --- a/src/content/encoding.rs +++ b/src/content/encoding.rs @@ -1,4 +1,4 @@ -use crate::headers::HeaderValue; +use crate::headers::FieldValue; use std::fmt::{self, Display}; /// Available compression algorithms. @@ -50,9 +50,9 @@ impl Display for Encoding { } } -impl From for HeaderValue { +impl From for FieldValue { fn from(directive: Encoding) -> Self { let s = directive.to_string(); - unsafe { HeaderValue::from_bytes_unchecked(s.into_bytes()) } + unsafe { FieldValue::from_bytes_unchecked(s.into_bytes()) } } } diff --git a/src/content/encoding_proposal.rs b/src/content/encoding_proposal.rs index 7d329447..92abc99f 100644 --- a/src/content/encoding_proposal.rs +++ b/src/content/encoding_proposal.rs @@ -1,6 +1,6 @@ use crate::content::Encoding; use crate::ensure; -use crate::headers::HeaderValue; +use crate::headers::FieldValue; use crate::utils::parse_weight; use std::cmp::{Ordering, PartialEq}; @@ -108,13 +108,13 @@ impl PartialOrd for EncodingProposal { } } -impl From for HeaderValue { - fn from(entry: EncodingProposal) -> HeaderValue { +impl From for FieldValue { + fn from(entry: EncodingProposal) -> FieldValue { let s = match entry.weight { Some(weight) => format!("{};q={:.3}", entry.encoding, weight), None => entry.encoding.to_string(), }; - unsafe { HeaderValue::from_bytes_unchecked(s.into_bytes()) } + unsafe { FieldValue::from_bytes_unchecked(s.into_bytes()) } } } diff --git a/src/content/media_type_proposal.rs b/src/content/media_type_proposal.rs index 622558de..795fadf3 100644 --- a/src/content/media_type_proposal.rs +++ b/src/content/media_type_proposal.rs @@ -1,5 +1,5 @@ use crate::ensure; -use crate::headers::HeaderValue; +use crate::headers::FieldValue; use crate::mime::Mime; use std::ops::{Deref, DerefMut}; @@ -125,13 +125,13 @@ impl PartialOrd for MediaTypeProposal { } } -impl From for HeaderValue { - fn from(entry: MediaTypeProposal) -> HeaderValue { +impl From for FieldValue { + fn from(entry: MediaTypeProposal) -> FieldValue { let s = match entry.weight { Some(weight) => format!("{};q={:.3}", entry.media_type, weight), None => entry.media_type.to_string(), }; - unsafe { HeaderValue::from_bytes_unchecked(s.into_bytes()) } + unsafe { FieldValue::from_bytes_unchecked(s.into_bytes()) } } } diff --git a/src/headers/constants.rs b/src/headers/constants.rs index b332b26e..2aa86eff 100644 --- a/src/headers/constants.rs +++ b/src/headers/constants.rs @@ -1,188 +1,188 @@ -use super::HeaderName; +use super::FieldName; /// The `Content-Encoding` Header -pub const CONTENT_ENCODING: HeaderName = HeaderName::from_lowercase_str("content-encoding"); +pub const CONTENT_ENCODING: FieldName = FieldName::from_lowercase_str("content-encoding"); /// The `Content-Language` Header -pub const CONTENT_LANGUAGE: HeaderName = HeaderName::from_lowercase_str("content-language"); +pub const CONTENT_LANGUAGE: FieldName = FieldName::from_lowercase_str("content-language"); /// The `Content-Length` Header -pub const CONTENT_LENGTH: HeaderName = HeaderName::from_lowercase_str("content-length"); +pub const CONTENT_LENGTH: FieldName = FieldName::from_lowercase_str("content-length"); /// The `Content-Location` Header -pub const CONTENT_LOCATION: HeaderName = HeaderName::from_lowercase_str("content-location"); +pub const CONTENT_LOCATION: FieldName = FieldName::from_lowercase_str("content-location"); /// The `Content-MD5` Header -pub const CONTENT_MD5: HeaderName = HeaderName::from_lowercase_str("content-md5"); +pub const CONTENT_MD5: FieldName = FieldName::from_lowercase_str("content-md5"); /// The `Content-Range` Header -pub const CONTENT_RANGE: HeaderName = HeaderName::from_lowercase_str("content-range"); +pub const CONTENT_RANGE: FieldName = FieldName::from_lowercase_str("content-range"); /// The `Content-Type` Header -pub const CONTENT_TYPE: HeaderName = HeaderName::from_lowercase_str("content-type"); +pub const CONTENT_TYPE: FieldName = FieldName::from_lowercase_str("content-type"); /// The `Cookie` Header -pub const COOKIE: HeaderName = HeaderName::from_lowercase_str("cookie"); +pub const COOKIE: FieldName = FieldName::from_lowercase_str("cookie"); /// The `Set-Cookie` Header -pub const SET_COOKIE: HeaderName = HeaderName::from_lowercase_str("set-cookie"); +pub const SET_COOKIE: FieldName = FieldName::from_lowercase_str("set-cookie"); /// The `Transfer-Encoding` Header -pub const TRANSFER_ENCODING: HeaderName = HeaderName::from_lowercase_str("transfer-encoding"); +pub const TRANSFER_ENCODING: FieldName = FieldName::from_lowercase_str("transfer-encoding"); /// The `Date` Header -pub const DATE: HeaderName = HeaderName::from_lowercase_str("date"); +pub const DATE: FieldName = FieldName::from_lowercase_str("date"); /// The `Host` Header -pub const HOST: HeaderName = HeaderName::from_lowercase_str("host"); +pub const HOST: FieldName = FieldName::from_lowercase_str("host"); /// The `Origin` Header -pub const ORIGIN: HeaderName = HeaderName::from_lowercase_str("origin"); +pub const ORIGIN: FieldName = FieldName::from_lowercase_str("origin"); /// The `access-control-max-age` Header -pub const ACCESS_CONTROL_MAX_AGE: HeaderName = - HeaderName::from_lowercase_str("access-control-max-age"); +pub const ACCESS_CONTROL_MAX_AGE: FieldName = + FieldName::from_lowercase_str("access-control-max-age"); /// The `access-control-allow-origin` Header -pub const ACCESS_CONTROL_ALLOW_ORIGIN: HeaderName = - HeaderName::from_lowercase_str("access-control-allow-origin"); +pub const ACCESS_CONTROL_ALLOW_ORIGIN: FieldName = + FieldName::from_lowercase_str("access-control-allow-origin"); /// The `access-control-allow-headers` Header -pub const ACCESS_CONTROL_ALLOW_HEADERS: HeaderName = - HeaderName::from_lowercase_str("access-control-allow-headers"); +pub const ACCESS_CONTROL_ALLOW_HEADERS: FieldName = + FieldName::from_lowercase_str("access-control-allow-headers"); /// The `access-control-allow-methods` Header -pub const ACCESS_CONTROL_ALLOW_METHODS: HeaderName = - HeaderName::from_lowercase_str("access-control-allow-methods"); +pub const ACCESS_CONTROL_ALLOW_METHODS: FieldName = + FieldName::from_lowercase_str("access-control-allow-methods"); /// The `access-control-expose-headers` Header -pub const ACCESS_CONTROL_EXPOSE_HEADERS: HeaderName = - HeaderName::from_lowercase_str("access-control-expose-headers"); +pub const ACCESS_CONTROL_EXPOSE_HEADERS: FieldName = + FieldName::from_lowercase_str("access-control-expose-headers"); /// The `access-control-request-method` Header -pub const ACCESS_CONTROL_REQUEST_METHOD: HeaderName = - HeaderName::from_lowercase_str("access-control-request-method"); +pub const ACCESS_CONTROL_REQUEST_METHOD: FieldName = + FieldName::from_lowercase_str("access-control-request-method"); /// The `access-control-request-headers` Header -pub const ACCESS_CONTROL_REQUEST_HEADERS: HeaderName = - HeaderName::from_lowercase_str("access-control-request-headers"); +pub const ACCESS_CONTROL_REQUEST_HEADERS: FieldName = + FieldName::from_lowercase_str("access-control-request-headers"); /// The `access-control-allow-credentials` Header -pub const ACCESS_CONTROL_ALLOW_CREDENTIALS: HeaderName = - HeaderName::from_lowercase_str("access-control-allow-credentials"); +pub const ACCESS_CONTROL_ALLOW_CREDENTIALS: FieldName = + FieldName::from_lowercase_str("access-control-allow-credentials"); /// The `Accept` Header -pub const ACCEPT: HeaderName = HeaderName::from_lowercase_str("accept"); +pub const ACCEPT: FieldName = FieldName::from_lowercase_str("accept"); /// The `Accept-Charset` Header -pub const ACCEPT_CHARSET: HeaderName = HeaderName::from_lowercase_str("accept-charset"); +pub const ACCEPT_CHARSET: FieldName = FieldName::from_lowercase_str("accept-charset"); /// The `Accept-Encoding` Header -pub const ACCEPT_ENCODING: HeaderName = HeaderName::from_lowercase_str("accept-encoding"); +pub const ACCEPT_ENCODING: FieldName = FieldName::from_lowercase_str("accept-encoding"); /// The `Accept-Language` Header -pub const ACCEPT_LANGUAGE: HeaderName = HeaderName::from_lowercase_str("accept-language"); +pub const ACCEPT_LANGUAGE: FieldName = FieldName::from_lowercase_str("accept-language"); /// The `Accept-Ranges` Header -pub const ACCEPT_RANGES: HeaderName = HeaderName::from_lowercase_str("accept-ranges"); +pub const ACCEPT_RANGES: FieldName = FieldName::from_lowercase_str("accept-ranges"); /// The `Age` Header -pub const AGE: HeaderName = HeaderName::from_lowercase_str("age"); +pub const AGE: FieldName = FieldName::from_lowercase_str("age"); /// The `Allow` Header -pub const ALLOW: HeaderName = HeaderName::from_lowercase_str("allow"); +pub const ALLOW: FieldName = FieldName::from_lowercase_str("allow"); /// The `Authorization` Header -pub const AUTHORIZATION: HeaderName = HeaderName::from_lowercase_str("authorization"); +pub const AUTHORIZATION: FieldName = FieldName::from_lowercase_str("authorization"); /// The `Cache-Control` Header -pub const CACHE_CONTROL: HeaderName = HeaderName::from_lowercase_str("cache-control"); +pub const CACHE_CONTROL: FieldName = FieldName::from_lowercase_str("cache-control"); /// The `Clear-Site-Data` Header -pub const CLEAR_SITE_DATA: HeaderName = HeaderName::from_lowercase_str("clear-site-data"); +pub const CLEAR_SITE_DATA: FieldName = FieldName::from_lowercase_str("clear-site-data"); /// The `Connection` Header -pub const CONNECTION: HeaderName = HeaderName::from_lowercase_str("connection"); +pub const CONNECTION: FieldName = FieldName::from_lowercase_str("connection"); /// The `ETag` Header -pub const ETAG: HeaderName = HeaderName::from_lowercase_str("etag"); +pub const ETAG: FieldName = FieldName::from_lowercase_str("etag"); /// The `Expect` Header -pub const EXPECT: HeaderName = HeaderName::from_lowercase_str("expect"); +pub const EXPECT: FieldName = FieldName::from_lowercase_str("expect"); /// The `Expires` Header -pub const EXPIRES: HeaderName = HeaderName::from_lowercase_str("expires"); +pub const EXPIRES: FieldName = FieldName::from_lowercase_str("expires"); /// The `Forwarded` Header -pub const FORWARDED: HeaderName = HeaderName::from_lowercase_str("forwarded"); +pub const FORWARDED: FieldName = FieldName::from_lowercase_str("forwarded"); /// The `From` Header -pub const FROM: HeaderName = HeaderName::from_lowercase_str("from"); +pub const FROM: FieldName = FieldName::from_lowercase_str("from"); /// The `If-Match` Header -pub const IF_MATCH: HeaderName = HeaderName::from_lowercase_str("if-match"); +pub const IF_MATCH: FieldName = FieldName::from_lowercase_str("if-match"); /// The `If-Modified-Since` Header -pub const IF_MODIFIED_SINCE: HeaderName = HeaderName::from_lowercase_str("if-modified-since"); +pub const IF_MODIFIED_SINCE: FieldName = FieldName::from_lowercase_str("if-modified-since"); /// The `If-None-Match` Header -pub const IF_NONE_MATCH: HeaderName = HeaderName::from_lowercase_str("if-none-match"); +pub const IF_NONE_MATCH: FieldName = FieldName::from_lowercase_str("if-none-match"); /// The `If-Range` Header -pub const IF_RANGE: HeaderName = HeaderName::from_lowercase_str("if-range"); +pub const IF_RANGE: FieldName = FieldName::from_lowercase_str("if-range"); /// The `If-Unmodified-Since` Header -pub const IF_UNMODIFIED_SINCE: HeaderName = HeaderName::from_lowercase_str("if-unmodified-since"); +pub const IF_UNMODIFIED_SINCE: FieldName = FieldName::from_lowercase_str("if-unmodified-since"); /// The `Last-Modified` Header -pub const LAST_MODIFIED: HeaderName = HeaderName::from_lowercase_str("last-modified"); +pub const LAST_MODIFIED: FieldName = FieldName::from_lowercase_str("last-modified"); /// The `Location` Header -pub const LOCATION: HeaderName = HeaderName::from_lowercase_str("location"); +pub const LOCATION: FieldName = FieldName::from_lowercase_str("location"); /// The `Max-Forwards` Header -pub const MAX_FORWARDS: HeaderName = HeaderName::from_lowercase_str("max-forwards"); +pub const MAX_FORWARDS: FieldName = FieldName::from_lowercase_str("max-forwards"); /// The `Pragma` Header -pub const PRAGMA: HeaderName = HeaderName::from_lowercase_str("pragma"); +pub const PRAGMA: FieldName = FieldName::from_lowercase_str("pragma"); /// The `Proxy-Authenticate` Header -pub const PROXY_AUTHENTICATE: HeaderName = HeaderName::from_lowercase_str("proxy-authenticate"); +pub const PROXY_AUTHENTICATE: FieldName = FieldName::from_lowercase_str("proxy-authenticate"); /// The `Proxy-Authorization` Header -pub const PROXY_AUTHORIZATION: HeaderName = HeaderName::from_lowercase_str("proxy-authorization"); +pub const PROXY_AUTHORIZATION: FieldName = FieldName::from_lowercase_str("proxy-authorization"); /// The `Proxy-Connection` Header -pub const PROXY_CONNECTION: HeaderName = HeaderName::from_lowercase_str("proxy-connection"); +pub const PROXY_CONNECTION: FieldName = FieldName::from_lowercase_str("proxy-connection"); /// The `Referer` Header -pub const REFERER: HeaderName = HeaderName::from_lowercase_str("referer"); +pub const REFERER: FieldName = FieldName::from_lowercase_str("referer"); /// The `Retry-After` Header -pub const RETRY_AFTER: HeaderName = HeaderName::from_lowercase_str("retry-after"); +pub const RETRY_AFTER: FieldName = FieldName::from_lowercase_str("retry-after"); /// The `Server` Header -pub const SERVER: HeaderName = HeaderName::from_lowercase_str("server"); +pub const SERVER: FieldName = FieldName::from_lowercase_str("server"); /// The `Server` Header -pub const SERVER_TIMING: HeaderName = HeaderName::from_lowercase_str("server-timing"); +pub const SERVER_TIMING: FieldName = FieldName::from_lowercase_str("server-timing"); /// The `SourceMap` Header -pub const SOURCE_MAP: HeaderName = HeaderName::from_lowercase_str("sourcemap"); +pub const SOURCE_MAP: FieldName = FieldName::from_lowercase_str("sourcemap"); /// The `Strict-Transport-Security` Header -pub const STRICT_TRANSPORT_SECURITY: HeaderName = - HeaderName::from_lowercase_str("strict-transport-security"); +pub const STRICT_TRANSPORT_SECURITY: FieldName = + FieldName::from_lowercase_str("strict-transport-security"); /// The `Te` Header -pub const TE: HeaderName = HeaderName::from_lowercase_str("te"); +pub const TE: FieldName = FieldName::from_lowercase_str("te"); /// The `Timing-Allow-Origin` Header -pub const TIMING_ALLOW_ORIGIN: HeaderName = HeaderName::from_lowercase_str("timing-allow-origin"); +pub const TIMING_ALLOW_ORIGIN: FieldName = FieldName::from_lowercase_str("timing-allow-origin"); /// The `Traceparent` Header -pub const TRACEPARENT: HeaderName = HeaderName::from_lowercase_str("traceparent"); +pub const TRACEPARENT: FieldName = FieldName::from_lowercase_str("traceparent"); /// The `Trailer` Header -pub const TRAILER: HeaderName = HeaderName::from_lowercase_str("trailer"); +pub const TRAILER: FieldName = FieldName::from_lowercase_str("trailer"); /// The `Upgrade` Header -pub const UPGRADE: HeaderName = HeaderName::from_lowercase_str("upgrade"); +pub const UPGRADE: FieldName = FieldName::from_lowercase_str("upgrade"); /// The `User-Agent` Header -pub const USER_AGENT: HeaderName = HeaderName::from_lowercase_str("user-agent"); +pub const USER_AGENT: FieldName = FieldName::from_lowercase_str("user-agent"); /// The `Vary` Header -pub const VARY: HeaderName = HeaderName::from_lowercase_str("vary"); +pub const VARY: FieldName = FieldName::from_lowercase_str("vary"); /// The `Via` Header -pub const VIA: HeaderName = HeaderName::from_lowercase_str("via"); +pub const VIA: FieldName = FieldName::from_lowercase_str("via"); /// The `Warning` Header -pub const WARNING: HeaderName = HeaderName::from_lowercase_str("warning"); +pub const WARNING: FieldName = FieldName::from_lowercase_str("warning"); /// The `WWW-Authenticate` Header -pub const WWW_AUTHENTICATE: HeaderName = HeaderName::from_lowercase_str("www-authenticate"); +pub const WWW_AUTHENTICATE: FieldName = FieldName::from_lowercase_str("www-authenticate"); diff --git a/src/headers/header.rs b/src/headers/header.rs index c5bdb890..97b7f0d5 100644 --- a/src/headers/header.rs +++ b/src/headers/header.rs @@ -1,47 +1,48 @@ use std::ops::Deref; -use crate::headers::{HeaderName, HeaderValue}; +use crate::headers::{FieldName, FieldValue}; /// A trait representing a [`HeaderName`] and [`HeaderValue`] pair. -pub trait Header +#[doc(alias = "Header")] +#[doc(alias = "FieldHeader")] +pub trait Field where Self: Sized, { /// The header's name. - fn header_name(&self) -> HeaderName; + fn field_name(&self) -> FieldName; /// Access the header's value. - fn header_value(&self) -> HeaderValue; + fn field_value(&self) -> FieldValue; +} + +/// Conversion into a [`Field`]. +#[doc(alias = "IntoHeader")] +pub trait IntoField { + /// What type are we converting into? + type IntoField: Field; - /// Create an instance from a header value. - fn from_parts(name: HeaderName, value: HeaderValue) -> crate::Result; + /// Convert into a `Field`. + fn into_field(self) -> Self::IntoField; } -impl Header for (HeaderName, HeaderValue) { - fn header_name(&self) -> HeaderName { +impl Field for (FieldName, FieldValue) { + fn field_name(&self) -> FieldName { self.0 } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { self.1 } - - fn from_parts(name: HeaderName, value: HeaderValue) -> crate::Result { - Ok((name, value)) - } } -impl<'a, T: Header> Header for &'a T { - fn header_name(&self) -> HeaderName { - self.deref().header_name() - } - - fn header_value(&self) -> HeaderValue { - self.deref().header_value() +impl<'a, T: Field> Field for &'a T { + fn field_name(&self) -> FieldName { + self.deref().field_name() } - fn from_parts(name: HeaderName, value: HeaderValue) -> crate::Result { - T::from_parts(name, value) + fn field_value(&self) -> FieldValue { + self.deref().field_value() } } diff --git a/src/headers/header_name.rs b/src/headers/header_name.rs index 430687f8..9628d6e8 100644 --- a/src/headers/header_name.rs +++ b/src/headers/header_name.rs @@ -4,13 +4,13 @@ use std::str::FromStr; use crate::Error; -use super::Header; +use super::Field; /// A header name. #[derive(Clone, PartialEq, Eq, Hash)] -pub struct HeaderName(Cow<'static, str>); +pub struct FieldName(Cow<'static, str>); -impl HeaderName { +impl FieldName { /// Create a new `HeaderName` from a Vec of ASCII bytes. /// /// # Error @@ -22,7 +22,7 @@ impl HeaderName { // This is permitted because ASCII is valid UTF-8, and we just checked that. let string = unsafe { String::from_utf8_unchecked(bytes.to_vec()) }; - Ok(HeaderName(Cow::Owned(string))) + Ok(FieldName(Cow::Owned(string))) } /// Create a new `HeaderName` from an ASCII string. @@ -51,28 +51,28 @@ impl HeaderName { pub unsafe fn from_bytes_unchecked(mut bytes: Vec) -> Self { bytes.make_ascii_lowercase(); let string = String::from_utf8_unchecked(bytes); - HeaderName(Cow::Owned(string)) + FieldName(Cow::Owned(string)) } /// Converts a string assumed to lowercase into a `HeaderName` pub(crate) const fn from_lowercase_str(str: &'static str) -> Self { - HeaderName(Cow::Borrowed(str)) + FieldName(Cow::Borrowed(str)) } } -impl Debug for HeaderName { +impl Debug for FieldName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.0) } } -impl Display for HeaderName { +impl Display for FieldName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } } -impl FromStr for HeaderName { +impl FromStr for FieldName { type Err = Error; /// Create a new `HeaderName`. @@ -80,58 +80,58 @@ impl FromStr for HeaderName { /// This checks it's valid ASCII, and lowercases it. fn from_str(s: &str) -> Result { crate::ensure!(s.is_ascii(), "String slice should be valid ASCII"); - Ok(HeaderName(Cow::Owned(s.to_ascii_lowercase()))) + Ok(FieldName(Cow::Owned(s.to_ascii_lowercase()))) } } -impl From<&HeaderName> for HeaderName { - fn from(value: &HeaderName) -> HeaderName { +impl From<&FieldName> for FieldName { + fn from(value: &FieldName) -> FieldName { value.clone() } } -impl From for HeaderName { - fn from(header: T) -> HeaderName { - header.header_name() +impl From for FieldName { + fn from(header: T) -> FieldName { + header.field_name() } } -impl<'a> From<&'a str> for HeaderName { +impl<'a> From<&'a str> for FieldName { fn from(value: &'a str) -> Self { Self::from_str(value).expect("String slice should be valid ASCII") } } -impl PartialEq for HeaderName { +impl PartialEq for FieldName { fn eq(&self, other: &str) -> bool { - match HeaderName::from_str(other) { + match FieldName::from_str(other) { Err(_) => false, Ok(other) => self == &other, } } } -impl<'a> PartialEq<&'a str> for HeaderName { +impl<'a> PartialEq<&'a str> for FieldName { fn eq(&self, other: &&'a str) -> bool { - match HeaderName::from_str(other) { + match FieldName::from_str(other) { Err(_) => false, Ok(other) => self == &other, } } } -impl PartialEq for HeaderName { +impl PartialEq for FieldName { fn eq(&self, other: &String) -> bool { - match HeaderName::from_str(other) { + match FieldName::from_str(other) { Err(_) => false, Ok(other) => self == &other, } } } -impl<'a> PartialEq<&String> for HeaderName { +impl<'a> PartialEq<&String> for FieldName { fn eq(&self, other: &&String) -> bool { - match HeaderName::from_str(other) { + match FieldName::from_str(other) { Err(_) => false, Ok(other) => self == &other, } @@ -145,8 +145,8 @@ mod tests { #[test] #[allow(clippy::eq_op)] fn test_header_name_static_non_static() { - let static_header = HeaderName::from_lowercase_str("hello"); - let non_static_header = HeaderName::from_str("hello").unwrap(); + let static_header = FieldName::from_lowercase_str("hello"); + let non_static_header = FieldName::from_str("hello").unwrap(); assert_eq!(&static_header, &non_static_header); assert_eq!(&static_header, &static_header); @@ -159,7 +159,7 @@ mod tests { #[test] fn equality() { - let static_header = HeaderName::from_lowercase_str("hello"); + let static_header = FieldName::from_lowercase_str("hello"); assert_eq!(static_header, "hello"); assert_eq!(&static_header, "hello"); assert_eq!(static_header, String::from("hello")); @@ -178,7 +178,7 @@ mod tests { #[test] fn test_debug() { - let header_name = HeaderName::from_str("hello").unwrap(); + let header_name = FieldName::from_str("hello").unwrap(); assert_eq!(format!("{:?}", header_name), "\"hello\""); } } diff --git a/src/headers/header_value.rs b/src/headers/header_value.rs index c8287a1c..726d25d2 100644 --- a/src/headers/header_value.rs +++ b/src/headers/header_value.rs @@ -10,11 +10,11 @@ use crate::Error; /// A header value. #[derive(Clone, Eq, PartialEq, Hash)] -pub struct HeaderValue { +pub struct FieldValue { inner: String, } -impl HeaderValue { +impl FieldValue { /// Create a new `HeaderValue` from a Vec of ASCII bytes. /// /// # Error @@ -48,32 +48,32 @@ impl HeaderValue { } } -impl From for HeaderValue { +impl From for FieldValue { fn from(mime: Mime) -> Self { - HeaderValue { + FieldValue { inner: format!("{}", mime), } } } #[cfg(feature = "cookies")] -impl From> for HeaderValue { +impl From> for FieldValue { fn from(cookie: Cookie<'_>) -> Self { - HeaderValue { + FieldValue { inner: cookie.to_string(), } } } -impl From<&Mime> for HeaderValue { +impl From<&Mime> for FieldValue { fn from(mime: &Mime) -> Self { - HeaderValue { + FieldValue { inner: format!("{}", mime), } } } -impl FromStr for HeaderValue { +impl FromStr for FieldValue { type Err = Error; /// Create a new `HeaderValue`. @@ -87,7 +87,7 @@ impl FromStr for HeaderValue { } } -impl<'a> TryFrom<&'a str> for HeaderValue { +impl<'a> TryFrom<&'a str> for FieldValue { type Error = Error; fn try_from(value: &'a str) -> Result { @@ -95,43 +95,43 @@ impl<'a> TryFrom<&'a str> for HeaderValue { } } -impl Debug for HeaderValue { +impl Debug for FieldValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.inner) } } -impl Display for HeaderValue { +impl Display for FieldValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.inner) } } -impl PartialEq for HeaderValue { +impl PartialEq for FieldValue { fn eq(&self, other: &str) -> bool { self.inner == other } } -impl<'a> PartialEq<&'a str> for HeaderValue { +impl<'a> PartialEq<&'a str> for FieldValue { fn eq(&self, other: &&'a str) -> bool { &self.inner == other } } -impl PartialEq for HeaderValue { +impl PartialEq for FieldValue { fn eq(&self, other: &String) -> bool { &self.inner == other } } -impl<'a> PartialEq<&String> for HeaderValue { +impl<'a> PartialEq<&String> for FieldValue { fn eq(&self, other: &&String) -> bool { &&self.inner == other } } -impl From for HeaderValue { +impl From for FieldValue { fn from(mut other: HeaderValues) -> Self { other.inner.reverse(); other @@ -147,7 +147,7 @@ mod tests { #[test] fn test_debug() { - let header_value = HeaderValue::from_str("foo0").unwrap(); + let header_value = FieldValue::from_str("foo0").unwrap(); assert_eq!(format!("{:?}", header_value), "\"foo0\""); } } diff --git a/src/headers/header_values.rs b/src/headers/header_values.rs index 27fc0045..6f69e432 100644 --- a/src/headers/header_values.rs +++ b/src/headers/header_values.rs @@ -1,4 +1,4 @@ -use crate::headers::{HeaderValue, Values}; +use crate::headers::{FieldValue, Values}; use std::fmt::{self, Debug, Display}; use std::iter::FromIterator; @@ -10,7 +10,7 @@ use std::slice::SliceIndex; /// This always contains at least one header value. #[derive(Clone)] pub struct HeaderValues { - pub(crate) inner: Vec, + pub(crate) inner: Vec, } impl HeaderValues { @@ -20,23 +20,23 @@ impl HeaderValues { } /// Returns a reference or a value depending on the type of index. - pub fn get(&self, index: usize) -> Option<&HeaderValue> { + pub fn get(&self, index: usize) -> Option<&FieldValue> { self.inner.get(index) } /// Returns a mutable reference or a value depending on the type of index. - pub fn get_mut(&mut self, index: usize) -> Option<&mut HeaderValue> { + pub fn get_mut(&mut self, index: usize) -> Option<&mut FieldValue> { self.inner.get_mut(index) } /// Returns `true` if there is a value corresponding to the specified `HeaderValue` in the list, /// `false` otherwise. - pub fn contains(&self, value: &HeaderValue) -> bool { + pub fn contains(&self, value: &FieldValue) -> bool { self.inner.contains(value) } /// Returns the last `HeaderValue`. - pub fn last(&self) -> &HeaderValue { + pub fn last(&self) -> &FieldValue { self.inner .last() .expect("HeaderValues must always contain at least one value") @@ -56,7 +56,7 @@ impl HeaderValues { // } } -impl> Index for HeaderValues { +impl> Index for HeaderValues { type Output = I::Output; #[inline] @@ -65,10 +65,10 @@ impl> Index for HeaderValues { } } -impl FromIterator for HeaderValues { +impl FromIterator for HeaderValues { fn from_iter(iter: I) -> HeaderValues where - I: IntoIterator, + I: IntoIterator, { let iter = iter.into_iter(); let mut output = Vec::with_capacity(iter.size_hint().0); @@ -129,40 +129,40 @@ impl<'a> PartialEq<&String> for HeaderValues { } } -impl From for HeaderValues { - fn from(other: HeaderValue) -> Self { +impl From for HeaderValues { + fn from(other: FieldValue) -> Self { Self { inner: vec![other] } } } -impl AsRef for HeaderValues { - fn as_ref(&self) -> &HeaderValue { +impl AsRef for HeaderValues { + fn as_ref(&self) -> &FieldValue { &self.inner[0] } } -impl AsMut for HeaderValues { - fn as_mut(&mut self) -> &mut HeaderValue { +impl AsMut for HeaderValues { + fn as_mut(&mut self) -> &mut FieldValue { &mut self.inner[0] } } impl Deref for HeaderValues { - type Target = HeaderValue; + type Target = FieldValue; - fn deref(&self) -> &HeaderValue { + fn deref(&self) -> &FieldValue { &self.inner[0] } } impl DerefMut for HeaderValues { - fn deref_mut(&mut self) -> &mut HeaderValue { + fn deref_mut(&mut self) -> &mut FieldValue { &mut self.inner[0] } } impl<'a> IntoIterator for &'a HeaderValues { - type Item = &'a HeaderValue; + type Item = &'a FieldValue; type IntoIter = Values<'a>; #[inline] @@ -171,15 +171,15 @@ impl<'a> IntoIterator for &'a HeaderValues { } } -impl From> for HeaderValues { - fn from(headers: Vec) -> Self { +impl From> for HeaderValues { + fn from(headers: Vec) -> Self { Self { inner: headers } } } impl IntoIterator for HeaderValues { - type Item = HeaderValue; - type IntoIter = std::vec::IntoIter; + type Item = FieldValue; + type IntoIter = std::vec::IntoIter; #[inline] fn into_iter(self) -> Self::IntoIter { diff --git a/src/headers/headers.rs b/src/headers/headers.rs index dd4e32ee..d7c5ee3f 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -8,10 +8,10 @@ use std::ops::Index; use std::str::FromStr; use crate::headers::{ - Header, HeaderName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, + Field, FieldName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, }; -use super::HeaderValue; +use super::FieldValue; /// A collection of HTTP Headers. /// @@ -31,7 +31,7 @@ use super::HeaderValue; /// ``` #[derive(Clone)] pub struct Headers { - pub(crate) headers: HashMap, + pub(crate) headers: HashMap, } impl Headers { @@ -45,25 +45,25 @@ impl Headers { /// Insert a header into the headers. /// /// Not that this will replace all header values for a given header name. - pub fn insert(&mut self, header: H) -> Option { - let name = header.header_name(); - let value = header.header_value(); + pub fn insert(&mut self, header: H) -> Option { + let name = header.field_name(); + let value = header.field_value(); self.headers.insert(name, value) } /// Get a reference to a header. - pub fn get(&self, name: HeaderName) -> Option { + pub fn get(&self, name: FieldName) -> Option { let value = self.headers.get(&name)?; H::from_parts(name, value.clone()).ok() } /// Get a mutable reference to a header. - pub fn get_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { + pub fn get_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { self.headers.get_mut(&name.into()) } /// Remove a header. - pub fn remove(&mut self, name: HeaderName) -> Option { + pub fn remove(&mut self, name: FieldName) -> Option { self.headers.remove(&name.into()) } @@ -95,7 +95,7 @@ impl Headers { } } -impl Index for Headers { +impl Index for Headers { type Output = HeaderValues; /// Returns a reference to the value corresponding to the supplied name. @@ -104,7 +104,7 @@ impl Index for Headers { /// /// Panics if the name is not present in `Headers`. #[inline] - fn index(&self, name: HeaderName) -> &HeaderValues { + fn index(&self, name: FieldName) -> &HeaderValues { self.get(name).expect("no entry found for name") } } @@ -119,13 +119,13 @@ impl Index<&str> for Headers { /// Panics if the name is not present in `Headers`. #[inline] fn index(&self, name: &str) -> &HeaderValues { - let name = HeaderName::from_str(name).expect("string slice needs to be valid ASCII"); + let name = FieldName::from_str(name).expect("string slice needs to be valid ASCII"); self.get(name).expect("no entry found for name") } } impl IntoIterator for Headers { - type Item = (HeaderName, HeaderValues); + type Item = (FieldName, HeaderValues); type IntoIter = IntoIter; /// Returns a iterator of references over the remaining items. @@ -138,7 +138,7 @@ impl IntoIterator for Headers { } impl<'a> IntoIterator for &'a Headers { - type Item = (&'a HeaderName, &'a HeaderValues); + type Item = (&'a FieldName, &'a HeaderValues); type IntoIter = Iter<'a>; #[inline] @@ -148,7 +148,7 @@ impl<'a> IntoIterator for &'a Headers { } impl<'a> IntoIterator for &'a mut Headers { - type Item = (&'a HeaderName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut HeaderValues); type IntoIter = IterMut<'a>; #[inline] @@ -180,12 +180,12 @@ mod tests { use super::*; use std::str::FromStr; - const STATIC_HEADER: HeaderName = HeaderName::from_lowercase_str("hello"); + const STATIC_HEADER: FieldName = FieldName::from_lowercase_str("hello"); #[test] fn test_header_name_static_non_static() -> crate::Result<()> { - let static_header = HeaderName::from_lowercase_str("hello"); - let non_static_header = HeaderName::from_str("hello")?; + let static_header = FieldName::from_lowercase_str("hello"); + let non_static_header = FieldName::from_str("hello")?; let mut headers = Headers::new(); headers.append(STATIC_HEADER, "foo0").unwrap(); diff --git a/src/headers/into_iter.rs b/src/headers/into_iter.rs index 2f1514c2..7f45af42 100644 --- a/src/headers/into_iter.rs +++ b/src/headers/into_iter.rs @@ -1,16 +1,16 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{HeaderName, HeaderValues}; +use crate::headers::{FieldName, HeaderValues}; /// An owning iterator over the entries of `Headers`. #[derive(Debug)] pub struct IntoIter { - pub(super) inner: hash_map::IntoIter, + pub(super) inner: hash_map::IntoIter, } impl Iterator for IntoIter { - type Item = (HeaderName, HeaderValues); + type Item = (FieldName, HeaderValues); fn next(&mut self) -> Option { self.inner.next() diff --git a/src/headers/iter.rs b/src/headers/iter.rs index 2b7aca05..0869b6d7 100644 --- a/src/headers/iter.rs +++ b/src/headers/iter.rs @@ -1,16 +1,16 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{HeaderName, HeaderValues}; +use crate::headers::{FieldName, HeaderValues}; /// Iterator over the headers. #[derive(Debug)] pub struct Iter<'a> { - pub(super) inner: hash_map::Iter<'a, HeaderName, HeaderValues>, + pub(super) inner: hash_map::Iter<'a, FieldName, HeaderValues>, } impl<'a> Iterator for Iter<'a> { - type Item = (&'a HeaderName, &'a HeaderValues); + type Item = (&'a FieldName, &'a HeaderValues); fn next(&mut self) -> Option { self.inner.next() diff --git a/src/headers/iter_mut.rs b/src/headers/iter_mut.rs index 88e5d922..ce052c7d 100644 --- a/src/headers/iter_mut.rs +++ b/src/headers/iter_mut.rs @@ -1,16 +1,16 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{HeaderName, HeaderValues}; +use crate::headers::{FieldName, HeaderValues}; /// Iterator over the headers. #[derive(Debug)] pub struct IterMut<'a> { - pub(super) inner: hash_map::IterMut<'a, HeaderName, HeaderValues>, + pub(super) inner: hash_map::IterMut<'a, FieldName, HeaderValues>, } impl<'a> Iterator for IterMut<'a> { - type Item = (&'a HeaderName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut HeaderValues); fn next(&mut self) -> Option { self.inner.next() diff --git a/src/headers/mod.rs b/src/headers/mod.rs index e23aede0..ba0a63e3 100644 --- a/src/headers/mod.rs +++ b/src/headers/mod.rs @@ -15,9 +15,9 @@ mod to_header_values; mod values; pub use constants::*; -pub use header::Header; -pub use header_name::HeaderName; -pub use header_value::HeaderValue; +pub use header::Field; +pub use header_name::FieldName; +pub use header_value::FieldValue; pub use header_values::HeaderValues; pub use headers::Headers; pub use into_iter::IntoIter; diff --git a/src/headers/names.rs b/src/headers/names.rs index 1bb4c26d..e2eef090 100644 --- a/src/headers/names.rs +++ b/src/headers/names.rs @@ -1,16 +1,16 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{HeaderName, HeaderValues}; +use crate::headers::{FieldName, HeaderValues}; /// Iterator over the headers. #[derive(Debug)] pub struct Names<'a> { - pub(super) inner: hash_map::Keys<'a, HeaderName, HeaderValues>, + pub(super) inner: hash_map::Keys<'a, FieldName, HeaderValues>, } impl<'a> Iterator for Names<'a> { - type Item = &'a HeaderName; + type Item = &'a FieldName; fn next(&mut self) -> Option { self.inner.next() diff --git a/src/headers/to_header_values.rs b/src/headers/to_header_values.rs index 37ef54d6..7909beba 100644 --- a/src/headers/to_header_values.rs +++ b/src/headers/to_header_values.rs @@ -4,27 +4,27 @@ use std::iter; use std::option; use std::slice; -use crate::headers::{Header, HeaderValue, HeaderValues, Values}; +use crate::headers::{Field, FieldValue, HeaderValues, Values}; /// A trait for objects which can be converted or resolved to one or more `HeaderValue`s. pub trait ToHeaderValues { /// Returned iterator over header values which this type may correspond to. - type Iter: Iterator; + type Iter: Iterator; /// Converts this object to an iterator of resolved `HeaderValues`. fn to_header_values(&self) -> crate::Result; } -impl ToHeaderValues for T { - type Iter = option::IntoIter; +impl ToHeaderValues for T { + type Iter = option::IntoIter; fn to_header_values(&self) -> crate::Result { - Ok(Some(self.header_value()).into_iter()) + Ok(Some(self.field_value()).into_iter()) } } -impl ToHeaderValues for HeaderValue { - type Iter = option::IntoIter; +impl ToHeaderValues for FieldValue { + type Iter = option::IntoIter; fn to_header_values(&self) -> crate::Result { Ok(Some(self.clone()).into_iter()) @@ -39,8 +39,8 @@ impl<'a> ToHeaderValues for &'a HeaderValues { } } -impl<'a> ToHeaderValues for &'a [HeaderValue] { - type Iter = iter::Cloned>; +impl<'a> ToHeaderValues for &'a [FieldValue] { + type Iter = iter::Cloned>; fn to_header_values(&self) -> crate::Result { Ok(self.iter().cloned()) @@ -48,7 +48,7 @@ impl<'a> ToHeaderValues for &'a [HeaderValue] { } impl<'a> ToHeaderValues for &'a str { - type Iter = option::IntoIter; + type Iter = option::IntoIter; fn to_header_values(&self) -> crate::Result { let value = self @@ -59,7 +59,7 @@ impl<'a> ToHeaderValues for &'a str { } impl ToHeaderValues for String { - type Iter = option::IntoIter; + type Iter = option::IntoIter; fn to_header_values(&self) -> crate::Result { self.as_str().to_header_values() @@ -67,7 +67,7 @@ impl ToHeaderValues for String { } impl ToHeaderValues for &String { - type Iter = option::IntoIter; + type Iter = option::IntoIter; fn to_header_values(&self) -> crate::Result { self.as_str().to_header_values() @@ -75,7 +75,7 @@ impl ToHeaderValues for &String { } impl ToHeaderValues for Cow<'_, str> { - type Iter = option::IntoIter; + type Iter = option::IntoIter; fn to_header_values(&self) -> crate::Result { self.as_ref().to_header_values() diff --git a/src/headers/values.rs b/src/headers/values.rs index 810c0514..32bef2e0 100644 --- a/src/headers/values.rs +++ b/src/headers/values.rs @@ -1,19 +1,19 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{HeaderName, HeaderValue, HeaderValues}; +use crate::headers::{FieldName, FieldValue, HeaderValues}; /// Iterator over the header values. #[derive(Debug)] pub struct Values<'a> { - pub(super) inner: Option>, + pub(super) inner: Option>, slot: Option<&'a HeaderValues>, cursor: usize, } impl<'a> Values<'a> { /// Constructor for `Headers`. - pub(crate) fn new(inner: hash_map::Values<'a, HeaderName, HeaderValues>) -> Self { + pub(crate) fn new(inner: hash_map::Values<'a, FieldName, HeaderValues>) -> Self { Self { inner: Some(inner), slot: None, @@ -32,7 +32,7 @@ impl<'a> Values<'a> { } impl<'a> Iterator for Values<'a> { - type Item = &'a HeaderValue; + type Item = &'a FieldValue; fn next(&mut self) -> Option { loop { diff --git a/src/lib.rs b/src/lib.rs index eb24affb..7c55acd3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -156,7 +156,7 @@ pub use version::Version; pub use crate::url::Url; #[doc(inline)] -pub use crate::headers::Header; +pub use crate::headers::Field; pub mod security; pub mod trailers; diff --git a/src/mime/mod.rs b/src/mime/mod.rs index 8aa3b03d..694b0415 100644 --- a/src/mime/mod.rs +++ b/src/mime/mod.rs @@ -12,7 +12,7 @@ use std::fmt::{self, Debug, Display}; use std::option; use std::str::FromStr; -use crate::headers::{HeaderValue, ToHeaderValues}; +use crate::headers::{FieldValue, ToHeaderValues}; use infer::Infer; @@ -196,11 +196,11 @@ impl<'a> From<&'a str> for Mime { } impl ToHeaderValues for Mime { - type Iter = option::IntoIter; + type Iter = option::IntoIter; fn to_header_values(&self) -> crate::Result { let mime = self.clone(); - let header: HeaderValue = mime.into(); + let header: FieldValue = mime.into(); // A HeaderValue will always convert into itself. Ok(header.to_header_values().unwrap()) diff --git a/src/other/date.rs b/src/other/date.rs index c2f332f8..c6ad73c7 100644 --- a/src/other/date.rs +++ b/src/other/date.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, DATE}; +use crate::headers::{Field, FieldName, FieldValue, Headers, DATE}; use crate::utils::HttpDate; use std::time::SystemTime; @@ -73,17 +73,17 @@ impl Date { } } -impl Header for Date { - fn header_name(&self) -> HeaderName { +impl Field for Date { + fn field_name(&self) -> FieldName { DATE } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let date: HttpDate = self.at.into(); let output = format!("{}", date); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/other/expect.rs b/src/other/expect.rs index 7aa3387c..ee1b0d62 100644 --- a/src/other/expect.rs +++ b/src/other/expect.rs @@ -1,5 +1,5 @@ -use crate::headers::{HeaderName, HeaderValue, Headers, EXPECT}; -use crate::{ensure_eq_status, headers::Header}; +use crate::headers::{FieldName, FieldValue, Headers, EXPECT}; +use crate::{ensure_eq_status, headers::Field}; use std::fmt::Debug; @@ -56,14 +56,14 @@ impl Expect { } } -impl Header for Expect { - fn header_name(&self) -> HeaderName { +impl Field for Expect { + fn field_name(&self) -> FieldName { EXPECT } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let value = "100-continue"; // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(value.into()) } + unsafe { FieldValue::from_bytes_unchecked(value.into()) } } } diff --git a/src/other/referer.rs b/src/other/referer.rs index f21f4ccd..0bfd60dc 100644 --- a/src/other/referer.rs +++ b/src/other/referer.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, REFERER}; +use crate::headers::{Field, FieldName, FieldValue, Headers, REFERER}; use crate::{bail_status as bail, Status, Url}; use std::convert::TryInto; @@ -86,16 +86,16 @@ impl Referer { } } -impl Header for Referer { - fn header_name(&self) -> HeaderName { +impl Field for Referer { + fn field_name(&self) -> FieldName { REFERER } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = self.location.to_string(); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/other/retry_after.rs b/src/other/retry_after.rs index 68091b86..27b43459 100644 --- a/src/other/retry_after.rs +++ b/src/other/retry_after.rs @@ -1,6 +1,6 @@ use std::time::{Duration, SystemTime, SystemTimeError}; -use crate::headers::{Header, HeaderName, HeaderValue, Headers, RETRY_AFTER}; +use crate::headers::{Field, FieldName, FieldValue, Headers, RETRY_AFTER}; use crate::utils::{fmt_http_date, parse_http_date}; /// Indicate how long the user agent should wait before making a follow-up request. @@ -89,18 +89,18 @@ impl RetryAfter { } } -impl Header for RetryAfter { - fn header_name(&self) -> HeaderName { +impl Field for RetryAfter { + fn field_name(&self) -> FieldName { RETRY_AFTER } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = match self.inner { RetryDirective::Duration(dur) => format!("{}", dur.as_secs()), RetryDirective::SystemTime(at) => fmt_http_date(at), }; // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/other/source_map.rs b/src/other/source_map.rs index 1d6746e3..749c578f 100644 --- a/src/other/source_map.rs +++ b/src/other/source_map.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, SOURCE_MAP}; +use crate::headers::{Field, FieldName, FieldValue, Headers, SOURCE_MAP}; use crate::{bail_status as bail, Status, Url}; use std::convert::TryInto; @@ -83,16 +83,16 @@ impl SourceMap { } } -impl Header for SourceMap { - fn header_name(&self) -> HeaderName { +impl Field for SourceMap { + fn field_name(&self) -> FieldName { SOURCE_MAP } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = self.location.to_string(); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/proxies/forwarded.rs b/src/proxies/forwarded.rs index 30e491b0..81dae52a 100644 --- a/src/proxies/forwarded.rs +++ b/src/proxies/forwarded.rs @@ -1,14 +1,14 @@ use crate::{ - headers::{Header, HeaderName, HeaderValue, Headers, FORWARDED}, + headers::{Field, FieldName, FieldValue, Headers, FORWARDED}, parse_utils::{parse_quoted_string, parse_token}, }; use std::{borrow::Cow, convert::TryFrom, fmt::Write, net::IpAddr}; // these constants are private because they are nonstandard -const X_FORWARDED_FOR: HeaderName = HeaderName::from_lowercase_str("x-forwarded-for"); -const X_FORWARDED_PROTO: HeaderName = HeaderName::from_lowercase_str("x-forwarded-proto"); -const X_FORWARDED_BY: HeaderName = HeaderName::from_lowercase_str("x-forwarded-by"); -const X_FORWARDED_HOST: HeaderName = HeaderName::from_lowercase_str("x-forwarded-host"); +const X_FORWARDED_FOR: FieldName = FieldName::from_lowercase_str("x-forwarded-for"); +const X_FORWARDED_PROTO: FieldName = FieldName::from_lowercase_str("x-forwarded-proto"); +const X_FORWARDED_BY: FieldName = FieldName::from_lowercase_str("x-forwarded-by"); +const X_FORWARDED_HOST: FieldName = FieldName::from_lowercase_str("x-forwarded-host"); /// A rust representation of the [forwarded /// header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded). @@ -358,11 +358,11 @@ impl<'a> Forwarded<'a> { } } -impl<'a> Header for Forwarded<'a> { - fn header_name(&self) -> HeaderName { +impl<'a> Field for Forwarded<'a> { + fn field_name(&self) -> FieldName { FORWARDED } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); if let Some(by) = self.by() { write!(&mut output, "by={};", by).unwrap(); @@ -391,7 +391,7 @@ impl<'a> Header for Forwarded<'a> { output.pop(); // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } @@ -439,7 +439,7 @@ fn starts_with_ignore_case(start: &'static str, input: &str) -> bool { impl std::fmt::Display for Forwarded<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(self.header_value().as_str()) + f.write_str(self.field_value().as_str()) } } @@ -665,7 +665,7 @@ mod tests { ]; for input in inputs { let forwarded = Forwarded::parse(input).map_err(|_| crate::Error::new_adhoc(input))?; - let header = forwarded.header_value(); + let header = forwarded.field_value(); let parsed = Forwarded::parse(header.as_str())?; assert_eq!(forwarded, parsed); } diff --git a/src/request.rs b/src/request.rs index 6b3bb355..ef462968 100644 --- a/src/request.rs +++ b/src/request.rs @@ -9,8 +9,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::{DeserializeOwned, Serialize}; use crate::headers::{ - self, HeaderName, HeaderValue, HeaderValues, Headers, Names, ToHeaderValues, Values, - CONTENT_TYPE, + self, FieldName, FieldValue, HeaderValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -408,17 +407,17 @@ impl Request { } /// Get an HTTP header. - pub fn header(&self, name: impl Into) -> Option<&HeaderValues> { + pub fn header(&self, name: impl Into) -> Option<&HeaderValues> { self.headers.get(name) } /// Get a mutable reference to a header. - pub fn header_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { + pub fn header_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { self.headers.get_mut(name.into()) } /// Remove a header. - pub fn remove_header(&mut self, name: impl Into) -> Option { + pub fn remove_header(&mut self, name: impl Into) -> Option { self.headers.remove(name.into()) } @@ -438,7 +437,7 @@ impl Request { /// ``` pub fn insert_header( &mut self, - name: impl Into, + name: impl Into, values: impl ToHeaderValues, ) -> crate::Result> { self.headers.insert(name, values) @@ -464,7 +463,7 @@ impl Request { /// ``` pub fn append_header( &mut self, - name: impl Into, + name: impl Into, values: impl ToHeaderValues, ) -> crate::Result<()> { self.headers.append(name, values) @@ -473,7 +472,7 @@ impl Request { /// Set the response MIME. // TODO: return a parsed MIME pub fn set_content_type(&mut self, mime: Mime) -> Option { - let value: HeaderValue = mime.into(); + let value: FieldValue = mime.into(); // A Mime instance is guaranteed to be valid header name. self.insert_header(CONTENT_TYPE, value).unwrap() @@ -945,7 +944,7 @@ impl From for Body { } } -impl Index for Request { +impl Index for Request { type Output = HeaderValues; /// Returns a reference to the value corresponding to the supplied name. @@ -954,7 +953,7 @@ impl Index for Request { /// /// Panics if the name is not present in `Request`. #[inline] - fn index(&self, name: HeaderName) -> &HeaderValues { + fn index(&self, name: FieldName) -> &HeaderValues { self.headers.index(name) } } @@ -974,7 +973,7 @@ impl Index<&str> for Request { } impl IntoIterator for Request { - type Item = (HeaderName, HeaderValues); + type Item = (FieldName, HeaderValues); type IntoIter = headers::IntoIter; /// Returns a iterator of references over the remaining items. @@ -985,7 +984,7 @@ impl IntoIterator for Request { } impl<'a> IntoIterator for &'a Request { - type Item = (&'a HeaderName, &'a HeaderValues); + type Item = (&'a FieldName, &'a HeaderValues); type IntoIter = headers::Iter<'a>; #[inline] @@ -995,7 +994,7 @@ impl<'a> IntoIterator for &'a Request { } impl<'a> IntoIterator for &'a mut Request { - type Item = (&'a HeaderName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut HeaderValues); type IntoIter = headers::IterMut<'a>; #[inline] diff --git a/src/response.rs b/src/response.rs index 4b4a4aa6..18c09017 100644 --- a/src/response.rs +++ b/src/response.rs @@ -10,8 +10,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::DeserializeOwned; use crate::headers::{ - self, HeaderName, HeaderValue, HeaderValues, Headers, Names, ToHeaderValues, Values, - CONTENT_TYPE, + self, FieldName, FieldValue, HeaderValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -87,17 +86,17 @@ impl Response { } /// Get a mutable reference to a header. - pub fn header_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { + pub fn header_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { self.headers.get_mut(name.into()) } /// Get an HTTP header. - pub fn header(&self, name: impl Into) -> Option<&HeaderValues> { + pub fn header(&self, name: impl Into) -> Option<&HeaderValues> { self.headers.get(name.into()) } /// Remove a header. - pub fn remove_header(&mut self, name: impl Into) -> Option { + pub fn remove_header(&mut self, name: impl Into) -> Option { self.headers.remove(name.into()) } @@ -117,7 +116,7 @@ impl Response { /// ``` pub fn insert_header( &mut self, - name: impl Into, + name: impl Into, values: impl ToHeaderValues, ) -> crate::Result> { self.headers.insert(name, values) @@ -143,7 +142,7 @@ impl Response { /// ``` pub fn append_header( &mut self, - name: impl Into, + name: impl Into, values: impl ToHeaderValues, ) -> crate::Result<()> { self.headers.append(name, values) @@ -378,7 +377,7 @@ impl Response { /// Set the response MIME. pub fn set_content_type(&mut self, mime: Mime) -> Option { - let value: HeaderValue = mime.into(); + let value: FieldValue = mime.into(); // A Mime instance is guaranteed to be valid header name. self.insert_header(CONTENT_TYPE, value).unwrap() @@ -644,7 +643,7 @@ impl From<()> for Response { Response::new(StatusCode::NoContent) } } -impl Index for Response { +impl Index for Response { type Output = HeaderValues; /// Returns a reference to the value corresponding to the supplied name. @@ -653,7 +652,7 @@ impl Index for Response { /// /// Panics if the name is not present in `Response`. #[inline] - fn index(&self, name: HeaderName) -> &HeaderValues { + fn index(&self, name: FieldName) -> &HeaderValues { self.headers.index(name) } } @@ -691,7 +690,7 @@ where } impl IntoIterator for Response { - type Item = (HeaderName, HeaderValues); + type Item = (FieldName, HeaderValues); type IntoIter = headers::IntoIter; /// Returns a iterator of references over the remaining items. @@ -702,7 +701,7 @@ impl IntoIterator for Response { } impl<'a> IntoIterator for &'a Response { - type Item = (&'a HeaderName, &'a HeaderValues); + type Item = (&'a FieldName, &'a HeaderValues); type IntoIter = headers::Iter<'a>; #[inline] @@ -712,7 +711,7 @@ impl<'a> IntoIterator for &'a Response { } impl<'a> IntoIterator for &'a mut Response { - type Item = (&'a HeaderName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut HeaderValues); type IntoIter = headers::IterMut<'a>; #[inline] diff --git a/src/security/mod.rs b/src/security/mod.rs index 2cb9b6a1..34f75bee 100644 --- a/src/security/mod.rs +++ b/src/security/mod.rs @@ -15,7 +15,7 @@ // //! assert_eq!(res["X-XSS-Protection"], "1; mode=block"); //! ``` -use crate::headers::{HeaderName, HeaderValue, Headers}; +use crate::headers::{FieldName, FieldValue, Headers}; mod csp; mod strict_transport_security; @@ -117,8 +117,8 @@ pub fn frameguard(mut headers: impl AsMut, guard: Option) // /// assert_eq!(headers.get("X-Powered-By"), None); // /// ``` #[inline] -pub fn powered_by(mut headers: impl AsMut, value: Option) { - let name = HeaderName::from_lowercase_str("X-Powered-By"); +pub fn powered_by(mut headers: impl AsMut, value: Option) { + let name = FieldName::from_lowercase_str("X-Powered-By"); match value { Some(value) => { // Can never fail as value is already a HeaderValue, could use unsafe version of insert diff --git a/src/security/strict_transport_security.rs b/src/security/strict_transport_security.rs index 089d79ae..874f12e2 100644 --- a/src/security/strict_transport_security.rs +++ b/src/security/strict_transport_security.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers}; +use crate::headers::{Field, FieldName, FieldValue, Headers}; use crate::Status; use crate::headers::STRICT_TRANSPORT_SECURITY; @@ -70,12 +70,12 @@ impl StrictTransportSecurity { } } -impl Header for StrictTransportSecurity { - fn header_name(&self) -> HeaderName { +impl Field for StrictTransportSecurity { + fn field_name(&self) -> FieldName { STRICT_TRANSPORT_SECURITY } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let max_age = self.max_age.as_secs(); let mut output = format!("max-age={}", max_age); if self.include_subdomains { @@ -86,7 +86,7 @@ impl Header for StrictTransportSecurity { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/security/timing_allow_origin.rs b/src/security/timing_allow_origin.rs index 77417cb6..87f471ab 100644 --- a/src/security/timing_allow_origin.rs +++ b/src/security/timing_allow_origin.rs @@ -26,7 +26,7 @@ //! # Ok(()) } //! ``` -use crate::headers::{Header, HeaderName, HeaderValue, Headers, TIMING_ALLOW_ORIGIN}; +use crate::headers::{Field, FieldName, FieldValue, Headers, TIMING_ALLOW_ORIGIN}; use crate::{Status, Url}; use std::fmt::Write; @@ -131,11 +131,11 @@ impl TimingAllowOrigin { } } -impl Header for TimingAllowOrigin { - fn header_name(&self) -> HeaderName { +impl Field for TimingAllowOrigin { + fn field_name(&self) -> FieldName { TIMING_ALLOW_ORIGIN } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, origin) in self.origins.iter().enumerate() { match n { @@ -152,7 +152,7 @@ impl Header for TimingAllowOrigin { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/server/allow.rs b/src/server/allow.rs index 0e4f914f..42a25096 100644 --- a/src/server/allow.rs +++ b/src/server/allow.rs @@ -1,6 +1,6 @@ //! List the set of methods supported by a resource. -use crate::headers::{Header, HeaderName, HeaderValue, Headers, ALLOW}; +use crate::headers::{Field, FieldName, FieldValue, Headers, ALLOW}; use crate::Method; use std::collections::{hash_set, HashSet}; @@ -84,11 +84,11 @@ impl Allow { } } -impl Header for Allow { - fn header_name(&self) -> HeaderName { +impl Field for Allow { + fn field_name(&self) -> FieldName { ALLOW } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, method) in self.entries.iter().enumerate() { match n { @@ -98,7 +98,7 @@ impl Header for Allow { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/trace/server_timing/metric.rs b/src/trace/server_timing/metric.rs index ed55c189..407c8b95 100644 --- a/src/trace/server_timing/metric.rs +++ b/src/trace/server_timing/metric.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use crate::headers::HeaderValue; +use crate::headers::FieldValue; /// An individual entry into `ServerTiming`. // @@ -52,8 +52,8 @@ impl Metric { } } -impl From for HeaderValue { - fn from(entry: Metric) -> HeaderValue { +impl From for FieldValue { + fn from(entry: Metric) -> FieldValue { let mut string = entry.name; // Format a `Duration` into the format that the spec expects. @@ -69,14 +69,14 @@ impl From for HeaderValue { }; // SAFETY: we validate that the values are valid ASCII on creation. - unsafe { HeaderValue::from_bytes_unchecked(string.into_bytes()) } + unsafe { FieldValue::from_bytes_unchecked(string.into_bytes()) } } } #[cfg(test)] mod test { use super::*; - use crate::headers::HeaderValue; + use crate::headers::FieldValue; use std::time::Duration; #[test] @@ -86,16 +86,16 @@ mod test { let dur = Duration::from_secs(1); let desc = String::from("A server timing"); - let val: HeaderValue = Metric::new(name.clone(), None, None)?.into(); + let val: FieldValue = Metric::new(name.clone(), None, None)?.into(); assert_eq!(val, "Server"); - let val: HeaderValue = Metric::new(name.clone(), Some(dur), None)?.into(); + let val: FieldValue = Metric::new(name.clone(), Some(dur), None)?.into(); assert_eq!(val, "Server; dur=1000"); - let val: HeaderValue = Metric::new(name.clone(), None, Some(desc.clone()))?.into(); + let val: FieldValue = Metric::new(name.clone(), None, Some(desc.clone()))?.into(); assert_eq!(val, r#"Server; desc="A server timing""#); - let val: HeaderValue = Metric::new(name.clone(), Some(dur), Some(desc.clone()))?.into(); + let val: FieldValue = Metric::new(name.clone(), Some(dur), Some(desc.clone()))?.into(); assert_eq!(val, r#"Server; dur=1000; desc="A server timing""#); Ok(()) } diff --git a/src/trace/server_timing/mod.rs b/src/trace/server_timing/mod.rs index aaabed97..c2aec711 100644 --- a/src/trace/server_timing/mod.rs +++ b/src/trace/server_timing/mod.rs @@ -32,7 +32,7 @@ use std::iter::Iterator; use std::slice; -use crate::headers::{Header, HeaderName, HeaderValue, Headers, SERVER_TIMING}; +use crate::headers::{Field, FieldName, FieldValue, Headers, SERVER_TIMING}; /// Metrics and descriptions for the given request-response cycle. /// @@ -105,15 +105,15 @@ impl ServerTiming { } } -impl Header for ServerTiming { - fn header_name(&self) -> HeaderName { +impl Field for ServerTiming { + fn field_name(&self) -> FieldName { SERVER_TIMING } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, timing) in self.timings.iter().enumerate() { - let timing: HeaderValue = timing.clone().into(); + let timing: FieldValue = timing.clone().into(); match n { 0 => write!(output, "{}", timing).unwrap(), _ => write!(output, ", {}", timing).unwrap(), @@ -121,7 +121,7 @@ impl Header for ServerTiming { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/trace/trace_context.rs b/src/trace/trace_context.rs index 3bc062f7..68c462a4 100644 --- a/src/trace/trace_context.rs +++ b/src/trace/trace_context.rs @@ -1,6 +1,6 @@ use std::fmt; -use crate::headers::{Header, HeaderName, HeaderValue, Headers, TRACEPARENT}; +use crate::headers::{Field, FieldName, FieldValue, Headers, TRACEPARENT}; use crate::Status; /// Extract and apply [Trace-Context](https://w3c.github.io/trace-context/) headers. @@ -195,14 +195,14 @@ impl TraceContext { } } -impl Header for TraceContext { - fn header_name(&self) -> HeaderName { +impl Field for TraceContext { + fn field_name(&self) -> FieldName { TRACEPARENT } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let output = format!("{}", self); - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/trailers.rs b/src/trailers.rs index c65801c6..2aae49de 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -49,7 +49,7 @@ //! - [HTTP/2 spec: HTTP Sequence](https://http2.github.io/http2-spec/#HttpSequence) use crate::headers::{ - HeaderName, HeaderValues, Headers, Iter, IterMut, Names, ToHeaderValues, Values, + FieldName, HeaderValues, Headers, Iter, IterMut, Names, ToHeaderValues, Values, }; use futures_lite::Stream; @@ -89,7 +89,7 @@ impl Trailers { /// ``` pub fn insert( &mut self, - name: impl Into, + name: impl Into, values: impl ToHeaderValues, ) -> crate::Result> { self.headers.insert(name, values) @@ -114,24 +114,24 @@ impl Trailers { /// ``` pub fn append( &mut self, - name: impl Into, + name: impl Into, values: impl ToHeaderValues, ) -> crate::Result<()> { self.headers.append(name, values) } /// Get a reference to a header. - pub fn get(&self, name: impl Into) -> Option<&HeaderValues> { + pub fn get(&self, name: impl Into) -> Option<&HeaderValues> { self.headers.get(name) } /// Get a mutable reference to a header. - pub fn get_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { + pub fn get_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { self.headers.get_mut(name) } /// Remove a header. - pub fn remove(&mut self, name: impl Into) -> Option { + pub fn remove(&mut self, name: impl Into) -> Option { self.headers.remove(name) } @@ -181,7 +181,7 @@ impl DerefMut for Trailers { } } -impl Index for Trailers { +impl Index for Trailers { type Output = HeaderValues; /// Returns a reference to the value corresponding to the supplied name. @@ -190,7 +190,7 @@ impl Index for Trailers { /// /// Panics if the name is not present in `Trailers`. #[inline] - fn index(&self, name: HeaderName) -> &HeaderValues { + fn index(&self, name: FieldName) -> &HeaderValues { self.headers.index(name) } } diff --git a/src/transfer/encoding.rs b/src/transfer/encoding.rs index c64b3a45..e0bb220e 100644 --- a/src/transfer/encoding.rs +++ b/src/transfer/encoding.rs @@ -1,4 +1,4 @@ -use crate::headers::HeaderValue; +use crate::headers::FieldValue; use std::fmt::{self, Display}; /// Available compression algorithms. @@ -56,9 +56,9 @@ impl Display for Encoding { } } -impl From for HeaderValue { +impl From for FieldValue { fn from(directive: Encoding) -> Self { let s = directive.to_string(); - unsafe { HeaderValue::from_bytes_unchecked(s.into_bytes()) } + unsafe { FieldValue::from_bytes_unchecked(s.into_bytes()) } } } diff --git a/src/transfer/encoding_proposal.rs b/src/transfer/encoding_proposal.rs index 72f083d5..710d8ed3 100644 --- a/src/transfer/encoding_proposal.rs +++ b/src/transfer/encoding_proposal.rs @@ -1,5 +1,5 @@ use crate::ensure; -use crate::headers::HeaderValue; +use crate::headers::FieldValue; use crate::transfer::Encoding; use crate::utils::parse_weight; @@ -110,13 +110,13 @@ impl PartialOrd for EncodingProposal { } } -impl From for HeaderValue { - fn from(entry: EncodingProposal) -> HeaderValue { +impl From for FieldValue { + fn from(entry: EncodingProposal) -> FieldValue { let s = match entry.weight { Some(weight) => format!("{};q={:.3}", entry.encoding, weight), None => entry.encoding.to_string(), }; - unsafe { HeaderValue::from_bytes_unchecked(s.into_bytes()) } + unsafe { FieldValue::from_bytes_unchecked(s.into_bytes()) } } } diff --git a/src/transfer/te.rs b/src/transfer/te.rs index 5da44707..18260113 100644 --- a/src/transfer/te.rs +++ b/src/transfer/te.rs @@ -1,4 +1,4 @@ -use crate::headers::{self, Header, HeaderName, HeaderValue, Headers}; +use crate::headers::{self, Field, FieldName, FieldValue, Headers}; use crate::transfer::{Encoding, EncodingProposal, TransferEncoding}; use crate::utils::sort_by_weight; use crate::{Error, StatusCode}; @@ -151,15 +151,15 @@ impl TE { } } -impl Header for TE { - fn header_name(&self) -> HeaderName { +impl Field for TE { + fn field_name(&self) -> FieldName { headers::TE } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, directive) in self.entries.iter().enumerate() { - let directive: HeaderValue = (*directive).into(); + let directive: FieldValue = (*directive).into(); match n { 0 => write!(output, "{}", directive).unwrap(), _ => write!(output, ", {}", directive).unwrap(), @@ -174,7 +174,7 @@ impl Header for TE { } // SAFETY: the internal string is validated to be ASCII. - unsafe { HeaderValue::from_bytes_unchecked(output.into()) } + unsafe { FieldValue::from_bytes_unchecked(output.into()) } } } diff --git a/src/transfer/transfer_encoding.rs b/src/transfer/transfer_encoding.rs index 7fede4aa..07e650b0 100644 --- a/src/transfer/transfer_encoding.rs +++ b/src/transfer/transfer_encoding.rs @@ -1,4 +1,4 @@ -use crate::headers::{Header, HeaderName, HeaderValue, Headers, TRANSFER_ENCODING}; +use crate::headers::{Field, FieldName, FieldValue, Headers, TRANSFER_ENCODING}; use crate::transfer::{Encoding, EncodingProposal}; use std::fmt::{self, Debug}; @@ -64,11 +64,11 @@ impl TransferEncoding { } } -impl Header for TransferEncoding { - fn header_name(&self) -> HeaderName { +impl Field for TransferEncoding { + fn field_name(&self) -> FieldName { TRANSFER_ENCODING } - fn header_value(&self) -> HeaderValue { + fn field_value(&self) -> FieldValue { self.inner.into() } } From a9fc3590c342f0f8042ed8aba87585e6327433b6 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 19 Jun 2022 02:23:22 +0200 Subject: [PATCH 4/9] update more header stuff --- src/headers/header.rs | 50 +++++++++++++-------------- src/headers/header_value.rs | 6 ++-- src/headers/header_values.rs | 46 ++++++++++++------------- src/headers/headers.rs | 60 ++++++--------------------------- src/headers/into_iter.rs | 6 ++-- src/headers/iter.rs | 6 ++-- src/headers/iter_mut.rs | 6 ++-- src/headers/mod.rs | 2 +- src/headers/names.rs | 4 +-- src/headers/to_header_values.rs | 4 +-- src/headers/values.rs | 10 +++--- src/request.rs | 26 +++++++------- src/response.rs | 26 +++++++------- src/trailers.rs | 18 +++++----- 14 files changed, 116 insertions(+), 154 deletions(-) diff --git a/src/headers/header.rs b/src/headers/header.rs index 97b7f0d5..f6dcae07 100644 --- a/src/headers/header.rs +++ b/src/headers/header.rs @@ -1,48 +1,48 @@ -use std::ops::Deref; - use crate::headers::{FieldName, FieldValue}; /// A trait representing a [`HeaderName`] and [`HeaderValue`] pair. +/// +/// # Specifications +/// +/// - [RFC 9110, section 5: Fields](https://www.rfc-editor.org/rfc/rfc9110.html#fields) #[doc(alias = "Header")] #[doc(alias = "FieldHeader")] pub trait Field where Self: Sized, { - /// The header's name. - fn field_name(&self) -> FieldName; + /// The header's field name. + const FIELD_NAME: FieldName; /// Access the header's value. fn field_value(&self) -> FieldValue; + + /// Create a field from its parts. + // TODO: move this to a separate trait. + fn from_field_pair(name: FieldName, value: FieldValue) -> Result; } -/// Conversion into a [`Field`]. -#[doc(alias = "IntoHeader")] -pub trait IntoField { - /// What type are we converting into? - type IntoField: Field; +mod void { + use core::marker::PhantomData; - /// Convert into a `Field`. - fn into_field(self) -> Self::IntoField; -} + enum Void {} -impl Field for (FieldName, FieldValue) { - fn field_name(&self) -> FieldName { - self.0 - } + impl Copy for Void {} - fn field_value(&self) -> FieldValue { - self.1 + impl Clone for Void { + fn clone(&self) -> Self { + match *self {} + } } -} -impl<'a, T: Field> Field for &'a T { - fn field_name(&self) -> FieldName { - self.deref().field_name() - } + pub struct MustBeStr(PhantomData, Void); + + impl Copy for MustBeStr {} - fn field_value(&self) -> FieldValue { - self.deref().field_value() + impl Clone for MustBeStr { + fn clone(&self) -> Self { + *self + } } } diff --git a/src/headers/header_value.rs b/src/headers/header_value.rs index 726d25d2..a23d3791 100644 --- a/src/headers/header_value.rs +++ b/src/headers/header_value.rs @@ -4,7 +4,7 @@ use std::str::FromStr; #[cfg(feature = "cookies")] use crate::cookies::Cookie; -use crate::headers::HeaderValues; +use crate::headers::FieldValues; use crate::mime::Mime; use crate::Error; @@ -131,8 +131,8 @@ impl<'a> PartialEq<&String> for FieldValue { } } -impl From for FieldValue { - fn from(mut other: HeaderValues) -> Self { +impl From for FieldValue { + fn from(mut other: FieldValues) -> Self { other.inner.reverse(); other .inner diff --git a/src/headers/header_values.rs b/src/headers/header_values.rs index 6f69e432..ee46b521 100644 --- a/src/headers/header_values.rs +++ b/src/headers/header_values.rs @@ -9,11 +9,11 @@ use std::slice::SliceIndex; /// /// This always contains at least one header value. #[derive(Clone)] -pub struct HeaderValues { +pub struct FieldValues { pub(crate) inner: Vec, } -impl HeaderValues { +impl FieldValues { /// Move all values from `other` into `self`, leaving `other` empty. pub fn append(&mut self, other: &mut Self) { self.inner.append(&mut other.inner) @@ -56,7 +56,7 @@ impl HeaderValues { // } } -impl> Index for HeaderValues { +impl> Index for FieldValues { type Output = I::Output; #[inline] @@ -65,8 +65,8 @@ impl> Index for HeaderValues { } } -impl FromIterator for HeaderValues { - fn from_iter(iter: I) -> HeaderValues +impl FromIterator for FieldValues { + fn from_iter(iter: I) -> FieldValues where I: IntoIterator, { @@ -75,11 +75,11 @@ impl FromIterator for HeaderValues { for v in iter { output.push(v); } - HeaderValues { inner: output } + FieldValues { inner: output } } } -impl Debug for HeaderValues { +impl Debug for FieldValues { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.inner.len() == 1 { write!(f, "{:?}", self.inner[0]) @@ -89,7 +89,7 @@ impl Debug for HeaderValues { } } -impl Display for HeaderValues { +impl Display for FieldValues { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut list = f.debug_list(); for v in &self.inner { @@ -99,55 +99,55 @@ impl Display for HeaderValues { } } -impl PartialEq for HeaderValues { +impl PartialEq for FieldValues { fn eq(&self, other: &str) -> bool { self.inner.len() == 1 && self.inner[0] == other } } -impl<'a> PartialEq<&'a str> for HeaderValues { +impl<'a> PartialEq<&'a str> for FieldValues { fn eq(&self, other: &&'a str) -> bool { self.inner.len() == 1 && &self.inner[0] == other } } -impl<'a> PartialEq<[&'a str]> for HeaderValues { +impl<'a> PartialEq<[&'a str]> for FieldValues { fn eq(&self, other: &[&'a str]) -> bool { self.inner.iter().eq(other.iter()) } } -impl PartialEq for HeaderValues { +impl PartialEq for FieldValues { fn eq(&self, other: &String) -> bool { self.inner.len() == 1 && self.inner[0] == *other } } -impl<'a> PartialEq<&String> for HeaderValues { +impl<'a> PartialEq<&String> for FieldValues { fn eq(&self, other: &&String) -> bool { self.inner.len() == 1 && self.inner[0] == **other } } -impl From for HeaderValues { +impl From for FieldValues { fn from(other: FieldValue) -> Self { Self { inner: vec![other] } } } -impl AsRef for HeaderValues { +impl AsRef for FieldValues { fn as_ref(&self) -> &FieldValue { &self.inner[0] } } -impl AsMut for HeaderValues { +impl AsMut for FieldValues { fn as_mut(&mut self) -> &mut FieldValue { &mut self.inner[0] } } -impl Deref for HeaderValues { +impl Deref for FieldValues { type Target = FieldValue; fn deref(&self) -> &FieldValue { @@ -155,13 +155,13 @@ impl Deref for HeaderValues { } } -impl DerefMut for HeaderValues { +impl DerefMut for FieldValues { fn deref_mut(&mut self) -> &mut FieldValue { &mut self.inner[0] } } -impl<'a> IntoIterator for &'a HeaderValues { +impl<'a> IntoIterator for &'a FieldValues { type Item = &'a FieldValue; type IntoIter = Values<'a>; @@ -171,13 +171,13 @@ impl<'a> IntoIterator for &'a HeaderValues { } } -impl From> for HeaderValues { +impl From> for FieldValues { fn from(headers: Vec) -> Self { Self { inner: headers } } } -impl IntoIterator for HeaderValues { +impl IntoIterator for FieldValues { type Item = FieldValue; type IntoIter = std::vec::IntoIter; @@ -193,14 +193,14 @@ mod tests { #[test] fn test_debug_single() { - let header_values = HeaderValues { + let header_values = FieldValues { inner: vec!["foo0".parse().unwrap()], }; assert_eq!(format!("{:?}", header_values), "\"foo0\""); } #[test] fn test_debug_multiple() { - let header_values = HeaderValues { + let header_values = FieldValues { inner: vec!["foo0".parse().unwrap(), "foo1".parse().unwrap()], }; assert_eq!(format!("{:?}", header_values), r#"["foo0", "foo1"]"#); diff --git a/src/headers/headers.rs b/src/headers/headers.rs index d7c5ee3f..39e889dc 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -1,14 +1,11 @@ //! HTTP headers. use std::collections::HashMap; -use std::convert::Into; use std::fmt::{self, Debug}; use std::iter::IntoIterator; -use std::ops::Index; -use std::str::FromStr; use crate::headers::{ - Field, FieldName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, + Field, FieldName, FieldValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, }; use super::FieldValue; @@ -46,25 +43,19 @@ impl Headers { /// /// Not that this will replace all header values for a given header name. pub fn insert(&mut self, header: H) -> Option { - let name = header.field_name(); - let value = header.field_value(); - self.headers.insert(name, value) + self.headers.insert(H::FIELD_NAME, header.field_value()) } /// Get a reference to a header. - pub fn get(&self, name: FieldName) -> Option { - let value = self.headers.get(&name)?; - H::from_parts(name, value.clone()).ok() - } - - /// Get a mutable reference to a header. - pub fn get_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { - self.headers.get_mut(&name.into()) + pub fn get(&self) -> Option { + let value = self.headers.get(&F::FIELD_NAME)?; + F::from_field_pair(F::FIELD_NAME, value.clone()).ok() } /// Remove a header. - pub fn remove(&mut self, name: FieldName) -> Option { - self.headers.remove(&name.into()) + pub fn remove(&mut self) -> Option { + let value = self.headers.remove(&F::FIELD_NAME)?; + F::from_field_pair(F::FIELD_NAME, value.clone()).ok() } /// An iterator visiting all header pairs in arbitrary order. @@ -95,37 +86,8 @@ impl Headers { } } -impl Index for Headers { - type Output = HeaderValues; - - /// Returns a reference to the value corresponding to the supplied name. - /// - /// # Panics - /// - /// Panics if the name is not present in `Headers`. - #[inline] - fn index(&self, name: FieldName) -> &HeaderValues { - self.get(name).expect("no entry found for name") - } -} - -impl Index<&str> for Headers { - type Output = HeaderValues; - - /// Returns a reference to the value corresponding to the supplied name. - /// - /// # Panics - /// - /// Panics if the name is not present in `Headers`. - #[inline] - fn index(&self, name: &str) -> &HeaderValues { - let name = FieldName::from_str(name).expect("string slice needs to be valid ASCII"); - self.get(name).expect("no entry found for name") - } -} - impl IntoIterator for Headers { - type Item = (FieldName, HeaderValues); + type Item = (FieldName, FieldValues); type IntoIter = IntoIter; /// Returns a iterator of references over the remaining items. @@ -138,7 +100,7 @@ impl IntoIterator for Headers { } impl<'a> IntoIterator for &'a Headers { - type Item = (&'a FieldName, &'a HeaderValues); + type Item = (&'a FieldName, &'a FieldValues); type IntoIter = Iter<'a>; #[inline] @@ -148,7 +110,7 @@ impl<'a> IntoIterator for &'a Headers { } impl<'a> IntoIterator for &'a mut Headers { - type Item = (&'a FieldName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut FieldValues); type IntoIter = IterMut<'a>; #[inline] diff --git a/src/headers/into_iter.rs b/src/headers/into_iter.rs index 7f45af42..fdf56e7d 100644 --- a/src/headers/into_iter.rs +++ b/src/headers/into_iter.rs @@ -1,16 +1,16 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{FieldName, HeaderValues}; +use crate::headers::{FieldName, FieldValues}; /// An owning iterator over the entries of `Headers`. #[derive(Debug)] pub struct IntoIter { - pub(super) inner: hash_map::IntoIter, + pub(super) inner: hash_map::IntoIter, } impl Iterator for IntoIter { - type Item = (FieldName, HeaderValues); + type Item = (FieldName, FieldValues); fn next(&mut self) -> Option { self.inner.next() diff --git a/src/headers/iter.rs b/src/headers/iter.rs index 0869b6d7..cc5da6fe 100644 --- a/src/headers/iter.rs +++ b/src/headers/iter.rs @@ -1,16 +1,16 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{FieldName, HeaderValues}; +use crate::headers::{FieldName, FieldValues}; /// Iterator over the headers. #[derive(Debug)] pub struct Iter<'a> { - pub(super) inner: hash_map::Iter<'a, FieldName, HeaderValues>, + pub(super) inner: hash_map::Iter<'a, FieldName, FieldValues>, } impl<'a> Iterator for Iter<'a> { - type Item = (&'a FieldName, &'a HeaderValues); + type Item = (&'a FieldName, &'a FieldValues); fn next(&mut self) -> Option { self.inner.next() diff --git a/src/headers/iter_mut.rs b/src/headers/iter_mut.rs index ce052c7d..fd822faf 100644 --- a/src/headers/iter_mut.rs +++ b/src/headers/iter_mut.rs @@ -1,16 +1,16 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{FieldName, HeaderValues}; +use crate::headers::{FieldName, FieldValues}; /// Iterator over the headers. #[derive(Debug)] pub struct IterMut<'a> { - pub(super) inner: hash_map::IterMut<'a, FieldName, HeaderValues>, + pub(super) inner: hash_map::IterMut<'a, FieldName, FieldValues>, } impl<'a> Iterator for IterMut<'a> { - type Item = (&'a FieldName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut FieldValues); fn next(&mut self) -> Option { self.inner.next() diff --git a/src/headers/mod.rs b/src/headers/mod.rs index ba0a63e3..08c01b16 100644 --- a/src/headers/mod.rs +++ b/src/headers/mod.rs @@ -18,7 +18,7 @@ pub use constants::*; pub use header::Field; pub use header_name::FieldName; pub use header_value::FieldValue; -pub use header_values::HeaderValues; +pub use header_values::FieldValues; pub use headers::Headers; pub use into_iter::IntoIter; pub use iter::Iter; diff --git a/src/headers/names.rs b/src/headers/names.rs index e2eef090..d4753c0b 100644 --- a/src/headers/names.rs +++ b/src/headers/names.rs @@ -1,12 +1,12 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{FieldName, HeaderValues}; +use crate::headers::{FieldName, FieldValues}; /// Iterator over the headers. #[derive(Debug)] pub struct Names<'a> { - pub(super) inner: hash_map::Keys<'a, FieldName, HeaderValues>, + pub(super) inner: hash_map::Keys<'a, FieldName, FieldValues>, } impl<'a> Iterator for Names<'a> { diff --git a/src/headers/to_header_values.rs b/src/headers/to_header_values.rs index 7909beba..961a914d 100644 --- a/src/headers/to_header_values.rs +++ b/src/headers/to_header_values.rs @@ -4,7 +4,7 @@ use std::iter; use std::option; use std::slice; -use crate::headers::{Field, FieldValue, HeaderValues, Values}; +use crate::headers::{Field, FieldValue, FieldValues, Values}; /// A trait for objects which can be converted or resolved to one or more `HeaderValue`s. pub trait ToHeaderValues { @@ -31,7 +31,7 @@ impl ToHeaderValues for FieldValue { } } -impl<'a> ToHeaderValues for &'a HeaderValues { +impl<'a> ToHeaderValues for &'a FieldValues { type Iter = iter::Cloned>; fn to_header_values(&self) -> crate::Result { diff --git a/src/headers/values.rs b/src/headers/values.rs index 32bef2e0..12e28a83 100644 --- a/src/headers/values.rs +++ b/src/headers/values.rs @@ -1,19 +1,19 @@ use std::collections::hash_map; use std::iter::Iterator; -use crate::headers::{FieldName, FieldValue, HeaderValues}; +use crate::headers::{FieldName, FieldValue, FieldValues}; /// Iterator over the header values. #[derive(Debug)] pub struct Values<'a> { - pub(super) inner: Option>, - slot: Option<&'a HeaderValues>, + pub(super) inner: Option>, + slot: Option<&'a FieldValues>, cursor: usize, } impl<'a> Values<'a> { /// Constructor for `Headers`. - pub(crate) fn new(inner: hash_map::Values<'a, FieldName, HeaderValues>) -> Self { + pub(crate) fn new(inner: hash_map::Values<'a, FieldName, FieldValues>) -> Self { Self { inner: Some(inner), slot: None, @@ -22,7 +22,7 @@ impl<'a> Values<'a> { } /// Constructor for `HeaderValues`. - pub(crate) fn new_values(values: &'a HeaderValues) -> Self { + pub(crate) fn new_values(values: &'a FieldValues) -> Self { Self { inner: None, slot: Some(values), diff --git a/src/request.rs b/src/request.rs index ef462968..9c06ce9d 100644 --- a/src/request.rs +++ b/src/request.rs @@ -9,7 +9,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::{DeserializeOwned, Serialize}; use crate::headers::{ - self, FieldName, FieldValue, HeaderValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, + self, FieldName, FieldValue, FieldValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -407,17 +407,17 @@ impl Request { } /// Get an HTTP header. - pub fn header(&self, name: impl Into) -> Option<&HeaderValues> { + pub fn header(&self, name: impl Into) -> Option<&FieldValues> { self.headers.get(name) } /// Get a mutable reference to a header. - pub fn header_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { + pub fn header_mut(&mut self, name: impl Into) -> Option<&mut FieldValues> { self.headers.get_mut(name.into()) } /// Remove a header. - pub fn remove_header(&mut self, name: impl Into) -> Option { + pub fn remove_header(&mut self, name: impl Into) -> Option { self.headers.remove(name.into()) } @@ -439,7 +439,7 @@ impl Request { &mut self, name: impl Into, values: impl ToHeaderValues, - ) -> crate::Result> { + ) -> crate::Result> { self.headers.insert(name, values) } @@ -471,7 +471,7 @@ impl Request { /// Set the response MIME. // TODO: return a parsed MIME - pub fn set_content_type(&mut self, mime: Mime) -> Option { + pub fn set_content_type(&mut self, mime: Mime) -> Option { let value: FieldValue = mime.into(); // A Mime instance is guaranteed to be valid header name. @@ -945,7 +945,7 @@ impl From for Body { } impl Index for Request { - type Output = HeaderValues; + type Output = FieldValues; /// Returns a reference to the value corresponding to the supplied name. /// @@ -953,13 +953,13 @@ impl Index for Request { /// /// Panics if the name is not present in `Request`. #[inline] - fn index(&self, name: FieldName) -> &HeaderValues { + fn index(&self, name: FieldName) -> &FieldValues { self.headers.index(name) } } impl Index<&str> for Request { - type Output = HeaderValues; + type Output = FieldValues; /// Returns a reference to the value corresponding to the supplied name. /// @@ -967,13 +967,13 @@ impl Index<&str> for Request { /// /// Panics if the name is not present in `Request`. #[inline] - fn index(&self, name: &str) -> &HeaderValues { + fn index(&self, name: &str) -> &FieldValues { self.headers.index(name) } } impl IntoIterator for Request { - type Item = (FieldName, HeaderValues); + type Item = (FieldName, FieldValues); type IntoIter = headers::IntoIter; /// Returns a iterator of references over the remaining items. @@ -984,7 +984,7 @@ impl IntoIterator for Request { } impl<'a> IntoIterator for &'a Request { - type Item = (&'a FieldName, &'a HeaderValues); + type Item = (&'a FieldName, &'a FieldValues); type IntoIter = headers::Iter<'a>; #[inline] @@ -994,7 +994,7 @@ impl<'a> IntoIterator for &'a Request { } impl<'a> IntoIterator for &'a mut Request { - type Item = (&'a FieldName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut FieldValues); type IntoIter = headers::IterMut<'a>; #[inline] diff --git a/src/response.rs b/src/response.rs index 18c09017..b73670a7 100644 --- a/src/response.rs +++ b/src/response.rs @@ -10,7 +10,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::DeserializeOwned; use crate::headers::{ - self, FieldName, FieldValue, HeaderValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, + self, FieldName, FieldValue, FieldValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -86,17 +86,17 @@ impl Response { } /// Get a mutable reference to a header. - pub fn header_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { + pub fn header_mut(&mut self, name: impl Into) -> Option<&mut FieldValues> { self.headers.get_mut(name.into()) } /// Get an HTTP header. - pub fn header(&self, name: impl Into) -> Option<&HeaderValues> { + pub fn header(&self, name: impl Into) -> Option<&FieldValues> { self.headers.get(name.into()) } /// Remove a header. - pub fn remove_header(&mut self, name: impl Into) -> Option { + pub fn remove_header(&mut self, name: impl Into) -> Option { self.headers.remove(name.into()) } @@ -118,7 +118,7 @@ impl Response { &mut self, name: impl Into, values: impl ToHeaderValues, - ) -> crate::Result> { + ) -> crate::Result> { self.headers.insert(name, values) } @@ -376,7 +376,7 @@ impl Response { } /// Set the response MIME. - pub fn set_content_type(&mut self, mime: Mime) -> Option { + pub fn set_content_type(&mut self, mime: Mime) -> Option { let value: FieldValue = mime.into(); // A Mime instance is guaranteed to be valid header name. @@ -644,7 +644,7 @@ impl From<()> for Response { } } impl Index for Response { - type Output = HeaderValues; + type Output = FieldValues; /// Returns a reference to the value corresponding to the supplied name. /// @@ -652,13 +652,13 @@ impl Index for Response { /// /// Panics if the name is not present in `Response`. #[inline] - fn index(&self, name: FieldName) -> &HeaderValues { + fn index(&self, name: FieldName) -> &FieldValues { self.headers.index(name) } } impl Index<&str> for Response { - type Output = HeaderValues; + type Output = FieldValues; /// Returns a reference to the value corresponding to the supplied name. /// @@ -666,7 +666,7 @@ impl Index<&str> for Response { /// /// Panics if the name is not present in `Response`. #[inline] - fn index(&self, name: &str) -> &HeaderValues { + fn index(&self, name: &str) -> &FieldValues { self.headers.index(name) } } @@ -690,7 +690,7 @@ where } impl IntoIterator for Response { - type Item = (FieldName, HeaderValues); + type Item = (FieldName, FieldValues); type IntoIter = headers::IntoIter; /// Returns a iterator of references over the remaining items. @@ -701,7 +701,7 @@ impl IntoIterator for Response { } impl<'a> IntoIterator for &'a Response { - type Item = (&'a FieldName, &'a HeaderValues); + type Item = (&'a FieldName, &'a FieldValues); type IntoIter = headers::Iter<'a>; #[inline] @@ -711,7 +711,7 @@ impl<'a> IntoIterator for &'a Response { } impl<'a> IntoIterator for &'a mut Response { - type Item = (&'a FieldName, &'a mut HeaderValues); + type Item = (&'a FieldName, &'a mut FieldValues); type IntoIter = headers::IterMut<'a>; #[inline] diff --git a/src/trailers.rs b/src/trailers.rs index 2aae49de..db1fd383 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -49,7 +49,7 @@ //! - [HTTP/2 spec: HTTP Sequence](https://http2.github.io/http2-spec/#HttpSequence) use crate::headers::{ - FieldName, HeaderValues, Headers, Iter, IterMut, Names, ToHeaderValues, Values, + FieldName, FieldValues, Headers, Iter, IterMut, Names, ToHeaderValues, Values, }; use futures_lite::Stream; @@ -91,7 +91,7 @@ impl Trailers { &mut self, name: impl Into, values: impl ToHeaderValues, - ) -> crate::Result> { + ) -> crate::Result> { self.headers.insert(name, values) } @@ -121,17 +121,17 @@ impl Trailers { } /// Get a reference to a header. - pub fn get(&self, name: impl Into) -> Option<&HeaderValues> { + pub fn get(&self, name: impl Into) -> Option<&FieldValues> { self.headers.get(name) } /// Get a mutable reference to a header. - pub fn get_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> { + pub fn get_mut(&mut self, name: impl Into) -> Option<&mut FieldValues> { self.headers.get_mut(name) } /// Remove a header. - pub fn remove(&mut self, name: impl Into) -> Option { + pub fn remove(&mut self, name: impl Into) -> Option { self.headers.remove(name) } @@ -182,7 +182,7 @@ impl DerefMut for Trailers { } impl Index for Trailers { - type Output = HeaderValues; + type Output = FieldValues; /// Returns a reference to the value corresponding to the supplied name. /// @@ -190,13 +190,13 @@ impl Index for Trailers { /// /// Panics if the name is not present in `Trailers`. #[inline] - fn index(&self, name: FieldName) -> &HeaderValues { + fn index(&self, name: FieldName) -> &FieldValues { self.headers.index(name) } } impl Index<&str> for Trailers { - type Output = HeaderValues; + type Output = FieldValues; /// Returns a reference to the value corresponding to the supplied name. /// @@ -204,7 +204,7 @@ impl Index<&str> for Trailers { /// /// Panics if the name is not present in `Trailers`. #[inline] - fn index(&self, name: &str) -> &HeaderValues { + fn index(&self, name: &str) -> &FieldValues { self.headers.index(name) } } From 04953ce909e2e3b7a90f8d73195c3f2bc0f490bd Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 19 Jun 2022 02:30:33 +0200 Subject: [PATCH 5/9] use `const FIELD_NAME` --- src/auth/authorization.rs | 4 +--- src/auth/basic_auth.rs | 4 +--- src/cache/age.rs | 4 +--- src/cache/expires.rs | 4 +--- src/conditional/etag.rs | 4 +--- src/conditional/vary.rs | 4 +--- src/content/accept.rs | 4 +--- src/other/date.rs | 4 +--- src/other/expect.rs | 4 +--- src/other/referer.rs | 4 +--- src/proxies/forwarded.rs | 4 +--- src/server/allow.rs | 4 +--- src/trace/trace_context.rs | 4 +--- 13 files changed, 13 insertions(+), 39 deletions(-) diff --git a/src/auth/authorization.rs b/src/auth/authorization.rs index 930ae84c..6f9898b8 100644 --- a/src/auth/authorization.rs +++ b/src/auth/authorization.rs @@ -93,9 +93,7 @@ impl Authorization { } impl Field for Authorization { - fn field_name(&self) -> FieldName { - AUTHORIZATION - } + const FIELD_NAME: FieldName = AUTHORIZATION; fn field_value(&self) -> FieldValue { let output = format!("{} {}", self.scheme, self.credentials); diff --git a/src/auth/basic_auth.rs b/src/auth/basic_auth.rs index 68ff5713..0fcfc03c 100644 --- a/src/auth/basic_auth.rs +++ b/src/auth/basic_auth.rs @@ -99,9 +99,7 @@ impl BasicAuth { } impl Field for BasicAuth { - fn field_name(&self) -> FieldName { - AUTHORIZATION - } + const FIELD_NAME: FieldName = AUTHORIZATION; fn field_value(&self) -> FieldValue { let scheme = AuthenticationScheme::Basic; diff --git a/src/cache/age.rs b/src/cache/age.rs index b8499b5d..1f266be0 100644 --- a/src/cache/age.rs +++ b/src/cache/age.rs @@ -70,9 +70,7 @@ impl Age { } impl Field for Age { - fn field_name(&self) -> FieldName { - AGE - } + const FIELD_NAME: FieldName = AGE; fn field_value(&self) -> FieldValue { let output = self.dur.as_secs().to_string(); diff --git a/src/cache/expires.rs b/src/cache/expires.rs index cd3c55e5..ad717847 100644 --- a/src/cache/expires.rs +++ b/src/cache/expires.rs @@ -72,9 +72,7 @@ impl Expires { } impl Field for Expires { - fn field_name(&self) -> FieldName { - EXPIRES - } + const FIELD_NAME: FieldName = EXPIRES; fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); diff --git a/src/conditional/etag.rs b/src/conditional/etag.rs index 7ca75fc9..9910378e 100644 --- a/src/conditional/etag.rs +++ b/src/conditional/etag.rs @@ -113,9 +113,7 @@ impl ETag { } impl Field for ETag { - fn field_name(&self) -> FieldName { - ETAG - } + const FIELD_NAME: FieldName = ETAG; fn field_value(&self) -> FieldValue { let s = self.to_string(); // SAFETY: the internal string is validated to be ASCII. diff --git a/src/conditional/vary.rs b/src/conditional/vary.rs index 8a036250..70b76b82 100644 --- a/src/conditional/vary.rs +++ b/src/conditional/vary.rs @@ -106,9 +106,7 @@ impl Vary { } impl Field for Vary { - fn field_name(&self) -> FieldName { - VARY - } + const FIELD_NAME: FieldName = VARY; fn field_value(&self) -> FieldValue { let mut output = String::new(); diff --git a/src/content/accept.rs b/src/content/accept.rs index fe5bf07a..c628f74d 100644 --- a/src/content/accept.rs +++ b/src/content/accept.rs @@ -162,9 +162,7 @@ impl Accept { } impl Field for Accept { - fn field_name(&self) -> FieldName { - ACCEPT - } + const FIELD_NAME: FieldName = ACCEPT; fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, directive) in self.entries.iter().enumerate() { diff --git a/src/other/date.rs b/src/other/date.rs index c6ad73c7..5e2028a3 100644 --- a/src/other/date.rs +++ b/src/other/date.rs @@ -74,9 +74,7 @@ impl Date { } impl Field for Date { - fn field_name(&self) -> FieldName { - DATE - } + const FIELD_NAME: FieldName = DATE; fn field_value(&self) -> FieldValue { let date: HttpDate = self.at.into(); diff --git a/src/other/expect.rs b/src/other/expect.rs index ee1b0d62..0b122dc3 100644 --- a/src/other/expect.rs +++ b/src/other/expect.rs @@ -57,9 +57,7 @@ impl Expect { } impl Field for Expect { - fn field_name(&self) -> FieldName { - EXPECT - } + const FIELD_NAME: FieldName = EXPECT; fn field_value(&self) -> FieldValue { let value = "100-continue"; // SAFETY: the internal string is validated to be ASCII. diff --git a/src/other/referer.rs b/src/other/referer.rs index 0bfd60dc..f69846b8 100644 --- a/src/other/referer.rs +++ b/src/other/referer.rs @@ -87,9 +87,7 @@ impl Referer { } impl Field for Referer { - fn field_name(&self) -> FieldName { - REFERER - } + const FIELD_NAME: FieldName = REFERER; fn field_value(&self) -> FieldValue { let output = self.location.to_string(); diff --git a/src/proxies/forwarded.rs b/src/proxies/forwarded.rs index 81dae52a..38df64b6 100644 --- a/src/proxies/forwarded.rs +++ b/src/proxies/forwarded.rs @@ -359,9 +359,7 @@ impl<'a> Forwarded<'a> { } impl<'a> Field for Forwarded<'a> { - fn field_name(&self) -> FieldName { - FORWARDED - } + const FIELD_NAME: FieldName = FORWARDED; fn field_value(&self) -> FieldValue { let mut output = String::new(); if let Some(by) = self.by() { diff --git a/src/server/allow.rs b/src/server/allow.rs index 42a25096..8055a46b 100644 --- a/src/server/allow.rs +++ b/src/server/allow.rs @@ -85,9 +85,7 @@ impl Allow { } impl Field for Allow { - fn field_name(&self) -> FieldName { - ALLOW - } + const FIELD_NAME: FieldName = ALLOW; fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, method) in self.entries.iter().enumerate() { diff --git a/src/trace/trace_context.rs b/src/trace/trace_context.rs index 68c462a4..9c6176c8 100644 --- a/src/trace/trace_context.rs +++ b/src/trace/trace_context.rs @@ -196,9 +196,7 @@ impl TraceContext { } impl Field for TraceContext { - fn field_name(&self) -> FieldName { - TRACEPARENT - } + const FIELD_NAME: FieldName = TRACEPARENT; fn field_value(&self) -> FieldValue { let output = format!("{}", self); From fe27416dd6b11e59a7f82b7f77c14b5800fecb46 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 19 Jun 2022 03:01:00 +0200 Subject: [PATCH 6/9] undo some of the header access changes --- src/headers/header.rs | 24 --------- src/headers/headers.rs | 89 +++++++++++++++++++++++---------- src/headers/mod.rs | 2 +- src/headers/to_header_values.rs | 42 ++++++++-------- src/mime/mod.rs | 8 +-- src/request.rs | 6 +-- src/response.rs | 6 +-- src/trailers.rs | 6 +-- 8 files changed, 97 insertions(+), 86 deletions(-) diff --git a/src/headers/header.rs b/src/headers/header.rs index f6dcae07..b13f87d3 100644 --- a/src/headers/header.rs +++ b/src/headers/header.rs @@ -22,30 +22,6 @@ where fn from_field_pair(name: FieldName, value: FieldValue) -> Result; } -mod void { - use core::marker::PhantomData; - - enum Void {} - - impl Copy for Void {} - - impl Clone for Void { - fn clone(&self) -> Self { - match *self {} - } - } - - pub struct MustBeStr(PhantomData, Void); - - impl Copy for MustBeStr {} - - impl Clone for MustBeStr { - fn clone(&self) -> Self { - *self - } - } -} - #[cfg(test)] mod test { use super::*; diff --git a/src/headers/headers.rs b/src/headers/headers.rs index 39e889dc..95bc9e27 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -1,20 +1,23 @@ //! HTTP headers. use std::collections::HashMap; +use std::convert::Into; use std::fmt::{self, Debug}; use std::iter::IntoIterator; +use std::ops::Index; +use std::str::FromStr; use crate::headers::{ - Field, FieldName, FieldValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values, + Field, FieldName, FieldValues, IntoIter, Iter, IterMut, Names, ToFieldValues, Values, }; use super::FieldValue; -/// A collection of HTTP Headers. +/// A collection of HTTP Fields. /// -/// Headers are never manually constructed, but are part of `Request`, -/// `Response`, and `Trailers`. Each of these types implements `AsRef` -/// and `AsMut` so functions that want to modify headers can be generic +/// Fields are never manually constructed, but are part of `Request`, +/// `Response`, and `Trailers`. Each of these types implements `AsRef` +/// and `AsMut` so functions that want to modify headers can be generic /// over either of these traits. /// /// # Examples @@ -27,11 +30,11 @@ use super::FieldValue; /// assert_eq!(res["hello"], "foo0"); /// ``` #[derive(Clone)] -pub struct Headers { +pub struct Fields { pub(crate) headers: HashMap, } -impl Headers { +impl Fields { /// Create a new instance. pub(crate) fn new() -> Self { Self { @@ -42,20 +45,23 @@ impl Headers { /// Insert a header into the headers. /// /// Not that this will replace all header values for a given header name. - pub fn insert(&mut self, header: H) -> Option { - self.headers.insert(H::FIELD_NAME, header.field_value()) + pub fn insert(&mut self, name: FieldName, value: FieldValue) -> Option { + self.headers.insert(name, value) } /// Get a reference to a header. - pub fn get(&self) -> Option { - let value = self.headers.get(&F::FIELD_NAME)?; - F::from_field_pair(F::FIELD_NAME, value.clone()).ok() + pub fn get(&self, name: FieldName) -> Option<&FieldValue> { + self.headers.get(&name) + } + + /// Get a mutable reference to a header. + pub fn get_mut(&mut self, name: impl Into) -> Option<&mut FieldValue> { + self.headers.get_mut(&name.into()) } /// Remove a header. - pub fn remove(&mut self) -> Option { - let value = self.headers.remove(&F::FIELD_NAME)?; - F::from_field_pair(F::FIELD_NAME, value.clone()).ok() + pub fn remove(&mut self, name: impl Into) -> Option { + self.headers.remove(&name.into()) } /// An iterator visiting all header pairs in arbitrary order. @@ -86,7 +92,36 @@ impl Headers { } } -impl IntoIterator for Headers { +impl Index for Fields { + type Output = FieldValues; + + /// Returns a reference to the value corresponding to the supplied name. + /// + /// # Panics + /// + /// Panics if the name is not present in `Fields`. + #[inline] + fn index(&self, name: FieldName) -> &FieldValues { + self.get(name).expect("no entry found for name") + } +} + +impl Index<&str> for Fields { + type Output = FieldValues; + + /// Returns a reference to the value corresponding to the supplied name. + /// + /// # Panics + /// + /// Panics if the name is not present in `Fields`. + #[inline] + fn index(&self, name: &str) -> &FieldValues { + let name = FieldName::from_str(name).expect("string slice needs to be valid ASCII"); + self.get(name).expect("no entry found for name") + } +} + +impl IntoIterator for Fields { type Item = (FieldName, FieldValues); type IntoIter = IntoIter; @@ -99,7 +134,7 @@ impl IntoIterator for Headers { } } -impl<'a> IntoIterator for &'a Headers { +impl<'a> IntoIterator for &'a Fields { type Item = (&'a FieldName, &'a FieldValues); type IntoIter = Iter<'a>; @@ -109,7 +144,7 @@ impl<'a> IntoIterator for &'a Headers { } } -impl<'a> IntoIterator for &'a mut Headers { +impl<'a> IntoIterator for &'a mut Fields { type Item = (&'a FieldName, &'a mut FieldValues); type IntoIter = IterMut<'a>; @@ -119,20 +154,20 @@ impl<'a> IntoIterator for &'a mut Headers { } } -impl Debug for Headers { +impl Debug for Fields { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.headers.iter()).finish() } } -impl AsRef for Headers { - fn as_ref(&self) -> &Headers { +impl AsRef for Fields { + fn as_ref(&self) -> &Fields { self } } -impl AsMut for Headers { - fn as_mut(&mut self) -> &mut Headers { +impl AsMut for Fields { + fn as_mut(&mut self) -> &mut Fields { self } } @@ -149,7 +184,7 @@ mod tests { let static_header = FieldName::from_lowercase_str("hello"); let non_static_header = FieldName::from_str("hello")?; - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.append(STATIC_HEADER, "foo0").unwrap(); headers.append(static_header.clone(), "foo1").unwrap(); headers.append(non_static_header.clone(), "foo2").unwrap(); @@ -163,7 +198,7 @@ mod tests { #[test] fn index_into_headers() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert("hello", "foo0").unwrap(); assert_eq!(headers["hello"], "foo0"); assert_eq!(headers.get("hello").unwrap(), "foo0"); @@ -171,14 +206,14 @@ mod tests { #[test] fn test_debug_single() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert("single", "foo0").unwrap(); assert_eq!(format!("{:?}", headers), r#"{"single": "foo0"}"#); } #[test] fn test_debug_multiple() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.append("multi", "foo0").unwrap(); headers.append("multi", "foo1").unwrap(); assert_eq!(format!("{:?}", headers), r#"{"multi": ["foo0", "foo1"]}"#); diff --git a/src/headers/mod.rs b/src/headers/mod.rs index 08c01b16..610c4740 100644 --- a/src/headers/mod.rs +++ b/src/headers/mod.rs @@ -24,5 +24,5 @@ pub use into_iter::IntoIter; pub use iter::Iter; pub use iter_mut::IterMut; pub use names::Names; -pub use to_header_values::ToHeaderValues; +pub use to_header_values::ToFieldValues; pub use values::Values; diff --git a/src/headers/to_header_values.rs b/src/headers/to_header_values.rs index 961a914d..274f052f 100644 --- a/src/headers/to_header_values.rs +++ b/src/headers/to_header_values.rs @@ -7,50 +7,50 @@ use std::slice; use crate::headers::{Field, FieldValue, FieldValues, Values}; /// A trait for objects which can be converted or resolved to one or more `HeaderValue`s. -pub trait ToHeaderValues { +pub trait ToFieldValues { /// Returned iterator over header values which this type may correspond to. type Iter: Iterator; /// Converts this object to an iterator of resolved `HeaderValues`. - fn to_header_values(&self) -> crate::Result; + fn to_field_values(&self) -> crate::Result; } -impl ToHeaderValues for T { +impl ToFieldValues for T { type Iter = option::IntoIter; - fn to_header_values(&self) -> crate::Result { + fn to_field_values(&self) -> crate::Result { Ok(Some(self.field_value()).into_iter()) } } -impl ToHeaderValues for FieldValue { +impl ToFieldValues for FieldValue { type Iter = option::IntoIter; - fn to_header_values(&self) -> crate::Result { + fn to_field_values(&self) -> crate::Result { Ok(Some(self.clone()).into_iter()) } } -impl<'a> ToHeaderValues for &'a FieldValues { +impl<'a> ToFieldValues for &'a FieldValues { type Iter = iter::Cloned>; - fn to_header_values(&self) -> crate::Result { + fn to_field_values(&self) -> crate::Result { Ok(self.iter().cloned()) } } -impl<'a> ToHeaderValues for &'a [FieldValue] { +impl<'a> ToFieldValues for &'a [FieldValue] { type Iter = iter::Cloned>; - fn to_header_values(&self) -> crate::Result { + fn to_field_values(&self) -> crate::Result { Ok(self.iter().cloned()) } } -impl<'a> ToHeaderValues for &'a str { +impl<'a> ToFieldValues for &'a str { type Iter = option::IntoIter; - fn to_header_values(&self) -> crate::Result { + fn to_field_values(&self) -> crate::Result { let value = self .parse() .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; @@ -58,26 +58,26 @@ impl<'a> ToHeaderValues for &'a str { } } -impl ToHeaderValues for String { +impl ToFieldValues for String { type Iter = option::IntoIter; - fn to_header_values(&self) -> crate::Result { - self.as_str().to_header_values() + fn to_field_values(&self) -> crate::Result { + self.as_str().to_field_values() } } -impl ToHeaderValues for &String { +impl ToFieldValues for &String { type Iter = option::IntoIter; - fn to_header_values(&self) -> crate::Result { - self.as_str().to_header_values() + fn to_field_values(&self) -> crate::Result { + self.as_str().to_field_values() } } -impl ToHeaderValues for Cow<'_, str> { +impl ToFieldValues for Cow<'_, str> { type Iter = option::IntoIter; - fn to_header_values(&self) -> crate::Result { - self.as_ref().to_header_values() + fn to_field_values(&self) -> crate::Result { + self.as_ref().to_field_values() } } diff --git a/src/mime/mod.rs b/src/mime/mod.rs index 694b0415..d098f2bb 100644 --- a/src/mime/mod.rs +++ b/src/mime/mod.rs @@ -12,7 +12,7 @@ use std::fmt::{self, Debug, Display}; use std::option; use std::str::FromStr; -use crate::headers::{FieldValue, ToHeaderValues}; +use crate::headers::{FieldValue, ToFieldValues}; use infer::Infer; @@ -195,15 +195,15 @@ impl<'a> From<&'a str> for Mime { } } -impl ToHeaderValues for Mime { +impl ToFieldValues for Mime { type Iter = option::IntoIter; - fn to_header_values(&self) -> crate::Result { + fn to_field_values(&self) -> crate::Result { let mime = self.clone(); let header: FieldValue = mime.into(); // A HeaderValue will always convert into itself. - Ok(header.to_header_values().unwrap()) + Ok(header.to_field_values().unwrap()) } } diff --git a/src/request.rs b/src/request.rs index 9c06ce9d..b190d548 100644 --- a/src/request.rs +++ b/src/request.rs @@ -9,7 +9,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::{DeserializeOwned, Serialize}; use crate::headers::{ - self, FieldName, FieldValue, FieldValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, + self, FieldName, FieldValue, FieldValues, Headers, Names, ToFieldValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -438,7 +438,7 @@ impl Request { pub fn insert_header( &mut self, name: impl Into, - values: impl ToHeaderValues, + values: impl ToFieldValues, ) -> crate::Result> { self.headers.insert(name, values) } @@ -464,7 +464,7 @@ impl Request { pub fn append_header( &mut self, name: impl Into, - values: impl ToHeaderValues, + values: impl ToFieldValues, ) -> crate::Result<()> { self.headers.append(name, values) } diff --git a/src/response.rs b/src/response.rs index b73670a7..7118bc51 100644 --- a/src/response.rs +++ b/src/response.rs @@ -10,7 +10,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::DeserializeOwned; use crate::headers::{ - self, FieldName, FieldValue, FieldValues, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, + self, FieldName, FieldValue, FieldValues, Headers, Names, ToFieldValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -117,7 +117,7 @@ impl Response { pub fn insert_header( &mut self, name: impl Into, - values: impl ToHeaderValues, + values: impl ToFieldValues, ) -> crate::Result> { self.headers.insert(name, values) } @@ -143,7 +143,7 @@ impl Response { pub fn append_header( &mut self, name: impl Into, - values: impl ToHeaderValues, + values: impl ToFieldValues, ) -> crate::Result<()> { self.headers.append(name, values) } diff --git a/src/trailers.rs b/src/trailers.rs index db1fd383..ebfdc279 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -49,7 +49,7 @@ //! - [HTTP/2 spec: HTTP Sequence](https://http2.github.io/http2-spec/#HttpSequence) use crate::headers::{ - FieldName, FieldValues, Headers, Iter, IterMut, Names, ToHeaderValues, Values, + FieldName, FieldValues, Headers, Iter, IterMut, Names, ToFieldValues, Values, }; use futures_lite::Stream; @@ -90,7 +90,7 @@ impl Trailers { pub fn insert( &mut self, name: impl Into, - values: impl ToHeaderValues, + values: impl ToFieldValues, ) -> crate::Result> { self.headers.insert(name, values) } @@ -115,7 +115,7 @@ impl Trailers { pub fn append( &mut self, name: impl Into, - values: impl ToHeaderValues, + values: impl ToFieldValues, ) -> crate::Result<()> { self.headers.append(name, values) } From 7a1a51817927943f3d90278654ecda87e7ce85ad Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 19 Jun 2022 03:26:50 +0200 Subject: [PATCH 7/9] rename stuffs --- src/auth/authorization.rs | 10 +++++----- src/auth/basic_auth.rs | 10 +++++----- src/auth/www_authenticate.rs | 14 ++++++-------- src/cache/age.rs | 10 +++++----- src/cache/cache_control/cache_control.rs | 8 +++----- src/cache/cache_control/mod.rs | 8 ++++---- src/cache/clear_site_data/mod.rs | 8 +++----- src/cache/expires.rs | 10 +++++----- src/conditional/etag.rs | 14 +++++++------- src/conditional/if_match.rs | 8 +++----- src/conditional/if_modified_since.rs | 14 ++++++-------- src/conditional/if_none_match.rs | 8 +++----- src/conditional/if_unmodified_since.rs | 14 ++++++-------- src/conditional/last_modified.rs | 14 ++++++-------- src/conditional/vary.rs | 4 ++-- src/content/accept.rs | 4 ++-- src/content/accept_encoding.rs | 8 +++----- src/content/content_encoding.rs | 8 +++----- src/content/content_length.rs | 14 ++++++-------- src/content/content_location.rs | 14 ++++++-------- src/content/content_type.rs | 14 ++++++-------- src/headers/header.rs | 6 +++--- src/headers/headers.rs | 8 ++++---- src/headers/mod.rs | 2 +- src/hyperium_http.rs | 4 ++-- src/other/date.rs | 10 +++++----- src/other/expect.rs | 10 +++++----- src/other/referer.rs | 14 +++++++------- src/other/retry_after.rs | 14 ++++++-------- src/other/source_map.rs | 18 ++++++++---------- src/proxies/forwarded.rs | 8 ++++---- src/request.rs | 8 ++++---- src/response.rs | 8 ++++---- src/security/csp.rs | 4 ++-- src/security/mod.rs | 16 ++++++++-------- src/security/strict_transport_security.rs | 6 ++---- src/security/timing_allow_origin.rs | 18 ++++++++---------- src/server/allow.rs | 8 ++++---- src/trace/server_timing/mod.rs | 16 +++++++--------- src/trace/trace_context.rs | 10 +++++----- src/trailers.rs | 6 ++---- src/transfer/te.rs | 2 +- src/transfer/transfer_encoding.rs | 8 +++----- 43 files changed, 190 insertions(+), 230 deletions(-) diff --git a/src/auth/authorization.rs b/src/auth/authorization.rs index 6f9898b8..f45b0489 100644 --- a/src/auth/authorization.rs +++ b/src/auth/authorization.rs @@ -1,6 +1,6 @@ use crate::auth::AuthenticationScheme; use crate::bail_status as bail; -use crate::headers::{Field, FieldName, FieldValue, Headers, AUTHORIZATION}; +use crate::headers::{Field, FieldName, FieldValue, Fields, AUTHORIZATION}; /// Credentials to authenticate a user agent with a server. /// @@ -46,7 +46,7 @@ impl Authorization { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(AUTHORIZATION) { Some(headers) => headers, None => return Ok(None), @@ -106,7 +106,7 @@ impl Field for Authorization { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { @@ -114,7 +114,7 @@ mod test { let credentials = "0xdeadbeef202020"; let authz = Authorization::new(scheme, credentials.into()); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(authz); let authz = Authorization::from_headers(headers)?.unwrap(); @@ -126,7 +126,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(AUTHORIZATION, "") .unwrap(); diff --git a/src/auth/basic_auth.rs b/src/auth/basic_auth.rs index 0fcfc03c..3dbbea63 100644 --- a/src/auth/basic_auth.rs +++ b/src/auth/basic_auth.rs @@ -1,4 +1,4 @@ -use crate::headers::{FieldName, FieldValue, Headers, AUTHORIZATION}; +use crate::headers::{FieldName, FieldValue, Fields, AUTHORIZATION}; use crate::Status; use crate::{ auth::{AuthenticationScheme, Authorization}, @@ -53,7 +53,7 @@ impl BasicAuth { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let auth = match Authorization::from_headers(headers)? { Some(auth) => auth, None => return Ok(None), @@ -112,7 +112,7 @@ impl Field for BasicAuth { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { @@ -120,7 +120,7 @@ mod test { let password = "secret_fish!!"; let authz = BasicAuth::new(username, password); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(authz); let authz = BasicAuth::from_headers(headers)?.unwrap(); @@ -132,7 +132,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(AUTHORIZATION, "") .unwrap(); diff --git a/src/auth/www_authenticate.rs b/src/auth/www_authenticate.rs index 876a4643..443b18b7 100644 --- a/src/auth/www_authenticate.rs +++ b/src/auth/www_authenticate.rs @@ -1,5 +1,5 @@ use crate::bail_status as bail; -use crate::headers::{FieldName, FieldValue, Headers, WWW_AUTHENTICATE}; +use crate::headers::{FieldName, FieldValue, Fields, WWW_AUTHENTICATE}; use crate::{auth::AuthenticationScheme, headers::Field}; /// Define the authentication method that should be used to gain access to a @@ -49,7 +49,7 @@ impl WwwAuthenticate { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(WWW_AUTHENTICATE) { Some(headers) => headers, None => return Ok(None), @@ -115,9 +115,7 @@ impl WwwAuthenticate { } impl Field for WwwAuthenticate { - fn field_name(&self) -> FieldName { - WWW_AUTHENTICATE - } + const FIELD_NAME: FieldName = WWW_AUTHENTICATE; fn field_value(&self) -> FieldValue { let output = format!(r#"{} realm="{}", charset="UTF-8""#, self.scheme, self.realm); @@ -130,7 +128,7 @@ impl Field for WwwAuthenticate { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { @@ -138,7 +136,7 @@ mod test { let realm = "Access to the staging site"; let authz = WwwAuthenticate::new(scheme, realm.into()); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(authz); assert_eq!( @@ -155,7 +153,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(WWW_AUTHENTICATE, "") .unwrap(); diff --git a/src/cache/age.rs b/src/cache/age.rs index 1f266be0..e118c469 100644 --- a/src/cache/age.rs +++ b/src/cache/age.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, AGE}; +use crate::headers::{Field, FieldName, FieldValue, Fields, AGE}; use crate::Status; use std::fmt::Debug; @@ -52,7 +52,7 @@ impl Age { } /// Create an instance of `Age` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(AGE) { Some(headers) => headers, None => return Ok(None), @@ -83,13 +83,13 @@ impl Field for Age { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let age = Age::new(Duration::from_secs(12)); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(age); let age = Age::from_headers(headers)?.unwrap(); @@ -99,7 +99,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(AGE, "").unwrap(); let err = Age::from_headers(headers).unwrap_err(); assert_eq!(err.status(), 400); diff --git a/src/cache/cache_control/cache_control.rs b/src/cache/cache_control/cache_control.rs index c9d89ce2..52491a14 100644 --- a/src/cache/cache_control/cache_control.rs +++ b/src/cache/cache_control/cache_control.rs @@ -1,6 +1,6 @@ use headers::Field; -use crate::headers::{FieldName, FieldValue, Headers, CACHE_CONTROL}; +use crate::headers::{FieldName, FieldValue, Fields, CACHE_CONTROL}; use crate::{cache::CacheDirective, headers}; use std::fmt::{self, Debug, Write}; @@ -42,7 +42,7 @@ impl CacheControl { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let headers = match headers.as_ref().get(CACHE_CONTROL) { Some(headers) => headers, @@ -82,9 +82,7 @@ impl CacheControl { } impl Field for CacheControl { - fn field_name(&self) -> FieldName { - CACHE_CONTROL - } + const FIELD_NAME: FieldName = CACHE_CONTROL; fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, directive) in self.entries.iter().enumerate() { diff --git a/src/cache/cache_control/mod.rs b/src/cache/cache_control/mod.rs index 3958c490..eb0ded36 100644 --- a/src/cache/cache_control/mod.rs +++ b/src/cache/cache_control/mod.rs @@ -16,7 +16,7 @@ pub use cache_directive::CacheDirective; #[cfg(test)] mod test { use super::*; - use crate::headers::{Field, Headers, CACHE_CONTROL}; + use crate::headers::{Field, Fields, CACHE_CONTROL}; #[test] fn smoke() -> crate::Result<()> { @@ -24,7 +24,7 @@ mod test { entries.push(CacheDirective::Immutable); entries.push(CacheDirective::NoStore); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(entries); let entries = CacheControl::from_headers(headers)?.unwrap(); @@ -36,7 +36,7 @@ mod test { #[test] fn ignore_unkonwn_directives() -> crate::Result<()> { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(CACHE_CONTROL, "barrel_roll").unwrap(); let entries = CacheControl::from_headers(headers)?.unwrap(); let mut entries = entries.iter(); @@ -46,7 +46,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(CACHE_CONTROL, "min-fresh=0.9").unwrap(); // floats are not supported let err = CacheControl::from_headers(headers).unwrap_err(); assert_eq!(err.status(), 400); diff --git a/src/cache/clear_site_data/mod.rs b/src/cache/clear_site_data/mod.rs index e56dc867..066fda31 100644 --- a/src/cache/clear_site_data/mod.rs +++ b/src/cache/clear_site_data/mod.rs @@ -1,7 +1,7 @@ //! Clear browsing data (cookies, storage, cache) associated with the //! requesting website -use crate::headers::{self, FieldName, FieldValue, Headers, CLEAR_SITE_DATA}; +use crate::headers::{self, FieldName, FieldValue, Fields, CLEAR_SITE_DATA}; use std::fmt::{self, Debug, Write}; use std::iter::Iterator; @@ -60,7 +60,7 @@ impl ClearSiteData { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let header_values = match headers.as_ref().get(CLEAR_SITE_DATA) { Some(headers) => headers, @@ -212,9 +212,7 @@ impl Debug for ClearSiteData { } impl Field for ClearSiteData { - fn field_name(&self) -> FieldName { - CLEAR_SITE_DATA - } + const FIELD_NAME: FieldName = CLEAR_SITE_DATA; fn field_value(&self) -> FieldValue { let mut output = String::new(); diff --git a/src/cache/expires.rs b/src/cache/expires.rs index ad717847..d8ca3575 100644 --- a/src/cache/expires.rs +++ b/src/cache/expires.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, EXPIRES}; +use crate::headers::{Field, FieldName, FieldValue, Fields, EXPIRES}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -56,7 +56,7 @@ impl Expires { } /// Create an instance of `Expires` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(EXPIRES) { Some(headers) => headers, None => return Ok(None), @@ -84,14 +84,14 @@ impl Field for Expires { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let time = SystemTime::now() + Duration::from_secs(5 * 60); let expires = Expires::new_at(time); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(expires); let expires = Expires::from_headers(headers)?.unwrap(); @@ -104,7 +104,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(EXPIRES, "").unwrap(); let err = Expires::from_headers(headers).unwrap_err(); assert_eq!(err.status(), 400); diff --git a/src/conditional/etag.rs b/src/conditional/etag.rs index 9910378e..3152299d 100644 --- a/src/conditional/etag.rs +++ b/src/conditional/etag.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, ETAG}; +use crate::headers::{Field, FieldName, FieldValue, Fields, ETAG}; use crate::{Error, StatusCode}; use std::fmt::{self, Debug, Display}; @@ -55,7 +55,7 @@ impl ETag { /// /// Only a single ETag per resource is assumed to exist. If multiple ETag /// headers are found the last one is used. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(ETAG) { Some(headers) => headers, None => return Ok(None), @@ -133,13 +133,13 @@ impl Display for ETag { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let etag = ETag::new("0xcafebeef".to_string()); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(etag); let etag = ETag::from_headers(headers)?.unwrap(); @@ -151,7 +151,7 @@ mod test { fn smoke_weak() -> crate::Result<()> { let etag = ETag::new_weak("0xcafebeef".to_string()); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(etag); let etag = ETag::from_headers(headers)?.unwrap(); @@ -161,7 +161,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(ETAG, "").unwrap(); let err = ETag::from_headers(headers).unwrap_err(); assert_eq!(err.status(), 400); @@ -176,7 +176,7 @@ mod test { } fn assert_entry_err(s: &str, msg: &str) { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(ETAG, s).unwrap(); let err = ETag::from_headers(headers).unwrap_err(); assert_eq!(format!("{}", err), msg); diff --git a/src/conditional/if_match.rs b/src/conditional/if_match.rs index 0d7a6c98..202873af 100644 --- a/src/conditional/if_match.rs +++ b/src/conditional/if_match.rs @@ -1,6 +1,6 @@ //! Apply the HTTP method if the ETag matches. -use crate::headers::{FieldName, FieldValue, Headers, IF_MATCH}; +use crate::headers::{FieldName, FieldValue, Fields, IF_MATCH}; use crate::{conditional::ETag, headers::Field}; use std::fmt::{self, Debug, Write}; @@ -51,7 +51,7 @@ impl IfMatch { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let headers = match headers.as_ref().get(IF_MATCH) { Some(headers) => headers, @@ -104,9 +104,7 @@ impl IfMatch { } impl Field for IfMatch { - fn field_name(&self) -> FieldName { - IF_MATCH - } + const FIELD_NAME: FieldName = IF_MATCH; fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { diff --git a/src/conditional/if_modified_since.rs b/src/conditional/if_modified_since.rs index fedc2c86..ff2da68f 100644 --- a/src/conditional/if_modified_since.rs +++ b/src/conditional/if_modified_since.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, IF_MODIFIED_SINCE}; +use crate::headers::{Field, FieldName, FieldValue, Fields, IF_MODIFIED_SINCE}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -52,7 +52,7 @@ impl IfModifiedSince { } /// Create an instance of `IfModifiedSince` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(IF_MODIFIED_SINCE) { Some(headers) => headers, None => return Ok(None), @@ -68,9 +68,7 @@ impl IfModifiedSince { } impl Field for IfModifiedSince { - fn field_name(&self) -> FieldName { - IF_MODIFIED_SINCE - } + const FIELD_NAME: FieldName = IF_MODIFIED_SINCE; fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); @@ -82,7 +80,7 @@ impl Field for IfModifiedSince { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; use std::time::Duration; #[test] @@ -90,7 +88,7 @@ mod test { let time = SystemTime::now() + Duration::from_secs(5 * 60); let expires = IfModifiedSince::new(time); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(expires); let expires = IfModifiedSince::from_headers(headers)?.unwrap(); @@ -103,7 +101,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(IF_MODIFIED_SINCE, "") .unwrap(); diff --git a/src/conditional/if_none_match.rs b/src/conditional/if_none_match.rs index d5a53d6c..0ea6cbd4 100644 --- a/src/conditional/if_none_match.rs +++ b/src/conditional/if_none_match.rs @@ -3,7 +3,7 @@ //! This is used to update caches or to prevent uploading a new resource when //! one already exists. -use crate::headers::{FieldName, FieldValue, Headers, IF_NONE_MATCH}; +use crate::headers::{FieldName, FieldValue, Fields, IF_NONE_MATCH}; use crate::{conditional::ETag, headers::Field}; use std::fmt::{self, Debug, Write}; @@ -57,7 +57,7 @@ impl IfNoneMatch { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let headers = match headers.as_ref().get(IF_NONE_MATCH) { Some(headers) => headers, @@ -110,9 +110,7 @@ impl IfNoneMatch { } impl Field for IfNoneMatch { - fn field_name(&self) -> FieldName { - IF_NONE_MATCH - } + const FIELD_NAME: FieldName = IF_NONE_MATCH; fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { diff --git a/src/conditional/if_unmodified_since.rs b/src/conditional/if_unmodified_since.rs index c8d21687..66075a00 100644 --- a/src/conditional/if_unmodified_since.rs +++ b/src/conditional/if_unmodified_since.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, IF_UNMODIFIED_SINCE}; +use crate::headers::{Field, FieldName, FieldValue, Fields, IF_UNMODIFIED_SINCE}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -52,7 +52,7 @@ impl IfUnmodifiedSince { } /// Create an instance of `IfUnmodifiedSince` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(IF_UNMODIFIED_SINCE) { Some(headers) => headers, None => return Ok(None), @@ -68,9 +68,7 @@ impl IfUnmodifiedSince { } impl Field for IfUnmodifiedSince { - fn field_name(&self) -> FieldName { - IF_UNMODIFIED_SINCE - } + const FIELD_NAME: FieldName = IF_UNMODIFIED_SINCE; fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); @@ -82,7 +80,7 @@ impl Field for IfUnmodifiedSince { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; use std::time::Duration; #[test] @@ -90,7 +88,7 @@ mod test { let time = SystemTime::now() + Duration::from_secs(5 * 60); let expires = IfUnmodifiedSince::new(time); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(expires); let expires = IfUnmodifiedSince::from_headers(headers)?.unwrap(); @@ -103,7 +101,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(IF_UNMODIFIED_SINCE, "") .unwrap(); diff --git a/src/conditional/last_modified.rs b/src/conditional/last_modified.rs index c3abf1c7..3bc1a8b1 100644 --- a/src/conditional/last_modified.rs +++ b/src/conditional/last_modified.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, LAST_MODIFIED}; +use crate::headers::{Field, FieldName, FieldValue, Fields, LAST_MODIFIED}; use crate::utils::{fmt_http_date, parse_http_date}; use std::fmt::Debug; @@ -51,7 +51,7 @@ impl LastModified { } /// Create an instance of `LastModified` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(LAST_MODIFIED) { Some(headers) => headers, None => return Ok(None), @@ -67,9 +67,7 @@ impl LastModified { } impl Field for LastModified { - fn field_name(&self) -> FieldName { - LAST_MODIFIED - } + const FIELD_NAME: FieldName = LAST_MODIFIED; fn field_value(&self) -> FieldValue { let output = fmt_http_date(self.instant); @@ -81,7 +79,7 @@ impl Field for LastModified { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; use std::time::Duration; #[test] @@ -89,7 +87,7 @@ mod test { let time = SystemTime::now() + Duration::from_secs(5 * 60); let last_modified = LastModified::new(time); - let mut headers = Headers::new(); + let mut headers = Fields::new(); last_headers.insert(modified); let last_modified = LastModified::from_headers(headers)?.unwrap(); @@ -102,7 +100,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(LAST_MODIFIED, "") .unwrap(); diff --git a/src/conditional/vary.rs b/src/conditional/vary.rs index 70b76b82..083628ec 100644 --- a/src/conditional/vary.rs +++ b/src/conditional/vary.rs @@ -1,6 +1,6 @@ //! Apply the HTTP method if the ETag matches. -use crate::headers::{Field, FieldName, FieldValue, Headers, VARY}; +use crate::headers::{Field, FieldName, FieldValue, Fields, VARY}; use std::fmt::{self, Debug, Write}; use std::iter::Iterator; @@ -51,7 +51,7 @@ impl Vary { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let headers = match headers.as_ref().get(VARY) { Some(headers) => headers, diff --git a/src/content/accept.rs b/src/content/accept.rs index c628f74d..d617dff1 100644 --- a/src/content/accept.rs +++ b/src/content/accept.rs @@ -1,6 +1,6 @@ //! Client header advertising which media types the client is able to understand. -use crate::headers::{FieldName, FieldValue, Headers, ACCEPT}; +use crate::headers::{FieldName, FieldValue, Fields, ACCEPT}; use crate::mime::Mime; use crate::utils::sort_by_weight; use crate::{ @@ -63,7 +63,7 @@ impl Accept { } /// Create an instance of `Accept` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let headers = match headers.as_ref().get(ACCEPT) { Some(headers) => headers, diff --git a/src/content/accept_encoding.rs b/src/content/accept_encoding.rs index 4961671a..79d07251 100644 --- a/src/content/accept_encoding.rs +++ b/src/content/accept_encoding.rs @@ -1,6 +1,6 @@ //! Client header advertising available compression algorithms. -use crate::headers::{FieldName, FieldValue, Headers, ACCEPT_ENCODING}; +use crate::headers::{FieldName, FieldValue, Fields, ACCEPT_ENCODING}; use crate::utils::sort_by_weight; use crate::{ content::{ContentEncoding, Encoding, EncodingProposal}, @@ -54,7 +54,7 @@ impl AcceptEncoding { } /// Create an instance of `AcceptEncoding` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let headers = match headers.as_ref().get(ACCEPT_ENCODING) { Some(headers) => headers, @@ -154,9 +154,7 @@ impl AcceptEncoding { } impl Field for AcceptEncoding { - fn field_name(&self) -> FieldName { - ACCEPT_ENCODING - } + const FIELD_NAME: FieldName = ACCEPT_ENCODING; fn field_value(&self) -> FieldValue { let mut output = String::new(); diff --git a/src/content/content_encoding.rs b/src/content/content_encoding.rs index c2706b3e..2da82b95 100644 --- a/src/content/content_encoding.rs +++ b/src/content/content_encoding.rs @@ -1,6 +1,6 @@ //! Specify the compression algorithm. -use crate::headers::{FieldName, FieldValue, Headers, CONTENT_ENCODING}; +use crate::headers::{FieldName, FieldValue, Fields, CONTENT_ENCODING}; use crate::{ content::{Encoding, EncodingProposal}, headers::Field, @@ -43,7 +43,7 @@ impl ContentEncoding { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(CONTENT_ENCODING) { Some(headers) => headers, None => return Ok(None), @@ -68,9 +68,7 @@ impl ContentEncoding { } impl Field for ContentEncoding { - fn field_name(&self) -> FieldName { - CONTENT_ENCODING - } + const FIELD_NAME: FieldName = CONTENT_ENCODING; fn field_value(&self) -> FieldValue { self.inner.into() } diff --git a/src/content/content_length.rs b/src/content/content_length.rs index c27a364d..393a9e8e 100644 --- a/src/content/content_length.rs +++ b/src/content/content_length.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, CONTENT_LENGTH}; +use crate::headers::{Field, FieldName, FieldValue, Fields, CONTENT_LENGTH}; use crate::Status; /// The size of the entity-body, in bytes, sent to the recipient. @@ -38,7 +38,7 @@ impl ContentLength { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(CONTENT_LENGTH) { Some(headers) => headers, None => return Ok(None), @@ -63,9 +63,7 @@ impl ContentLength { } impl Field for ContentLength { - fn field_name(&self) -> FieldName { - CONTENT_LENGTH - } + const FIELD_NAME: FieldName = CONTENT_LENGTH; fn field_value(&self) -> FieldValue { let output = format!("{}", self.length); @@ -77,13 +75,13 @@ impl Field for ContentLength { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let content_len = ContentLength::new(12); - let mut headers = Headers::new(); + let mut headers = Fields::new(); content_headers.insert(len); let content_len = ContentLength::from_headers(headers)?.unwrap(); @@ -93,7 +91,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(CONTENT_LENGTH, "") .unwrap(); diff --git a/src/content/content_location.rs b/src/content/content_location.rs index ac834bad..085ce111 100644 --- a/src/content/content_location.rs +++ b/src/content/content_location.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, CONTENT_LOCATION}; +use crate::headers::{Field, FieldName, FieldValue, Fields, CONTENT_LOCATION}; use crate::{bail_status as bail, Status, Url}; use std::convert::TryInto; @@ -42,7 +42,7 @@ impl ContentLocation { } /// Create a new instance from headers. - pub fn from_headers(base_url: U, headers: impl AsRef) -> crate::Result> + pub fn from_headers(base_url: U, headers: impl AsRef) -> crate::Result> where U: TryInto, U::Error: std::fmt::Debug, @@ -82,9 +82,7 @@ impl ContentLocation { } impl Field for ContentLocation { - fn field_name(&self) -> FieldName { - CONTENT_LOCATION - } + const FIELD_NAME: FieldName = CONTENT_LOCATION; fn field_value(&self) -> FieldValue { let output = self.url.to_string(); @@ -96,13 +94,13 @@ impl Field for ContentLocation { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let content_location = ContentLocation::new(Url::parse("https://example.net/test.json")?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); content_headers.insert(location); let content_location = @@ -117,7 +115,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(CONTENT_LOCATION, "htt://") .unwrap(); diff --git a/src/content/content_type.rs b/src/content/content_type.rs index b44b27b4..0245c774 100644 --- a/src/content/content_type.rs +++ b/src/content/content_type.rs @@ -1,6 +1,6 @@ use std::{convert::TryInto, str::FromStr}; -use crate::headers::{Field, FieldName, FieldValue, Headers, CONTENT_TYPE}; +use crate::headers::{Field, FieldName, FieldValue, Fields, CONTENT_TYPE}; use crate::mime::Mime; /// Indicate the media type of a resource's content. @@ -57,7 +57,7 @@ impl ContentType { /// order to always return fully qualified URLs, a base URL must be passed to /// reference the current environment. In HTTP/1.1 and above this value can /// always be determined from the request. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(CONTENT_TYPE) { Some(headers) => headers, None => return Ok(None), @@ -76,9 +76,7 @@ impl ContentType { } impl Field for ContentType { - fn field_name(&self) -> FieldName { - CONTENT_TYPE - } + const FIELD_NAME: FieldName = CONTENT_TYPE; fn field_value(&self) -> FieldValue { let output = format!("{}", self.media_type); // SAFETY: the internal string is validated to be ASCII. @@ -107,13 +105,13 @@ impl From for ContentType { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let ct = ContentType::new(Mime::from_str("text/*")?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(ct); let ct = ContentType::from_headers(headers)?.unwrap(); @@ -126,7 +124,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(CONTENT_TYPE, "") .unwrap(); diff --git a/src/headers/header.rs b/src/headers/header.rs index b13f87d3..65ee9626 100644 --- a/src/headers/header.rs +++ b/src/headers/header.rs @@ -17,9 +17,9 @@ where /// Access the header's value. fn field_value(&self) -> FieldValue; - /// Create a field from its parts. - // TODO: move this to a separate trait. - fn from_field_pair(name: FieldName, value: FieldValue) -> Result; + // /// Create a field from its parts. + // // TODO: move this to a separate trait. + // fn from_field_pair(name: FieldName, value: FieldValue) -> Result; } #[cfg(test)] diff --git a/src/headers/headers.rs b/src/headers/headers.rs index 95bc9e27..80e3cbc8 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -31,7 +31,7 @@ use super::FieldValue; /// ``` #[derive(Clone)] pub struct Fields { - pub(crate) headers: HashMap, + pub(crate) headers: HashMap, } impl Fields { @@ -50,17 +50,17 @@ impl Fields { } /// Get a reference to a header. - pub fn get(&self, name: FieldName) -> Option<&FieldValue> { + pub fn get(&self, name: FieldName) -> Option<&FieldValues> { self.headers.get(&name) } /// Get a mutable reference to a header. - pub fn get_mut(&mut self, name: impl Into) -> Option<&mut FieldValue> { + pub fn get_mut(&mut self, name: impl Into) -> Option<&mut FieldValues> { self.headers.get_mut(&name.into()) } /// Remove a header. - pub fn remove(&mut self, name: impl Into) -> Option { + pub fn remove(&mut self, name: impl Into) -> Option { self.headers.remove(&name.into()) } diff --git a/src/headers/mod.rs b/src/headers/mod.rs index 610c4740..b1979d5f 100644 --- a/src/headers/mod.rs +++ b/src/headers/mod.rs @@ -19,7 +19,7 @@ pub use header::Field; pub use header_name::FieldName; pub use header_value::FieldValue; pub use header_values::FieldValues; -pub use headers::Headers; +pub use headers::Fields; pub use into_iter::IntoIter; pub use iter::Iter; pub use iter_mut::IterMut; diff --git a/src/hyperium_http.rs b/src/hyperium_http.rs index 81d33425..f0d01ffc 100644 --- a/src/hyperium_http.rs +++ b/src/hyperium_http.rs @@ -112,7 +112,7 @@ impl TryFrom for Headers { } } -impl TryFrom for http::HeaderMap { +impl TryFrom for http::HeaderMap { type Error = Error; fn try_from(headers: Headers) -> Result { @@ -156,7 +156,7 @@ fn hyperium_headers_to_headers( Ok(()) } -fn headers_to_hyperium_headers(headers: &mut Headers, hyperium_headers: &mut http::HeaderMap) { +fn headers_to_hyperium_headers(headers: &mut Fields, hyperium_headers: &mut http::HeaderMap) { for (name, values) in headers { let name = format!("{}", name).into_bytes(); let name = http::header::HeaderName::from_bytes(&name).unwrap(); diff --git a/src/other/date.rs b/src/other/date.rs index 5e2028a3..85fc0783 100644 --- a/src/other/date.rs +++ b/src/other/date.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, DATE}; +use crate::headers::{Field, FieldName, FieldValue, Fields, DATE}; use crate::utils::HttpDate; use std::time::SystemTime; @@ -51,7 +51,7 @@ impl Date { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(DATE) { Some(headers) => headers, None => return Ok(None), @@ -106,7 +106,7 @@ impl PartialEq for Date { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; use std::time::Duration; #[test] @@ -114,7 +114,7 @@ mod test { let now = SystemTime::now(); let date = Date::new(now); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(date); let date = Date::from_headers(headers)?.unwrap(); @@ -126,7 +126,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(DATE, "").unwrap(); let err = Date::from_headers(headers).unwrap_err(); assert_eq!(err.status(), 400); diff --git a/src/other/expect.rs b/src/other/expect.rs index 0b122dc3..0d9084a3 100644 --- a/src/other/expect.rs +++ b/src/other/expect.rs @@ -1,4 +1,4 @@ -use crate::headers::{FieldName, FieldValue, Headers, EXPECT}; +use crate::headers::{FieldName, FieldValue, Fields, EXPECT}; use crate::{ensure_eq_status, headers::Field}; use std::fmt::Debug; @@ -41,7 +41,7 @@ impl Expect { } /// Create an instance of `Expect` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(EXPECT) { Some(headers) => headers, None => return Ok(None), @@ -68,13 +68,13 @@ impl Field for Expect { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let expect = Expect::new(); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(expect); let expect = Expect::from_headers(headers)?.unwrap(); @@ -84,7 +84,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(EXPECT, "").unwrap(); let err = Expect::from_headers(headers).unwrap_err(); assert_eq!(err.status(), 400); diff --git a/src/other/referer.rs b/src/other/referer.rs index f69846b8..059a4038 100644 --- a/src/other/referer.rs +++ b/src/other/referer.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, REFERER}; +use crate::headers::{Field, FieldName, FieldValue, Fields, REFERER}; use crate::{bail_status as bail, Status, Url}; use std::convert::TryInto; @@ -45,7 +45,7 @@ impl Referer { } /// Create a new instance from headers. - pub fn from_headers(base_url: U, headers: impl AsRef) -> crate::Result> + pub fn from_headers(base_url: U, headers: impl AsRef) -> crate::Result> where U: TryInto, U::Error: std::fmt::Debug, @@ -100,13 +100,13 @@ impl Field for Referer { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let referer = Referer::new(Url::parse("https://example.net/test.json")?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(referer); let base_url = Url::parse("https://example.net/")?; @@ -120,7 +120,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(REFERER, "htt://") .unwrap(); @@ -131,7 +131,7 @@ mod test { #[test] fn fallback_works() -> crate::Result<()> { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(REFERER, "/test.json").unwrap(); let base_url = Url::parse("https://fallback.net/")?; @@ -141,7 +141,7 @@ mod test { &Url::parse("https://fallback.net/test.json")? ); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(REFERER, "https://example.com/test.json") .unwrap(); diff --git a/src/other/retry_after.rs b/src/other/retry_after.rs index 27b43459..ac2b26bf 100644 --- a/src/other/retry_after.rs +++ b/src/other/retry_after.rs @@ -1,6 +1,6 @@ use std::time::{Duration, SystemTime, SystemTimeError}; -use crate::headers::{Field, FieldName, FieldValue, Headers, RETRY_AFTER}; +use crate::headers::{Field, FieldName, FieldValue, Fields, RETRY_AFTER}; use crate::utils::{fmt_http_date, parse_http_date}; /// Indicate how long the user agent should wait before making a follow-up request. @@ -58,7 +58,7 @@ impl RetryAfter { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let header = match headers.as_ref().get(RETRY_AFTER) { Some(headers) => headers.last(), None => return Ok(None), @@ -90,9 +90,7 @@ impl RetryAfter { } impl Field for RetryAfter { - fn field_name(&self) -> FieldName { - RETRY_AFTER - } + const FIELD_NAME: FieldName = RETRY_AFTER; fn field_value(&self) -> FieldValue { let output = match self.inner { @@ -126,13 +124,13 @@ enum RetryDirective { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let retry = RetryAfter::new(Duration::from_secs(10)); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(retry); // `SystemTime::now` uses sub-second precision which means there's some @@ -151,7 +149,7 @@ mod test { let now = SystemTime::now(); let retry = RetryAfter::new_at(now + Duration::from_secs(10)); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(retry); // `SystemTime::now` uses sub-second precision which means there's some diff --git a/src/other/source_map.rs b/src/other/source_map.rs index 749c578f..b16149b0 100644 --- a/src/other/source_map.rs +++ b/src/other/source_map.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, SOURCE_MAP}; +use crate::headers::{Field, FieldName, FieldValue, Fields, SOURCE_MAP}; use crate::{bail_status as bail, Status, Url}; use std::convert::TryInto; @@ -42,7 +42,7 @@ impl SourceMap { } /// Create a new instance from headers. - pub fn from_headers(base_url: U, headers: impl AsRef) -> crate::Result> + pub fn from_headers(base_url: U, headers: impl AsRef) -> crate::Result> where U: TryInto, U::Error: std::fmt::Debug, @@ -84,9 +84,7 @@ impl SourceMap { } impl Field for SourceMap { - fn field_name(&self) -> FieldName { - SOURCE_MAP - } + const FIELD_NAME: FieldName = SOURCE_MAP; fn field_value(&self) -> FieldValue { let output = self.location.to_string(); @@ -99,13 +97,13 @@ impl Field for SourceMap { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let source_map = SourceMap::new(Url::parse("https://example.net/test.json")?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); source_headers.insert(map); let base_url = Url::parse("https://example.net/")?; @@ -119,7 +117,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(SOURCE_MAP, "htt://") .unwrap(); @@ -130,7 +128,7 @@ mod test { #[test] fn fallback_works() -> crate::Result<()> { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(SOURCE_MAP, "/test.json").unwrap(); let base_url = Url::parse("https://fallback.net/")?; @@ -140,7 +138,7 @@ mod test { &Url::parse("https://fallback.net/test.json")? ); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(SOURCE_MAP, "https://example.com/test.json") .unwrap(); diff --git a/src/proxies/forwarded.rs b/src/proxies/forwarded.rs index 38df64b6..301c1351 100644 --- a/src/proxies/forwarded.rs +++ b/src/proxies/forwarded.rs @@ -1,5 +1,5 @@ use crate::{ - headers::{Field, FieldName, FieldValue, Headers, FORWARDED}, + headers::{Field, FieldName, FieldValue, Fields, FORWARDED}, parse_utils::{parse_quoted_string, parse_token}, }; use std::{borrow::Cow, convert::TryFrom, fmt::Write, net::IpAddr}; @@ -76,7 +76,7 @@ impl<'a> Forwarded<'a> { /// # Ok(()) } /// ``` - pub fn from_headers(headers: &'a impl AsRef) -> Result, ParseError> { + pub fn from_headers(headers: &'a impl AsRef) -> Result, ParseError> { if let Some(forwarded) = Self::from_forwarded_header(headers)? { Ok(Some(forwarded)) } else { @@ -109,7 +109,7 @@ impl<'a> Forwarded<'a> { /// # Ok(()) } /// ``` pub fn from_forwarded_header( - headers: &'a impl AsRef, + headers: &'a impl AsRef, ) -> Result, ParseError> { if let Some(headers) = headers.as_ref().get(FORWARDED) { Ok(Some(Self::parse(headers.as_ref().as_str())?)) @@ -143,7 +143,7 @@ impl<'a> Forwarded<'a> { /// assert!(Forwarded::from_x_headers(&request)?.is_none()); /// # Ok(()) } /// ``` - pub fn from_x_headers(headers: &'a impl AsRef) -> Result, ParseError> { + pub fn from_x_headers(headers: &'a impl AsRef) -> Result, ParseError> { let headers = headers.as_ref(); let forwarded_for: Vec> = headers diff --git a/src/request.rs b/src/request.rs index b190d548..fc61f0af 100644 --- a/src/request.rs +++ b/src/request.rs @@ -9,7 +9,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::{DeserializeOwned, Serialize}; use crate::headers::{ - self, FieldName, FieldValue, FieldValues, Headers, Names, ToFieldValues, Values, CONTENT_TYPE, + self, FieldName, FieldValue, FieldValues, Fields, Names, ToFieldValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -55,7 +55,7 @@ impl Request { Self { method, url, - headers: Headers::new(), + headers: Fields::new(), version: None, body: Body::empty(), ext: Extensions::new(), @@ -926,13 +926,13 @@ impl AsyncBufRead for Request { } } -impl AsRef for Request { +impl AsRef for Request { fn as_ref(&self) -> &Headers { &self.headers } } -impl AsMut for Request { +impl AsMut for Request { fn as_mut(&mut self) -> &mut Headers { &mut self.headers } diff --git a/src/response.rs b/src/response.rs index 7118bc51..042d0341 100644 --- a/src/response.rs +++ b/src/response.rs @@ -10,7 +10,7 @@ use std::task::{Context, Poll}; #[cfg(feature = "serde")] use crate::convert::DeserializeOwned; use crate::headers::{ - self, FieldName, FieldValue, FieldValues, Headers, Names, ToFieldValues, Values, CONTENT_TYPE, + self, FieldName, FieldValue, FieldValues, Fields, Names, ToFieldValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; @@ -65,7 +65,7 @@ impl Response { let (upgrade_sender, upgrade_receiver) = async_channel::bounded(1); Self { status, - headers: Headers::new(), + headers: Fields::new(), version: None, body: Body::empty(), trailers_sender: Some(trailers_sender), @@ -626,13 +626,13 @@ impl AsyncBufRead for Response { } } -impl AsRef for Response { +impl AsRef for Response { fn as_ref(&self) -> &Headers { &self.headers } } -impl AsMut for Response { +impl AsMut for Response { fn as_mut(&mut self) -> &mut Headers { &mut self.headers } diff --git a/src/security/csp.rs b/src/security/csp.rs index 9478f34a..cc38a991 100644 --- a/src/security/csp.rs +++ b/src/security/csp.rs @@ -1,4 +1,4 @@ -use crate::headers::Headers; +use crate::headers::Fields; use std::collections::HashMap; use std::fmt; @@ -355,7 +355,7 @@ impl ContentSecurityPolicy { } /// Sets the `Content-Security-Policy` (CSP) HTTP header to prevent cross-site injections - pub fn apply(&mut self, mut headers: impl AsMut) { + pub fn apply(&mut self, mut headers: impl AsMut) { let name = if self.report_only_flag { "Content-Security-Policy-Report-Only" } else { diff --git a/src/security/mod.rs b/src/security/mod.rs index 34f75bee..8d755309 100644 --- a/src/security/mod.rs +++ b/src/security/mod.rs @@ -41,7 +41,7 @@ pub use timing_allow_origin::TimingAllowOrigin; // /// assert_eq!(headers["X-Content-Type-Options"], "nosniff"); // /// assert_eq!(headers["X-XSS-Protection"], "1; mode=block"); // /// ``` -pub fn default(mut headers: impl AsMut) { +pub fn default(mut headers: impl AsMut) { dns_prefetch_control(&mut headers); nosniff(&mut headers); frameguard(&mut headers, None); @@ -63,7 +63,7 @@ pub fn default(mut headers: impl AsMut) { // /// assert_eq!(headers["X-DNS-Prefetch-Control"], "on"); // /// ``` #[inline] -pub fn dns_prefetch_control(mut headers: impl AsMut) { +pub fn dns_prefetch_control(mut headers: impl AsMut) { // This will never fail, could use an unsafe version of insert. headers .as_mut() @@ -93,7 +93,7 @@ pub enum FrameOptions { // /// assert_eq!(headers["X-Frame-Options"], "sameorigin"); // /// ``` #[inline] -pub fn frameguard(mut headers: impl AsMut, guard: Option) { +pub fn frameguard(mut headers: impl AsMut, guard: Option) { let kind = match guard { None | Some(FrameOptions::SameOrigin) => "sameorigin", Some(FrameOptions::Deny) => "deny", @@ -117,7 +117,7 @@ pub fn frameguard(mut headers: impl AsMut, guard: Option) // /// assert_eq!(headers.get("X-Powered-By"), None); // /// ``` #[inline] -pub fn powered_by(mut headers: impl AsMut, value: Option) { +pub fn powered_by(mut headers: impl AsMut, value: Option) { let name = FieldName::from_lowercase_str("X-Powered-By"); match value { Some(value) => { @@ -146,7 +146,7 @@ pub fn powered_by(mut headers: impl AsMut, value: Option) { // /// assert_eq!(headers["Strict-Transport-Security"], "max-age=5184000"); // /// ``` #[inline] -pub fn hsts(mut headers: impl AsMut) { +pub fn hsts(mut headers: impl AsMut) { // Never fails, could use unsafe version of insert headers .as_mut() @@ -168,7 +168,7 @@ pub fn hsts(mut headers: impl AsMut) { // /// assert_eq!(headers["X-Content-Type-Options"], "nosniff"); // /// ``` #[inline] -pub fn nosniff(mut headers: impl AsMut) { +pub fn nosniff(mut headers: impl AsMut) { // Never fails, could use unsafe verison of insert. headers .as_mut() @@ -189,7 +189,7 @@ pub fn nosniff(mut headers: impl AsMut) { // /// assert_eq!(headers["X-XSS-Protection"], "1; mode=block"); // /// ``` #[inline] -pub fn xss_filter(mut headers: impl AsMut) { +pub fn xss_filter(mut headers: impl AsMut) { // Never fails, could use unsafe version of insert. headers .as_mut() @@ -236,7 +236,7 @@ pub enum ReferrerOptions { // /// assert_eq!(referrerValues.sort(), vec!("unsafe-url", "no-referrer").sort()); // /// ``` #[inline] -pub fn referrer_policy(mut headers: impl AsMut, referrer: Option) { +pub fn referrer_policy(mut headers: impl AsMut, referrer: Option) { let policy = match referrer { None | Some(ReferrerOptions::NoReferrer) => "no-referrer", Some(ReferrerOptions::NoReferrerDowngrade) => "no-referrer-when-downgrade", diff --git a/src/security/strict_transport_security.rs b/src/security/strict_transport_security.rs index 874f12e2..f95ffce6 100644 --- a/src/security/strict_transport_security.rs +++ b/src/security/strict_transport_security.rs @@ -71,9 +71,7 @@ impl StrictTransportSecurity { } impl Field for StrictTransportSecurity { - fn field_name(&self) -> FieldName { - STRICT_TRANSPORT_SECURITY - } + const FIELD_NAME: FieldName = STRICT_TRANSPORT_SECURITY; fn field_value(&self) -> FieldValue { let max_age = self.max_age.as_secs(); @@ -93,7 +91,7 @@ impl Field for StrictTransportSecurity { // TODO: move to new header traits impl StrictTransportSecurity { /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(STRICT_TRANSPORT_SECURITY) { Some(headers) => headers, None => return Ok(None), diff --git a/src/security/timing_allow_origin.rs b/src/security/timing_allow_origin.rs index 87f471ab..d9520a32 100644 --- a/src/security/timing_allow_origin.rs +++ b/src/security/timing_allow_origin.rs @@ -26,7 +26,7 @@ //! # Ok(()) } //! ``` -use crate::headers::{Field, FieldName, FieldValue, Headers, TIMING_ALLOW_ORIGIN}; +use crate::headers::{Field, FieldName, FieldValue, Fields, TIMING_ALLOW_ORIGIN}; use crate::{Status, Url}; use std::fmt::Write; @@ -77,7 +77,7 @@ impl TimingAllowOrigin { /// # Implementation note /// /// A header value of `"null"` is treated the same as if no header was sent. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(TIMING_ALLOW_ORIGIN) { Some(headers) => headers, None => return Ok(None), @@ -132,9 +132,7 @@ impl TimingAllowOrigin { } impl Field for TimingAllowOrigin { - fn field_name(&self) -> FieldName { - TIMING_ALLOW_ORIGIN - } + const FIELD_NAME: FieldName = TIMING_ALLOW_ORIGIN; fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, origin) in self.origins.iter().enumerate() { @@ -258,14 +256,14 @@ impl Debug for TimingAllowOrigin { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let mut origins = TimingAllowOrigin::new(); origins.push(Url::parse("https://example.com")?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); @@ -280,7 +278,7 @@ mod test { origins.push(Url::parse("https://example.com")?); origins.push(Url::parse("https://mozilla.org/")?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); @@ -295,7 +293,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(TIMING_ALLOW_ORIGIN, "server; ") .unwrap(); @@ -309,7 +307,7 @@ mod test { origins.push(Url::parse("https://example.com")?); origins.set_wildcard(true); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); diff --git a/src/server/allow.rs b/src/server/allow.rs index 8055a46b..6c2bd8be 100644 --- a/src/server/allow.rs +++ b/src/server/allow.rs @@ -1,6 +1,6 @@ //! List the set of methods supported by a resource. -use crate::headers::{Field, FieldName, FieldValue, Headers, ALLOW}; +use crate::headers::{Field, FieldName, FieldValue, Fields, ALLOW}; use crate::Method; use std::collections::{hash_set, HashSet}; @@ -49,7 +49,7 @@ impl Allow { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = HashSet::new(); let headers = match headers.as_ref().get(ALLOW) { Some(headers) => headers, @@ -173,7 +173,7 @@ impl Debug for Allow { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { @@ -181,7 +181,7 @@ mod test { allow.insert(Method::Put); allow.insert(Method::Post); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(allow); let allow = Allow::from_headers(headers)?.unwrap(); diff --git a/src/trace/server_timing/mod.rs b/src/trace/server_timing/mod.rs index c2aec711..187f9dd5 100644 --- a/src/trace/server_timing/mod.rs +++ b/src/trace/server_timing/mod.rs @@ -32,7 +32,7 @@ use std::iter::Iterator; use std::slice; -use crate::headers::{Field, FieldName, FieldValue, Headers, SERVER_TIMING}; +use crate::headers::{Field, FieldName, FieldValue, Fields, SERVER_TIMING}; /// Metrics and descriptions for the given request-response cycle. /// @@ -72,7 +72,7 @@ impl ServerTiming { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut timings = vec![]; let headers = match headers.as_ref().get(SERVER_TIMING) { Some(headers) => headers, @@ -106,9 +106,7 @@ impl ServerTiming { } impl Field for ServerTiming { - fn field_name(&self) -> FieldName { - SERVER_TIMING - } + const FIELD_NAME: FieldName = SERVER_TIMING; fn field_value(&self) -> FieldValue { let mut output = String::new(); @@ -217,14 +215,14 @@ impl<'a> Iterator for IterMut<'a> { #[cfg(test)] mod test { use super::*; - use crate::headers::Headers; + use crate::headers::Fields; #[test] fn smoke() -> crate::Result<()> { let mut timings = ServerTiming::new(); timings.push(Metric::new("server".to_owned(), None, None)?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(timings); let timings = ServerTiming::from_headers(headers)?.unwrap(); @@ -238,7 +236,7 @@ mod test { let mut timings = ServerTiming::new(); timings.push(Metric::new("server".to_owned(), None, None)?); - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers.insert(timings); let timings = ServerTiming::from_headers(headers)?.unwrap(); @@ -249,7 +247,7 @@ mod test { #[test] fn bad_request_on_parse_error() { - let mut headers = Headers::new(); + let mut headers = Fields::new(); headers .insert(SERVER_TIMING, "server; ") .unwrap(); diff --git a/src/trace/trace_context.rs b/src/trace/trace_context.rs index 9c6176c8..c887aa0c 100644 --- a/src/trace/trace_context.rs +++ b/src/trace/trace_context.rs @@ -1,6 +1,6 @@ use std::fmt; -use crate::headers::{Field, FieldName, FieldValue, Headers, TRACEPARENT}; +use crate::headers::{Field, FieldName, FieldValue, Fields, TRACEPARENT}; use crate::Status; /// Extract and apply [Trace-Context](https://w3c.github.io/trace-context/) headers. @@ -99,7 +99,7 @@ impl TraceContext { /// # /// # Ok(()) } /// ``` - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = headers.as_ref(); let traceparent = match headers.get(TRACEPARENT) { @@ -220,7 +220,7 @@ mod test { #[test] fn default() -> crate::Result<()> { - let mut headers = crate::headers::Headers::new(); + let mut headers = crate::headers::Fields::new(); headers.insert(TRACEPARENT, "00-01-deadbeef-00").unwrap(); let context = TraceContext::from_headers(&mut headers)?.unwrap(); assert_eq!(context.version(), 0); @@ -242,7 +242,7 @@ mod test { #[test] fn not_sampled() -> crate::Result<()> { - let mut headers = crate::headers::Headers::new(); + let mut headers = crate::headers::Fields::new(); headers.insert(TRACEPARENT, "00-01-02-00").unwrap(); let context = TraceContext::from_headers(&mut headers)?.unwrap(); assert!(!context.sampled()); @@ -251,7 +251,7 @@ mod test { #[test] fn sampled() -> crate::Result<()> { - let mut headers = crate::headers::Headers::new(); + let mut headers = crate::headers::Fields::new(); headers.insert(TRACEPARENT, "00-01-02-01").unwrap(); let context = TraceContext::from_headers(&mut headers)?.unwrap(); assert!(context.sampled()); diff --git a/src/trailers.rs b/src/trailers.rs index ebfdc279..b42a54ab 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -48,9 +48,7 @@ //! - [MDN HTTP Headers: Trailer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer) //! - [HTTP/2 spec: HTTP Sequence](https://http2.github.io/http2-spec/#HttpSequence) -use crate::headers::{ - FieldName, FieldValues, Headers, Iter, IterMut, Names, ToFieldValues, Values, -}; +use crate::headers::{FieldName, FieldValues, Fields, Iter, IterMut, Names, ToFieldValues, Values}; use futures_lite::Stream; use std::convert::Into; @@ -69,7 +67,7 @@ impl Trailers { /// Create a new instance of `Trailers`. pub fn new() -> Self { Self { - headers: Headers::new(), + headers: Fields::new(), } } diff --git a/src/transfer/te.rs b/src/transfer/te.rs index 18260113..e4aca83f 100644 --- a/src/transfer/te.rs +++ b/src/transfer/te.rs @@ -52,7 +52,7 @@ impl TE { } /// Create an instance of `TE` from a `Headers` instance. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; let headers = match headers.as_ref().get(headers::TE) { Some(headers) => headers, diff --git a/src/transfer/transfer_encoding.rs b/src/transfer/transfer_encoding.rs index 07e650b0..eb0d6d87 100644 --- a/src/transfer/transfer_encoding.rs +++ b/src/transfer/transfer_encoding.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers, TRANSFER_ENCODING}; +use crate::headers::{Field, FieldName, FieldValue, Fields, TRANSFER_ENCODING}; use crate::transfer::{Encoding, EncodingProposal}; use std::fmt::{self, Debug}; @@ -40,7 +40,7 @@ impl TransferEncoding { } /// Create a new instance from headers. - pub fn from_headers(headers: impl AsRef) -> crate::Result> { + pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = match headers.as_ref().get(TRANSFER_ENCODING) { Some(headers) => headers, None => return Ok(None), @@ -65,9 +65,7 @@ impl TransferEncoding { } impl Field for TransferEncoding { - fn field_name(&self) -> FieldName { - TRANSFER_ENCODING - } + const FIELD_NAME: FieldName = TRANSFER_ENCODING; fn field_value(&self) -> FieldValue { self.inner.into() } From b0c50be2dbefe9360bb98409ad96c3fb5b71ae92 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 19 Jun 2022 03:40:46 +0200 Subject: [PATCH 8/9] add typed insert methods --- src/auth/authorization.rs | 2 +- src/auth/basic_auth.rs | 2 +- src/auth/www_authenticate.rs | 2 +- src/cache/age.rs | 2 +- src/cache/cache_control/mod.rs | 2 +- src/cache/clear_site_data/mod.rs | 4 ++-- src/cache/expires.rs | 2 +- src/conditional/etag.rs | 4 ++-- src/conditional/if_match.rs | 4 ++-- src/conditional/if_modified_since.rs | 2 +- src/conditional/if_none_match.rs | 4 ++-- src/conditional/if_unmodified_since.rs | 2 +- src/conditional/vary.rs | 4 ++-- src/content/accept.rs | 12 ++++++------ src/content/accept_encoding.rs | 12 ++++++------ src/content/content_length.rs | 2 +- src/content/content_type.rs | 2 +- src/headers/headers.rs | 12 ++++++++++-- src/other/date.rs | 2 +- src/other/expect.rs | 2 +- src/other/referer.rs | 2 +- src/other/retry_after.rs | 4 ++-- src/request.rs | 10 +++++++++- src/response.rs | 10 +++++++++- src/security/mod.rs | 2 +- src/security/strict_transport_security.rs | 4 ++-- src/security/timing_allow_origin.rs | 8 ++++---- src/server/allow.rs | 2 +- src/trace/server_timing/mod.rs | 4 ++-- src/transfer/te.rs | 14 +++++++------- 30 files changed, 82 insertions(+), 58 deletions(-) diff --git a/src/auth/authorization.rs b/src/auth/authorization.rs index f45b0489..590eb50d 100644 --- a/src/auth/authorization.rs +++ b/src/auth/authorization.rs @@ -115,7 +115,7 @@ mod test { let authz = Authorization::new(scheme, credentials.into()); let mut headers = Fields::new(); - headers.insert(authz); + headers.insert_typed(authz); let authz = Authorization::from_headers(headers)?.unwrap(); diff --git a/src/auth/basic_auth.rs b/src/auth/basic_auth.rs index 3dbbea63..677e9fc1 100644 --- a/src/auth/basic_auth.rs +++ b/src/auth/basic_auth.rs @@ -121,7 +121,7 @@ mod test { let authz = BasicAuth::new(username, password); let mut headers = Fields::new(); - headers.insert(authz); + headers.insert_typed(authz); let authz = BasicAuth::from_headers(headers)?.unwrap(); diff --git a/src/auth/www_authenticate.rs b/src/auth/www_authenticate.rs index 443b18b7..40ce0bae 100644 --- a/src/auth/www_authenticate.rs +++ b/src/auth/www_authenticate.rs @@ -137,7 +137,7 @@ mod test { let authz = WwwAuthenticate::new(scheme, realm.into()); let mut headers = Fields::new(); - headers.insert(authz); + headers.insert_typed(authz); assert_eq!( headers["WWW-Authenticate"], diff --git a/src/cache/age.rs b/src/cache/age.rs index e118c469..6262bc50 100644 --- a/src/cache/age.rs +++ b/src/cache/age.rs @@ -90,7 +90,7 @@ mod test { let age = Age::new(Duration::from_secs(12)); let mut headers = Fields::new(); - headers.insert(age); + headers.insert_typed(age); let age = Age::from_headers(headers)?.unwrap(); assert_eq!(age, Age::new(Duration::from_secs(12))); diff --git a/src/cache/cache_control/mod.rs b/src/cache/cache_control/mod.rs index eb0ded36..a5edc39b 100644 --- a/src/cache/cache_control/mod.rs +++ b/src/cache/cache_control/mod.rs @@ -25,7 +25,7 @@ mod test { entries.push(CacheDirective::NoStore); let mut headers = Fields::new(); - headers.insert(entries); + headers.insert_typed(entries); let entries = CacheControl::from_headers(headers)?.unwrap(); let mut entries = entries.iter(); diff --git a/src/cache/clear_site_data/mod.rs b/src/cache/clear_site_data/mod.rs index 066fda31..b217e44f 100644 --- a/src/cache/clear_site_data/mod.rs +++ b/src/cache/clear_site_data/mod.rs @@ -248,7 +248,7 @@ mod test { entries.push(ClearDirective::Cookies); let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = ClearSiteData::from_headers(res)?.unwrap(); let mut entries = entries.iter(); @@ -264,7 +264,7 @@ mod test { entries.set_wildcard(true); let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = ClearSiteData::from_headers(res)?.unwrap(); assert!(entries.wildcard()); diff --git a/src/cache/expires.rs b/src/cache/expires.rs index d8ca3575..1496b7ea 100644 --- a/src/cache/expires.rs +++ b/src/cache/expires.rs @@ -92,7 +92,7 @@ mod test { let expires = Expires::new_at(time); let mut headers = Fields::new(); - headers.insert(expires); + headers.insert_typed(expires); let expires = Expires::from_headers(headers)?.unwrap(); diff --git a/src/conditional/etag.rs b/src/conditional/etag.rs index 3152299d..e13b5324 100644 --- a/src/conditional/etag.rs +++ b/src/conditional/etag.rs @@ -140,7 +140,7 @@ mod test { let etag = ETag::new("0xcafebeef".to_string()); let mut headers = Fields::new(); - headers.insert(etag); + headers.insert_typed(etag); let etag = ETag::from_headers(headers)?.unwrap(); assert_eq!(etag, ETag::Strong(String::from("0xcafebeef"))); @@ -152,7 +152,7 @@ mod test { let etag = ETag::new_weak("0xcafebeef".to_string()); let mut headers = Fields::new(); - headers.insert(etag); + headers.insert_typed(etag); let etag = ETag::from_headers(headers)?.unwrap(); assert_eq!(etag, ETag::Weak(String::from("0xcafebeef"))); diff --git a/src/conditional/if_match.rs b/src/conditional/if_match.rs index 202873af..fed73c3a 100644 --- a/src/conditional/if_match.rs +++ b/src/conditional/if_match.rs @@ -238,7 +238,7 @@ mod test { entries.push(ETag::new("0xbeefcafe".to_string())); let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = IfMatch::from_headers(res)?.unwrap(); let mut entries = entries.iter(); @@ -260,7 +260,7 @@ mod test { entries.set_wildcard(true); let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = IfMatch::from_headers(res)?.unwrap(); assert!(entries.wildcard()); diff --git a/src/conditional/if_modified_since.rs b/src/conditional/if_modified_since.rs index ff2da68f..8c6d0d27 100644 --- a/src/conditional/if_modified_since.rs +++ b/src/conditional/if_modified_since.rs @@ -89,7 +89,7 @@ mod test { let expires = IfModifiedSince::new(time); let mut headers = Fields::new(); - headers.insert(expires); + headers.insert_typed(expires); let expires = IfModifiedSince::from_headers(headers)?.unwrap(); diff --git a/src/conditional/if_none_match.rs b/src/conditional/if_none_match.rs index 0ea6cbd4..4b26abc5 100644 --- a/src/conditional/if_none_match.rs +++ b/src/conditional/if_none_match.rs @@ -244,7 +244,7 @@ mod test { entries.push(ETag::new("0xbeefcafe".to_string())); let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = IfNoneMatch::from_headers(res)?.unwrap(); let mut entries = entries.iter(); @@ -266,7 +266,7 @@ mod test { entries.set_wildcard(true); let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = IfNoneMatch::from_headers(res)?.unwrap(); assert!(entries.wildcard()); diff --git a/src/conditional/if_unmodified_since.rs b/src/conditional/if_unmodified_since.rs index 66075a00..0891a6e9 100644 --- a/src/conditional/if_unmodified_since.rs +++ b/src/conditional/if_unmodified_since.rs @@ -89,7 +89,7 @@ mod test { let expires = IfUnmodifiedSince::new(time); let mut headers = Fields::new(); - headers.insert(expires); + headers.insert_typed(expires); let expires = IfUnmodifiedSince::from_headers(headers)?.unwrap(); diff --git a/src/conditional/vary.rs b/src/conditional/vary.rs index 083628ec..503a640b 100644 --- a/src/conditional/vary.rs +++ b/src/conditional/vary.rs @@ -245,7 +245,7 @@ mod test { entries.push("Accept-Encoding")?; let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = Vary::from_headers(res)?.unwrap(); let mut entries = entries.iter(); @@ -261,7 +261,7 @@ mod test { entries.set_wildcard(true); let mut res = Response::new(200); - entries.apply_header(&mut res); + res.insert_typed_header(entries); let entries = Vary::from_headers(res)?.unwrap(); assert!(entries.wildcard()); diff --git a/src/content/accept.rs b/src/content/accept.rs index d617dff1..84fb4ca3 100644 --- a/src/content/accept.rs +++ b/src/content/accept.rs @@ -296,7 +296,7 @@ mod test { accept.push(mime::HTML); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = Accept::from_headers(headers)?.unwrap(); assert_eq!(accept.iter().next().unwrap(), mime::HTML); @@ -309,7 +309,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = Accept::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -323,7 +323,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = Accept::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -338,7 +338,7 @@ mod test { accept.push(mime::XML); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = Accept::from_headers(headers)?.unwrap(); let mut accept = accept.iter(); @@ -355,7 +355,7 @@ mod test { accept.push(MediaTypeProposal::new(mime::PLAIN, Some(0.8))?); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let mut accept = Accept::from_headers(headers)?.unwrap(); accept.sort(); @@ -374,7 +374,7 @@ mod test { accept.push(MediaTypeProposal::new(mime::PLAIN, Some(0.8))?); let mut res = Response::new(200); - accept.apply_header(&mut res); + res.insert_typed_header(accept); let mut accept = Accept::from_headers(res)?.unwrap(); accept.sort(); diff --git a/src/content/accept_encoding.rs b/src/content/accept_encoding.rs index 79d07251..e2c969ec 100644 --- a/src/content/accept_encoding.rs +++ b/src/content/accept_encoding.rs @@ -289,7 +289,7 @@ mod test { accept.push(Encoding::Gzip); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); assert_eq!(accept.iter().next().unwrap(), Encoding::Gzip); @@ -302,7 +302,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -316,7 +316,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -331,7 +331,7 @@ mod test { accept.push(Encoding::Brotli); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = AcceptEncoding::from_headers(headers)?.unwrap(); let mut accept = accept.iter(); @@ -348,7 +348,7 @@ mod test { accept.push(EncodingProposal::new(Encoding::Brotli, Some(0.8))?); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let mut accept = AcceptEncoding::from_headers(headers)?.unwrap(); accept.sort(); @@ -367,7 +367,7 @@ mod test { accept.push(EncodingProposal::new(Encoding::Brotli, Some(0.8))?); let mut res = Response::new(200); - accept.apply_header(&mut res); + res.insert_typed_header(accept); let mut accept = AcceptEncoding::from_headers(res)?.unwrap(); accept.sort(); diff --git a/src/content/content_length.rs b/src/content/content_length.rs index 393a9e8e..208e6518 100644 --- a/src/content/content_length.rs +++ b/src/content/content_length.rs @@ -82,7 +82,7 @@ mod test { let content_len = ContentLength::new(12); let mut headers = Fields::new(); - content_headers.insert(len); + headers.insert(content_len); let content_len = ContentLength::from_headers(headers)?.unwrap(); assert_eq!(content_len.len(), 12); diff --git a/src/content/content_type.rs b/src/content/content_type.rs index 0245c774..51c3cc1b 100644 --- a/src/content/content_type.rs +++ b/src/content/content_type.rs @@ -112,7 +112,7 @@ mod test { let ct = ContentType::new(Mime::from_str("text/*")?); let mut headers = Fields::new(); - headers.insert(ct); + headers.insert_typed(ct); let ct = ContentType::from_headers(headers)?.unwrap(); assert_eq!( diff --git a/src/headers/headers.rs b/src/headers/headers.rs index 80e3cbc8..fc08d290 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -45,8 +45,16 @@ impl Fields { /// Insert a header into the headers. /// /// Not that this will replace all header values for a given header name. - pub fn insert(&mut self, name: FieldName, value: FieldValue) -> Option { - self.headers.insert(name, value) + pub fn insert(&mut self, name: FieldName, value: FieldValue) -> Option { + self.headers.insert(name, value.into()) + } + + /// Insert a typed header into the headers. + /// + /// Not that this will replace all header values for a given header name. + pub fn insert_typed(&mut self, field: F) -> Option { + self.headers + .insert(F::FIELD_NAME, field.field_value().into()) } /// Get a reference to a header. diff --git a/src/other/date.rs b/src/other/date.rs index 85fc0783..78b8b4b8 100644 --- a/src/other/date.rs +++ b/src/other/date.rs @@ -115,7 +115,7 @@ mod test { let date = Date::new(now); let mut headers = Fields::new(); - headers.insert(date); + headers.insert_typed(date); let date = Date::from_headers(headers)?.unwrap(); diff --git a/src/other/expect.rs b/src/other/expect.rs index 0d9084a3..88690c49 100644 --- a/src/other/expect.rs +++ b/src/other/expect.rs @@ -75,7 +75,7 @@ mod test { let expect = Expect::new(); let mut headers = Fields::new(); - headers.insert(expect); + headers.insert_typed(expect); let expect = Expect::from_headers(headers)?.unwrap(); assert_eq!(expect, Expect::new()); diff --git a/src/other/referer.rs b/src/other/referer.rs index 059a4038..65138553 100644 --- a/src/other/referer.rs +++ b/src/other/referer.rs @@ -107,7 +107,7 @@ mod test { let referer = Referer::new(Url::parse("https://example.net/test.json")?); let mut headers = Fields::new(); - headers.insert(referer); + headers.insert_typed(referer); let base_url = Url::parse("https://example.net/")?; let referer = Referer::from_headers(base_url, headers)?.unwrap(); diff --git a/src/other/retry_after.rs b/src/other/retry_after.rs index ac2b26bf..f0a78695 100644 --- a/src/other/retry_after.rs +++ b/src/other/retry_after.rs @@ -131,7 +131,7 @@ mod test { let retry = RetryAfter::new(Duration::from_secs(10)); let mut headers = Fields::new(); - headers.insert(retry); + headers.insert_typed(retry); // `SystemTime::now` uses sub-second precision which means there's some // offset that's not encoded. @@ -150,7 +150,7 @@ mod test { let retry = RetryAfter::new_at(now + Duration::from_secs(10)); let mut headers = Fields::new(); - headers.insert(retry); + headers.insert_typed(retry); // `SystemTime::now` uses sub-second precision which means there's some // offset that's not encoded. diff --git a/src/request.rs b/src/request.rs index fc61f0af..c4d1a617 100644 --- a/src/request.rs +++ b/src/request.rs @@ -13,7 +13,7 @@ use crate::headers::{ }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; -use crate::{Body, Extensions, Method, Url, Version}; +use crate::{Body, Extensions, Field, Method, Url, Version}; pin_project_lite::pin_project! { /// An HTTP request. @@ -443,6 +443,14 @@ impl Request { self.headers.insert(name, values) } + /// Set a typed HTTP header. + pub fn insert_typed_header( + &mut self, + field: F, + ) -> crate::Result> { + self.headers.insert_typed(field) + } + /// Append a header to the headers. /// /// Unlike `insert` this function will not override the contents of a diff --git a/src/response.rs b/src/response.rs index 042d0341..3f8385f7 100644 --- a/src/response.rs +++ b/src/response.rs @@ -14,7 +14,7 @@ use crate::headers::{ }; use crate::mime::Mime; use crate::trailers::{self, Trailers}; -use crate::upgrade; +use crate::{upgrade, Field}; use crate::{Body, Extensions, StatusCode, Version}; pin_project_lite::pin_project! { @@ -122,6 +122,14 @@ impl Response { self.headers.insert(name, values) } + /// Set a typed HTTP header. + pub fn insert_typed_header( + &mut self, + field: F, + ) -> crate::Result> { + self.headers.insert_typed(field) + } + /// Append a header to the headers. /// /// Unlike `insert` this function will not override the contents of a diff --git a/src/security/mod.rs b/src/security/mod.rs index 8d755309..c581b1da 100644 --- a/src/security/mod.rs +++ b/src/security/mod.rs @@ -15,7 +15,7 @@ // //! assert_eq!(res["X-XSS-Protection"], "1; mode=block"); //! ``` -use crate::headers::{FieldName, FieldValue, Headers}; +use crate::headers::{FieldName, FieldValue, Fields}; mod csp; mod strict_transport_security; diff --git a/src/security/strict_transport_security.rs b/src/security/strict_transport_security.rs index f95ffce6..7e1ead7a 100644 --- a/src/security/strict_transport_security.rs +++ b/src/security/strict_transport_security.rs @@ -1,4 +1,4 @@ -use crate::headers::{Field, FieldName, FieldValue, Headers}; +use crate::headers::{Field, FieldName, FieldValue, Fields}; use crate::Status; use crate::headers::STRICT_TRANSPORT_SECURITY; @@ -168,7 +168,7 @@ mod test { let stc = StrictTransportSecurity::new(duration); let mut headers = Response::new(200); - headers.insert(stc); + headers.insert_typed_header(stc); let stc = StrictTransportSecurity::from_headers(headers)?.unwrap(); diff --git a/src/security/timing_allow_origin.rs b/src/security/timing_allow_origin.rs index d9520a32..a5524341 100644 --- a/src/security/timing_allow_origin.rs +++ b/src/security/timing_allow_origin.rs @@ -17,7 +17,7 @@ //! origins.push(Url::parse("https://example.com")?); //! //! let mut res = Response::new(200); -//! origins.apply_header(&mut res); +//! res.insert_typed_header(origins); //! //! let origins = TimingAllowOrigin::from_headers(res)?.unwrap(); //! let origin = origins.iter().next().unwrap(); @@ -264,7 +264,7 @@ mod test { origins.push(Url::parse("https://example.com")?); let mut headers = Fields::new(); - headers.insert(origins); + headers.insert_typed(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); let origin = origins.iter().next().unwrap(); @@ -279,7 +279,7 @@ mod test { origins.push(Url::parse("https://mozilla.org/")?); let mut headers = Fields::new(); - headers.insert(origins); + headers.insert_typed(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); let mut origins = origins.iter(); @@ -308,7 +308,7 @@ mod test { origins.set_wildcard(true); let mut headers = Fields::new(); - headers.insert(origins); + headers.insert_typed(origins); let origins = TimingAllowOrigin::from_headers(headers)?.unwrap(); assert!(origins.wildcard()); diff --git a/src/server/allow.rs b/src/server/allow.rs index 6c2bd8be..0f670140 100644 --- a/src/server/allow.rs +++ b/src/server/allow.rs @@ -182,7 +182,7 @@ mod test { allow.insert(Method::Post); let mut headers = Fields::new(); - headers.insert(allow); + headers.insert_typed(allow); let allow = Allow::from_headers(headers)?.unwrap(); assert!(allow.contains(Method::Put)); diff --git a/src/trace/server_timing/mod.rs b/src/trace/server_timing/mod.rs index 187f9dd5..50f60b1f 100644 --- a/src/trace/server_timing/mod.rs +++ b/src/trace/server_timing/mod.rs @@ -223,7 +223,7 @@ mod test { timings.push(Metric::new("server".to_owned(), None, None)?); let mut headers = Fields::new(); - headers.insert(timings); + headers.insert_typed(timings); let timings = ServerTiming::from_headers(headers)?.unwrap(); let entry = timings.iter().next().unwrap(); @@ -237,7 +237,7 @@ mod test { timings.push(Metric::new("server".to_owned(), None, None)?); let mut headers = Fields::new(); - headers.insert(timings); + headers.insert_typed(timings); let timings = ServerTiming::from_headers(headers)?.unwrap(); let entry = timings.iter().next().unwrap(); diff --git a/src/transfer/te.rs b/src/transfer/te.rs index e4aca83f..7c73b251 100644 --- a/src/transfer/te.rs +++ b/src/transfer/te.rs @@ -1,4 +1,4 @@ -use crate::headers::{self, Field, FieldName, FieldValue, Headers}; +use crate::headers::{self, Field, FieldName, FieldValue, Fields}; use crate::transfer::{Encoding, EncodingProposal, TransferEncoding}; use crate::utils::sort_by_weight; use crate::{Error, StatusCode}; @@ -289,7 +289,7 @@ mod test { accept.push(Encoding::Gzip); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = TE::from_headers(headers)?.unwrap(); assert_eq!(accept.iter().next().unwrap(), Encoding::Gzip); @@ -302,7 +302,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = TE::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -316,7 +316,7 @@ mod test { accept.set_wildcard(true); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = TE::from_headers(headers)?.unwrap(); assert!(accept.wildcard()); @@ -331,7 +331,7 @@ mod test { accept.push(Encoding::Brotli); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let accept = TE::from_headers(headers)?.unwrap(); let mut accept = accept.iter(); @@ -348,7 +348,7 @@ mod test { accept.push(EncodingProposal::new(Encoding::Brotli, Some(0.8))?); let mut headers = Response::new(200); - headers.insert(accept); + headers.insert_typed_header(accept); let mut accept = TE::from_headers(headers)?.unwrap(); accept.sort(); @@ -367,7 +367,7 @@ mod test { accept.push(EncodingProposal::new(Encoding::Brotli, Some(0.8))?); let mut res = Response::new(200); - accept.apply_header(&mut res); + res.insert_typed_header(accept); let mut accept = TE::from_headers(res)?.unwrap(); accept.sort(); From eb1f01134104b54d4cea622675b7535ffdcf7f32 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 19 Jun 2022 03:56:50 +0200 Subject: [PATCH 9/9] finish adding the `Field` trait --- src/cache/cache_control/mod.rs | 2 +- src/conditional/last_modified.rs | 2 +- src/content/content_length.rs | 2 +- src/content/content_location.rs | 2 +- src/headers/header.rs | 12 ---------- src/headers/header_name.rs | 4 ++-- src/headers/headers.rs | 38 +++++++++++++++++++++++++++----- src/other/source_map.rs | 2 +- src/request.rs | 13 +++++------ src/response.rs | 11 ++++----- src/status_code.rs | 1 - src/trailers.rs | 12 +++++----- src/transfer/te.rs | 6 ++--- 13 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/cache/cache_control/mod.rs b/src/cache/cache_control/mod.rs index a5edc39b..28145b76 100644 --- a/src/cache/cache_control/mod.rs +++ b/src/cache/cache_control/mod.rs @@ -16,7 +16,7 @@ pub use cache_directive::CacheDirective; #[cfg(test)] mod test { use super::*; - use crate::headers::{Field, Fields, CACHE_CONTROL}; + use crate::headers::{Fields, CACHE_CONTROL}; #[test] fn smoke() -> crate::Result<()> { diff --git a/src/conditional/last_modified.rs b/src/conditional/last_modified.rs index 3bc1a8b1..92eb6f05 100644 --- a/src/conditional/last_modified.rs +++ b/src/conditional/last_modified.rs @@ -88,7 +88,7 @@ mod test { let last_modified = LastModified::new(time); let mut headers = Fields::new(); - last_headers.insert(modified); + headers.insert_typed(last_modified); let last_modified = LastModified::from_headers(headers)?.unwrap(); diff --git a/src/content/content_length.rs b/src/content/content_length.rs index 208e6518..3ef3334e 100644 --- a/src/content/content_length.rs +++ b/src/content/content_length.rs @@ -82,7 +82,7 @@ mod test { let content_len = ContentLength::new(12); let mut headers = Fields::new(); - headers.insert(content_len); + headers.insert_typed(content_len); let content_len = ContentLength::from_headers(headers)?.unwrap(); assert_eq!(content_len.len(), 12); diff --git a/src/content/content_location.rs b/src/content/content_location.rs index 085ce111..d0cee5de 100644 --- a/src/content/content_location.rs +++ b/src/content/content_location.rs @@ -101,7 +101,7 @@ mod test { let content_location = ContentLocation::new(Url::parse("https://example.net/test.json")?); let mut headers = Fields::new(); - content_headers.insert(location); + headers.insert_typed(content_location); let content_location = ContentLocation::from_headers(Url::parse("https://example.net/").unwrap(), headers)? diff --git a/src/headers/header.rs b/src/headers/header.rs index 65ee9626..9e9587b4 100644 --- a/src/headers/header.rs +++ b/src/headers/header.rs @@ -21,15 +21,3 @@ where // // TODO: move this to a separate trait. // fn from_field_pair(name: FieldName, value: FieldValue) -> Result; } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn header_from_strings() { - let strings = ("Content-Length", "12"); - assert_eq!(strings.header_name(), "Content-Length"); - assert_eq!(strings.header_value(), "12"); - } -} diff --git a/src/headers/header_name.rs b/src/headers/header_name.rs index 9628d6e8..ac597e66 100644 --- a/src/headers/header_name.rs +++ b/src/headers/header_name.rs @@ -91,8 +91,8 @@ impl From<&FieldName> for FieldName { } impl From for FieldName { - fn from(header: T) -> FieldName { - header.field_name() + fn from(_field: T) -> FieldName { + T::FIELD_NAME } } diff --git a/src/headers/headers.rs b/src/headers/headers.rs index fc08d290..47dba549 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -11,8 +11,6 @@ use crate::headers::{ Field, FieldName, FieldValues, IntoIter, Iter, IterMut, Names, ToFieldValues, Values, }; -use super::FieldValue; - /// A collection of HTTP Fields. /// /// Fields are never manually constructed, but are part of `Request`, @@ -45,8 +43,14 @@ impl Fields { /// Insert a header into the headers. /// /// Not that this will replace all header values for a given header name. - pub fn insert(&mut self, name: FieldName, value: FieldValue) -> Option { - self.headers.insert(name, value.into()) + pub fn insert( + &mut self, + name: impl Into, + values: impl ToFieldValues, + ) -> crate::Result> { + let name = name.into(); + let values: FieldValues = values.to_field_values().unwrap().collect(); + Ok(self.headers.insert(name, values)) } /// Insert a typed header into the headers. @@ -57,9 +61,31 @@ impl Fields { .insert(F::FIELD_NAME, field.field_value().into()) } + /// Append a header to the headers. + /// + /// Unlike `insert` this function will not override the contents of a header, but insert a + /// header if there aren't any. Or else append to the existing list of headers. + pub fn append( + &mut self, + name: impl Into, + values: impl ToFieldValues, + ) -> crate::Result<()> { + let name = name.into(); + match self.get_mut(&name) { + Some(headers) => { + let mut values: FieldValues = values.to_field_values()?.collect(); + headers.append(&mut values); + } + None => { + self.insert(name, values)?; + } + } + Ok(()) + } + /// Get a reference to a header. - pub fn get(&self, name: FieldName) -> Option<&FieldValues> { - self.headers.get(&name) + pub fn get(&self, name: impl Into) -> Option<&FieldValues> { + self.headers.get(&name.into()) } /// Get a mutable reference to a header. diff --git a/src/other/source_map.rs b/src/other/source_map.rs index b16149b0..f528f12e 100644 --- a/src/other/source_map.rs +++ b/src/other/source_map.rs @@ -104,7 +104,7 @@ mod test { let source_map = SourceMap::new(Url::parse("https://example.net/test.json")?); let mut headers = Fields::new(); - source_headers.insert(map); + headers.insert_typed(source_map); let base_url = Url::parse("https://example.net/")?; let source_map = SourceMap::from_headers(base_url, headers)?.unwrap(); diff --git a/src/request.rs b/src/request.rs index c4d1a617..d9b83754 100644 --- a/src/request.rs +++ b/src/request.rs @@ -30,7 +30,7 @@ pin_project_lite::pin_project! { pub struct Request { method: Method, url: Url, - headers: Headers, + headers: Fields, version: Option, #[pin] body: Body, @@ -408,7 +408,7 @@ impl Request { /// Get an HTTP header. pub fn header(&self, name: impl Into) -> Option<&FieldValues> { - self.headers.get(name) + self.headers.get(name.into()) } /// Get a mutable reference to a header. @@ -444,10 +444,7 @@ impl Request { } /// Set a typed HTTP header. - pub fn insert_typed_header( - &mut self, - field: F, - ) -> crate::Result> { + pub fn insert_typed_header(&mut self, field: F) -> Option { self.headers.insert_typed(field) } @@ -935,13 +932,13 @@ impl AsyncBufRead for Request { } impl AsRef for Request { - fn as_ref(&self) -> &Headers { + fn as_ref(&self) -> &Fields { &self.headers } } impl AsMut for Request { - fn as_mut(&mut self) -> &mut Headers { + fn as_mut(&mut self) -> &mut Fields { &mut self.headers } } diff --git a/src/response.rs b/src/response.rs index 3f8385f7..0037bab9 100644 --- a/src/response.rs +++ b/src/response.rs @@ -35,7 +35,7 @@ pin_project_lite::pin_project! { #[derive(Debug)] pub struct Response { status: StatusCode, - headers: Headers, + headers: Fields, version: Option, has_trailers: bool, trailers_sender: Option>, @@ -123,10 +123,7 @@ impl Response { } /// Set a typed HTTP header. - pub fn insert_typed_header( - &mut self, - field: F, - ) -> crate::Result> { + pub fn insert_typed_header(&mut self, field: F) -> Option { self.headers.insert_typed(field) } @@ -635,13 +632,13 @@ impl AsyncBufRead for Response { } impl AsRef for Response { - fn as_ref(&self) -> &Headers { + fn as_ref(&self) -> &Fields { &self.headers } } impl AsMut for Response { - fn as_mut(&mut self) -> &mut Headers { + fn as_mut(&mut self) -> &mut Fields { &mut self.headers } } diff --git a/src/status_code.rs b/src/status_code.rs index a86d8ac6..aa42ab7a 100644 --- a/src/status_code.rs +++ b/src/status_code.rs @@ -582,7 +582,6 @@ mod serde { where E: DeError, { - use std::convert::TryFrom; match StatusCode::try_from(v) { Ok(status_code) => Ok(status_code), Err(_) => Err(DeError::invalid_value( diff --git a/src/trailers.rs b/src/trailers.rs index b42a54ab..b662b922 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -60,7 +60,7 @@ use std::task::{Context, Poll}; /// A collection of trailing HTTP headers. #[derive(Debug)] pub struct Trailers { - headers: Headers, + headers: Fields, } impl Trailers { @@ -120,17 +120,17 @@ impl Trailers { /// Get a reference to a header. pub fn get(&self, name: impl Into) -> Option<&FieldValues> { - self.headers.get(name) + self.headers.get(name.into()) } /// Get a mutable reference to a header. pub fn get_mut(&mut self, name: impl Into) -> Option<&mut FieldValues> { - self.headers.get_mut(name) + self.headers.get_mut(name.into()) } /// Remove a header. pub fn remove(&mut self, name: impl Into) -> Option { - self.headers.remove(name) + self.headers.remove(name.into()) } /// An iterator visiting all header pairs in arbitrary order. @@ -158,7 +158,7 @@ impl Trailers { impl Clone for Trailers { fn clone(&self) -> Self { Self { - headers: Headers { + headers: Fields { headers: self.headers.headers.clone(), }, } @@ -166,7 +166,7 @@ impl Clone for Trailers { } impl Deref for Trailers { - type Target = Headers; + type Target = Fields; fn deref(&self) -> &Self::Target { &self.headers diff --git a/src/transfer/te.rs b/src/transfer/te.rs index 7c73b251..b07f1876 100644 --- a/src/transfer/te.rs +++ b/src/transfer/te.rs @@ -152,10 +152,6 @@ impl TE { } impl Field for TE { - fn field_name(&self) -> FieldName { - headers::TE - } - fn field_value(&self) -> FieldValue { let mut output = String::new(); for (n, directive) in self.entries.iter().enumerate() { @@ -176,6 +172,8 @@ impl Field for TE { // SAFETY: the internal string is validated to be ASCII. unsafe { FieldValue::from_bytes_unchecked(output.into()) } } + + const FIELD_NAME: FieldName = headers::TE; } impl IntoIterator for TE {