Bug 1852173 - Update headers to 0.3.9. r=emilio,supply-chain-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D187732
This commit is contained in:
Mike Hommey 2023-09-10 22:26:07 +00:00
parent e8f5539bb1
commit 1b9fc418a6
16 changed files with 139 additions and 71 deletions

7
Cargo.lock generated
View File

@ -2446,12 +2446,11 @@ dependencies = [
[[package]]
name = "headers"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584"
checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270"
dependencies = [
"base64 0.13.999",
"bitflags 1.3.2",
"base64 0.21.3",
"bytes",
"headers-core",
"http",

View File

@ -246,6 +246,13 @@ user-id = 359
user-login = "seanmonstar"
user-name = "Sean McArthur"
[[publisher.headers]]
version = "0.3.9"
when = "2023-08-31"
user-id = 359
user-login = "seanmonstar"
user-name = "Sean McArthur"
[[publisher.httparse]]
version = "1.8.0"
when = "2022-08-30"

File diff suppressed because one or more lines are too long

View File

@ -10,8 +10,9 @@
# See Cargo.toml.orig for the original contents.
[package]
rust-version = "1.56"
name = "headers"
version = "0.3.8"
version = "0.3.9"
authors = ["Sean McArthur <sean@seanmonstar.com>"]
description = "typed HTTP headers"
homepage = "https://hyper.rs"
@ -27,10 +28,7 @@ license = "MIT"
repository = "https://github.com/hyperium/headers"
[dependencies.base64]
version = "0.13"
[dependencies.bitflags]
version = "1.0"
version = "0.21.3"
[dependencies.bytes]
version = "1"

View File

@ -1,6 +1,7 @@
//! Authorization header and types.
use base64;
use base64::engine::general_purpose::STANDARD as ENGINE;
use base64::Engine;
use bytes::Bytes;
use util::HeaderValueString;
@ -94,7 +95,8 @@ impl<C: Credentials> ::Header for Authorization<C> {
}
fn encode<E: Extend<::HeaderValue>>(&self, values: &mut E) {
let value = self.0.encode();
let mut value = self.0.encode();
value.set_sensitive(true);
debug_assert!(
value.as_bytes().starts_with(C::SCHEME.as_bytes()),
"Credentials::encode should include its scheme: scheme = {:?}, encoded = {:?}",
@ -157,7 +159,8 @@ impl Credentials for Basic {
let bytes = &value.as_bytes()["Basic ".len()..];
let non_space_pos = bytes.iter().position(|b| *b != b' ')?;
let bytes = &bytes[non_space_pos..];
let bytes = base64::decode(bytes).ok()?;
let bytes = ENGINE.decode(bytes).ok()?;
let decoded = String::from_utf8(bytes).ok()?;
@ -168,10 +171,11 @@ impl Credentials for Basic {
fn encode(&self) -> HeaderValue {
let mut encoded = String::from("Basic ");
base64::encode_config_buf(&self.decoded, base64::STANDARD, &mut encoded);
ENGINE.encode_string(&self.decoded, &mut encoded);
let bytes = Bytes::from(encoded);
HeaderValue::from_maybe_shared(bytes).expect("base64 encoding is always a valid HeaderValue")
HeaderValue::from_maybe_shared(bytes)
.expect("base64 encoding is always a valid HeaderValue")
}
}

View File

@ -7,6 +7,7 @@ use util::{self, csv, Seconds};
use HeaderValue;
/// `Cache-Control` header, defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2)
/// with extensions in [RFC8246](https://www.rfc-editor.org/rfc/rfc8246)
///
/// The `Cache-Control` header field is used to specify directives for
/// caches along the request/response chain. Such cache directives are
@ -43,16 +44,32 @@ pub struct CacheControl {
s_max_age: Option<Seconds>,
}
bitflags! {
struct Flags: u32 {
const NO_CACHE = 0b00000001;
const NO_STORE = 0b00000010;
const NO_TRANSFORM = 0b00000100;
const ONLY_IF_CACHED = 0b00001000;
const MUST_REVALIDATE = 0b00010000;
const PUBLIC = 0b00100000;
const PRIVATE = 0b01000000;
const PROXY_REVALIDATE = 0b10000000;
#[derive(Debug, Clone, PartialEq)]
struct Flags {
bits: u64,
}
impl Flags {
const NO_CACHE: Self = Self { bits: 0b000000001 };
const NO_STORE: Self = Self { bits: 0b000000010 };
const NO_TRANSFORM: Self = Self { bits: 0b000000100 };
const ONLY_IF_CACHED: Self = Self { bits: 0b000001000 };
const MUST_REVALIDATE: Self = Self { bits: 0b000010000 };
const PUBLIC: Self = Self { bits: 0b000100000 };
const PRIVATE: Self = Self { bits: 0b001000000 };
const PROXY_REVALIDATE: Self = Self { bits: 0b010000000 };
const IMMUTABLE: Self = Self { bits: 0b100000000 };
fn empty() -> Self {
Self { bits: 0 }
}
fn contains(&self, flag: Self) -> bool {
(self.bits & flag.bits) != 0
}
fn insert(&mut self, flag: Self) {
self.bits |= flag.bits;
}
}
@ -100,6 +117,11 @@ impl CacheControl {
self.flags.contains(Flags::PRIVATE)
}
/// Check if the `immutable` directive is set.
pub fn immutable(&self) -> bool {
self.flags.contains(Flags::IMMUTABLE)
}
/// Get the value of the `max-age` directive if set.
pub fn max_age(&self) -> Option<Duration> {
self.max_age.map(Into::into)
@ -158,27 +180,33 @@ impl CacheControl {
self
}
/// Set the `immutable` directive.
pub fn with_immutable(mut self) -> Self {
self.flags.insert(Flags::IMMUTABLE);
self
}
/// Set the `max-age` directive.
pub fn with_max_age(mut self, seconds: Duration) -> Self {
self.max_age = Some(seconds.into());
pub fn with_max_age(mut self, duration: Duration) -> Self {
self.max_age = Some(duration.into());
self
}
/// Set the `max-stale` directive.
pub fn with_max_stale(mut self, seconds: Duration) -> Self {
self.max_stale = Some(seconds.into());
pub fn with_max_stale(mut self, duration: Duration) -> Self {
self.max_stale = Some(duration.into());
self
}
/// Set the `min-fresh` directive.
pub fn with_min_fresh(mut self, seconds: Duration) -> Self {
self.min_fresh = Some(seconds.into());
pub fn with_min_fresh(mut self, duration: Duration) -> Self {
self.min_fresh = Some(duration.into());
self
}
/// Set the `s-maxage` directive.
pub fn with_s_max_age(mut self, seconds: Duration) -> Self {
self.s_max_age = Some(seconds.into());
pub fn with_s_max_age(mut self, duration: Duration) -> Self {
self.s_max_age = Some(duration.into());
self
}
}
@ -236,6 +264,9 @@ impl FromIterator<KnownDirective> for FromIter {
Directive::Private => {
cc.flags.insert(Flags::PRIVATE);
}
Directive::Immutable => {
cc.flags.insert(Flags::IMMUTABLE);
}
Directive::ProxyRevalidate => {
cc.flags.insert(Flags::PROXY_REVALIDATE);
}
@ -278,6 +309,7 @@ impl<'a> fmt::Display for Fmt<'a> {
if_flag(Flags::MUST_REVALIDATE, Directive::MustRevalidate),
if_flag(Flags::PUBLIC, Directive::Public),
if_flag(Flags::PRIVATE, Directive::Private),
if_flag(Flags::IMMUTABLE, Directive::Immutable),
if_flag(Flags::PROXY_REVALIDATE, Directive::ProxyRevalidate),
self.0
.max_age
@ -325,6 +357,7 @@ enum Directive {
MustRevalidate,
Public,
Private,
Immutable,
ProxyRevalidate,
SMaxAge(u64),
}
@ -345,6 +378,7 @@ impl fmt::Display for Directive {
Directive::MustRevalidate => "must-revalidate",
Directive::Public => "public",
Directive::Private => "private",
Directive::Immutable => "immutable",
Directive::ProxyRevalidate => "proxy-revalidate",
Directive::SMaxAge(secs) => return write!(f, "s-maxage={}", secs),
},
@ -364,6 +398,7 @@ impl FromStr for KnownDirective {
"must-revalidate" => Directive::MustRevalidate,
"public" => Directive::Public,
"private" => Directive::Private,
"immutable" => Directive::Immutable,
"proxy-revalidate" => Directive::ProxyRevalidate,
"" => return Err(()),
_ => match s.find('=') {
@ -428,9 +463,18 @@ mod tests {
);
}
#[test]
fn test_immutable() {
let cc = CacheControl::new().with_immutable();
let headers = test_encode(cc.clone());
assert_eq!(headers["cache-control"], "immutable");
assert_eq!(test_decode::<CacheControl>(&["immutable"]).unwrap(), cc);
assert!(cc.immutable());
}
#[test]
fn test_parse_bad_syntax() {
assert_eq!(test_decode::<CacheControl>(&["max-age=lolz"]), None,);
assert_eq!(test_decode::<CacheControl>(&["max-age=lolz"]), None);
}
#[test]

View File

@ -178,22 +178,23 @@ fn split_in_two(s: &str, separator: char) -> Option<(&str, &str)> {
}
/*
test_header!(test_bytes,
vec![b"bytes 0-499/500"],
Some(ContentRange(ContentRangeSpec::Bytes {
range: Some((0, 499)),
complete_length: Some(500)
})));
test_header!(test_bytes,
vec![b"bytes 0-499/500"],
Some(ContentRange(ContentRangeSpec::Bytes {
range: Some((0, 499)),
complete_length: Some(500)
})));
test_header!(test_bytes_unknown_len,
vec![b"bytes 0-499/*"],
Some(ContentRange(ContentRangeSpec::Bytes {
range: Some((0, 499)),
complete_length: None
})));
test_header!(test_bytes_unknown_len,
vec![b"bytes 0-499/*"],
Some(ContentRange(ContentRangeSpec::Bytes {
range: Some((0, 499)),
complete_length: None
})));
test_header!(test_bytes_unknown_range,
vec![b"bytes */500"],
test_header!(test_bytes_unknown_range,
vec![b"bytes */
500"],
Some(ContentRange(ContentRangeSpec::Bytes {
range: None,
complete_length: Some(500)

View File

@ -135,6 +135,16 @@ impl fmt::Display for ContentType {
}
}
impl std::str::FromStr for ContentType {
type Err = ::Error;
fn from_str(s: &str) -> Result<ContentType, Self::Err> {
s.parse::<Mime>()
.map(|m| m.into())
.map_err(|_| ::Error::invalid())
}
}
#[cfg(test)]
mod tests {
use super::super::test_decode;
@ -148,6 +158,15 @@ mod tests {
);
}
#[test]
fn from_str() {
assert_eq!(
"application/json".parse::<ContentType>().unwrap(),
ContentType::json(),
);
assert!("invalid-mimetype".parse::<ContentType>().is_err());
}
bench_header!(bench_plain, ContentType, "text/plain");
bench_header!(bench_json, ContentType, "application/json");
bench_header!(

View File

@ -50,9 +50,7 @@ error_type!(InvalidETag);
impl FromStr for ETag {
type Err = InvalidETag;
fn from_str(src: &str) -> Result<Self, Self::Err> {
let val = src
.parse()
.map_err(|_| InvalidETag { _inner: () })?;
let val = src.parse().map_err(|_| InvalidETag { _inner: () })?;
EntityTag::from_owned(val)
.map(ETag)

View File

@ -1,5 +1,5 @@
use std::fmt;
use std::convert::TryFrom;
use std::fmt;
use http::uri::Authority;

View File

@ -64,7 +64,9 @@ impl IfRange {
pub fn is_modified(&self, etag: Option<&ETag>, last_modified: Option<&LastModified>) -> bool {
match self.0 {
IfRange_::Date(since) => last_modified.map(|time| since < time.0).unwrap_or(true),
IfRange_::EntityTag(ref entity) => etag.map(|etag| !etag.0.strong_eq(entity)).unwrap_or(true),
IfRange_::EntityTag(ref entity) => {
etag.map(|etag| !etag.0.strong_eq(entity)).unwrap_or(true)
}
}
}
}

View File

@ -1,5 +1,5 @@
use std::fmt;
use std::convert::TryFrom;
use std::fmt;
use bytes::Bytes;
use http::uri::{self, Authority, Scheme, Uri};

View File

@ -1,4 +1,5 @@
use base64;
use base64::engine::general_purpose::STANDARD as ENGINE;
use base64::Engine;
use bytes::Bytes;
use sha1::{Digest, Sha1};
@ -39,7 +40,7 @@ fn sign(key: &[u8]) -> SecWebsocketAccept {
let mut sha1 = Sha1::default();
sha1.update(key);
sha1.update(&b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"[..]);
let b64 = Bytes::from(base64::encode(&sha1.finalize()));
let b64 = Bytes::from(ENGINE.encode(&sha1.finalize()));
let val = ::HeaderValue::from_maybe_shared(b64).expect("base64 is a valid value");

View File

@ -2,7 +2,7 @@
#![deny(missing_debug_implementations)]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(all(test, feature = "nightly"), feature(test))]
#![doc(html_root_url = "https://docs.rs/headers/0.3.8")]
#![doc(html_root_url = "https://docs.rs/headers/0.3.9")]
//! # Typed HTTP Headers
//!
@ -73,8 +73,6 @@
//! ```
extern crate base64;
#[macro_use]
extern crate bitflags;
extern crate bytes;
extern crate headers_core;
extern crate http;

View File

@ -167,9 +167,7 @@ impl EntityTag {
}
pub(crate) fn from_val(val: &HeaderValue) -> Option<EntityTag> {
EntityTag::parse(val.as_bytes()).map(|_entity| {
EntityTag(val.clone())
})
EntityTag::parse(val.as_bytes()).map(|_entity| EntityTag(val.clone()))
}
}
@ -239,11 +237,10 @@ impl EntityTagRange {
{
match *self {
EntityTagRange::Any => true,
EntityTagRange::Tags(ref tags) => {
tags.iter()
.flat_map(EntityTag::<&str>::parse)
.any(|tag| func(&tag, entity))
},
EntityTagRange::Tags(ref tags) => tags
.iter()
.flat_map(EntityTag::<&str>::parse)
.any(|tag| func(&tag, entity)),
}
}
}

View File

@ -120,8 +120,8 @@ impl<'a, Sep: Separator> FromIterator<&'a HeaderValue> for FlatCsv<Sep> {
buf.extend_from_slice(val.as_bytes());
}
let val =
HeaderValue::from_maybe_shared(buf.freeze()).expect("comma separated HeaderValues are valid");
let val = HeaderValue::from_maybe_shared(buf.freeze())
.expect("comma separated HeaderValues are valid");
val.into()
}
@ -151,8 +151,8 @@ impl<Sep: Separator> FromIterator<HeaderValue> for FlatCsv<Sep> {
buf.extend_from_slice(val.as_bytes());
}
let val =
HeaderValue::from_maybe_shared(buf.freeze()).expect("comma separated HeaderValues are valid");
let val = HeaderValue::from_maybe_shared(buf.freeze())
.expect("comma separated HeaderValues are valid");
val.into()
}