Skip to content

Cleanup headers #340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 6 additions & 21 deletions src/auth/authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::headers::{Header, HeaderName, HeaderValue, Headers, AUTHORIZATION};
/// let authz = Authorization::new(scheme, credentials.into());
///
/// let mut res = Response::new(200);
/// authz.apply(&mut res);
/// res.insert_header(&authz, &authz);
///
/// let authz = Authorization::from_headers(res)?.unwrap();
///
Expand Down Expand Up @@ -71,24 +71,6 @@ impl Authorization {
}))
}

/// Sets the header.
pub fn apply(&self, mut headers: impl AsMut<Headers>) {
headers.as_mut().insert(self.name(), self.value());
}

/// Get the `HeaderName`.
pub fn name(&self) -> HeaderName {
self.header_name()
}

/// Get the `HeaderValue`.
pub fn value(&self) -> HeaderValue {
let output = format!("{} {}", self.scheme, self.credentials);

// SAFETY: the internal string is validated to be ASCII.
unsafe { HeaderValue::from_bytes_unchecked(output.into()) }
}

/// Get the authorization scheme.
pub fn scheme(&self) -> AuthenticationScheme {
self.scheme
Expand Down Expand Up @@ -116,7 +98,10 @@ impl Header for Authorization {
}

fn header_value(&self) -> HeaderValue {
self.value()
let output = format!("{} {}", self.scheme, self.credentials);

// SAFETY: the internal string is validated to be ASCII.
unsafe { HeaderValue::from_bytes_unchecked(output.into()) }
}
}

Expand All @@ -132,7 +117,7 @@ mod test {
let authz = Authorization::new(scheme, credentials.into());

let mut headers = Headers::new();
authz.apply(&mut headers);
authz.apply_header(&mut headers);

let authz = Authorization::from_headers(headers)?.unwrap();

Expand Down
34 changes: 11 additions & 23 deletions src/auth/basic_auth.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::auth::{AuthenticationScheme, Authorization};
use crate::headers::{HeaderName, HeaderValue, Headers, AUTHORIZATION};
use crate::Status;
use crate::{
auth::{AuthenticationScheme, Authorization},
headers::Header,
};
use crate::{bail_status as bail, ensure_status as ensure};

/// HTTP Basic authorization.
Expand All @@ -22,7 +25,7 @@ use crate::{bail_status as bail, ensure_status as ensure};
/// let authz = BasicAuth::new(username, password);
///
/// let mut res = Response::new(200);
/// authz.apply(&mut res);
/// res.insert_header(&authz, &authz);
///
/// let authz = BasicAuth::from_headers(res)?.unwrap();
///
Expand Down Expand Up @@ -84,24 +87,6 @@ impl BasicAuth {
Ok(Self { username, password })
}

/// Sets the header.
pub fn apply(&self, mut headers: impl AsMut<Headers>) {
headers.as_mut().insert(self.name(), self.value());
}

/// Get the `HeaderName`.
pub fn name(&self) -> HeaderName {
AUTHORIZATION
}

/// Get the `HeaderValue`.
pub fn value(&self) -> HeaderValue {
let scheme = AuthenticationScheme::Basic;
let credentials = base64::encode(format!("{}:{}", self.username, self.password));
let auth = Authorization::new(scheme, credentials);
auth.value()
}

/// Get the username.
pub fn username(&self) -> &str {
self.username.as_str()
Expand All @@ -113,13 +98,16 @@ impl BasicAuth {
}
}

impl crate::headers::Header for BasicAuth {
impl Header for BasicAuth {
fn header_name(&self) -> HeaderName {
AUTHORIZATION
}

fn header_value(&self) -> HeaderValue {
self.value()
let scheme = AuthenticationScheme::Basic;
let credentials = base64::encode(format!("{}:{}", self.username, self.password));
let auth = Authorization::new(scheme, credentials);
auth.header_value()
}
}

Expand All @@ -135,7 +123,7 @@ mod test {
let authz = BasicAuth::new(username, password);

let mut headers = Headers::new();
authz.apply(&mut headers);
authz.apply_header(&mut headers);

let authz = BasicAuth::from_headers(headers)?.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion src/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//! let authz = BasicAuth::new(username, password);
//!
//! let mut res = Response::new(200);
//! authz.apply(&mut res);
//! res.insert_header(&authz, &authz);
//!
//! let authz = BasicAuth::from_headers(res)?.unwrap();
//!
Expand Down
31 changes: 8 additions & 23 deletions src/auth/www_authenticate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::auth::AuthenticationScheme;
use crate::bail_status as bail;
use crate::headers::{HeaderName, HeaderValue, Headers, WWW_AUTHENTICATE};
use crate::{auth::AuthenticationScheme, headers::Header};

/// Define the authentication method that should be used to gain access to a
/// resource.
Expand All @@ -27,7 +27,7 @@ use crate::headers::{HeaderName, HeaderValue, Headers, WWW_AUTHENTICATE};
/// let authz = WwwAuthenticate::new(scheme, realm.into());
///
/// let mut res = Response::new(200);
/// authz.apply(&mut res);
/// res.insert_header(&authz, &authz);
///
/// let authz = WwwAuthenticate::from_headers(res)?.unwrap();
///
Expand Down Expand Up @@ -93,24 +93,6 @@ impl WwwAuthenticate {
Ok(Some(Self { scheme, realm }))
}

/// Sets the header.
pub fn apply(&self, mut headers: impl AsMut<Headers>) {
headers.as_mut().insert(self.name(), self.value());
}

/// Get the `HeaderName`.
pub fn name(&self) -> HeaderName {
WWW_AUTHENTICATE
}

/// Get the `HeaderValue`.
pub fn value(&self) -> HeaderValue {
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()) }
}

/// Get the authorization scheme.
pub fn scheme(&self) -> AuthenticationScheme {
self.scheme
Expand All @@ -132,13 +114,16 @@ impl WwwAuthenticate {
}
}

impl crate::headers::Header for WwwAuthenticate {
impl Header for WwwAuthenticate {
fn header_name(&self) -> HeaderName {
WWW_AUTHENTICATE
}

fn header_value(&self) -> HeaderValue {
self.value()
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()) }
}
}

Expand All @@ -154,7 +139,7 @@ mod test {
let authz = WwwAuthenticate::new(scheme, realm.into());

let mut headers = Headers::new();
authz.apply(&mut headers);
authz.apply_header(&mut headers);

assert_eq!(
headers["WWW-Authenticate"],
Expand Down
39 changes: 8 additions & 31 deletions src/cache/age.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::headers::{HeaderName, HeaderValue, Headers, ToHeaderValues, AGE};
use crate::headers::{Header, HeaderName, HeaderValue, Headers, AGE};
use crate::Status;

use std::fmt::Debug;
use std::option;

use std::time::Duration;

/// HTTP `Age` header
Expand All @@ -22,7 +22,7 @@ use std::time::Duration;
/// let age = Age::from_secs(12);
///
/// let mut res = Response::new(200);
/// age.apply(&mut res);
/// res.insert_header(&age, &age);
///
/// let age = Age::from_headers(res)?.unwrap();
/// assert_eq!(age, Age::from_secs(12));
Expand Down Expand Up @@ -67,44 +67,21 @@ impl Age {

Ok(Some(Self { dur }))
}
}

/// Insert a `HeaderName` + `HeaderValue` pair into a `Headers` instance.
pub fn apply(&self, mut headers: impl AsMut<Headers>) {
headers.as_mut().insert(AGE, self.value());
}

/// Get the `HeaderName`.
pub fn name(&self) -> HeaderName {
impl Header for Age {
fn header_name(&self) -> HeaderName {
AGE
}

/// Get the `HeaderValue`.
pub fn value(&self) -> HeaderValue {
fn header_value(&self) -> HeaderValue {
let output = self.dur.as_secs().to_string();

// SAFETY: the internal string is validated to be ASCII.
unsafe { HeaderValue::from_bytes_unchecked(output.into()) }
}
}

impl ToHeaderValues for Age {
type Iter = option::IntoIter<HeaderValue>;
fn to_header_values(&self) -> crate::Result<Self::Iter> {
// A HeaderValue will always convert into itself.
Ok(self.value().to_header_values().unwrap())
}
}

impl crate::headers::Header for Age {
fn header_name(&self) -> HeaderName {
AGE
}

fn header_value(&self) -> HeaderValue {
self.value()
}
}

#[cfg(test)]
mod test {
use super::*;
Expand All @@ -115,7 +92,7 @@ mod test {
let age = Age::new(Duration::from_secs(12));

let mut headers = Headers::new();
age.apply(&mut headers);
age.apply_header(&mut headers);

let age = Age::from_headers(headers)?.unwrap();
assert_eq!(age, Age::new(Duration::from_secs(12)));
Expand Down
57 changes: 18 additions & 39 deletions src/cache/cache_control/cache_control.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::cache::CacheDirective;
use crate::headers::{HeaderName, HeaderValue, Headers, ToHeaderValues, CACHE_CONTROL};
use headers::Header;

use crate::headers::{HeaderName, HeaderValue, Headers, CACHE_CONTROL};
use crate::{cache::CacheDirective, headers};

use std::fmt::{self, Debug, Write};
use std::iter::Iterator;
use std::option;

use std::slice;

/// A Cache-Control header.
Expand All @@ -20,7 +22,7 @@ use std::slice;
/// entries.push(CacheDirective::NoStore);
///
/// let mut res = Response::new(200);
/// entries.apply(&mut res);
/// res.insert_header(&entries, &entries);
///
/// let entries = CacheControl::from_headers(res)?.unwrap();
/// let mut entries = entries.iter();
Expand Down Expand Up @@ -59,31 +61,6 @@ impl CacheControl {

Ok(Some(Self { entries }))
}

/// Sets the `Server-Timing` header.
pub fn apply(&self, mut headers: impl AsMut<Headers>) {
headers.as_mut().insert(CACHE_CONTROL, self.value());
}

/// Get the `HeaderName`.
pub fn name(&self) -> HeaderName {
CACHE_CONTROL
}

/// Get the `HeaderValue`.
pub fn value(&self) -> HeaderValue {
let mut output = String::new();
for (n, directive) in self.entries.iter().enumerate() {
let directive: HeaderValue = directive.clone().into();
match n {
0 => write!(output, "{}", directive).unwrap(),
_ => write!(output, ", {}", directive).unwrap(),
};
}

// SAFETY: the internal string is validated to be ASCII.
unsafe { HeaderValue::from_bytes_unchecked(output.into()) }
}
/// Push a directive into the list of entries.
pub fn push(&mut self, directive: CacheDirective) {
self.entries.push(directive);
Expand All @@ -104,12 +81,22 @@ impl CacheControl {
}
}

impl crate::headers::Header for CacheControl {
impl Header for CacheControl {
fn header_name(&self) -> HeaderName {
CACHE_CONTROL
}
fn header_value(&self) -> HeaderValue {
self.value()
let mut output = String::new();
for (n, directive) in self.entries.iter().enumerate() {
let directive: HeaderValue = directive.clone().into();
match n {
0 => write!(output, "{}", directive).unwrap(),
_ => write!(output, ", {}", directive).unwrap(),
};
}

// SAFETY: the internal string is validated to be ASCII.
unsafe { HeaderValue::from_bytes_unchecked(output.into()) }
}
}

Expand Down Expand Up @@ -202,14 +189,6 @@ impl<'a> Iterator for IterMut<'a> {
}
}

impl ToHeaderValues for CacheControl {
type Iter = option::IntoIter<HeaderValue>;
fn to_header_values(&self) -> crate::Result<Self::Iter> {
// A HeaderValue will always convert into itself.
Ok(self.value().to_header_values().unwrap())
}
}

impl Debug for CacheControl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut list = f.debug_list();
Expand Down
4 changes: 2 additions & 2 deletions src/cache/cache_control/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use cache_directive::CacheDirective;
#[cfg(test)]
mod test {
use super::*;
use crate::headers::{Headers, CACHE_CONTROL};
use crate::headers::{Header, Headers, CACHE_CONTROL};

#[test]
fn smoke() -> crate::Result<()> {
Expand All @@ -25,7 +25,7 @@ mod test {
entries.push(CacheDirective::NoStore);

let mut headers = Headers::new();
entries.apply(&mut headers);
entries.apply_header(&mut headers);

let entries = CacheControl::from_headers(headers)?.unwrap();
let mut entries = entries.iter();
Expand Down
Loading