Skip to content

Commit 11f96bd

Browse files
committed
Merge branch 'master' into headers_encoding
2 parents f36805e + 0f78ab3 commit 11f96bd

File tree

10 files changed

+107
-52
lines changed

10 files changed

+107
-52
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
toolchain: ${{ matrix.rust }}
2222
profile: minimal
2323
override: true
24+
components: rustfmt
2425

2526
- name: cargo test --all
2627
uses: actions-rs/cargo@v1
@@ -41,6 +42,12 @@ jobs:
4142
cargo update -Z minimal-versions
4243
cargo check
4344
45+
- name: cargo fmt --check
46+
uses: actions-rs/cargo@v1
47+
with:
48+
command: fmt
49+
args: --all -- --check
50+
4451
MSRV:
4552
runs-on: ubuntu-latest
4653

src/common/authorization.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ impl<C: Credentials> ::Header for Authorization<C> {
9494
}
9595

9696
fn encode<E: Extend<::HeaderValue>>(&self, values: &mut E) {
97-
let value = self.0.encode();
97+
let mut value = self.0.encode();
98+
value.set_sensitive(true);
9899
debug_assert!(
99100
value.as_bytes().starts_with(C::SCHEME.as_bytes()),
100101
"Credentials::encode should include its scheme: scheme = {:?}, encoded = {:?}",
@@ -171,7 +172,8 @@ impl Credentials for Basic {
171172
base64::encode_config_buf(&self.decoded, base64::STANDARD, &mut encoded);
172173

173174
let bytes = Bytes::from(encoded);
174-
HeaderValue::from_maybe_shared(bytes).expect("base64 encoding is always a valid HeaderValue")
175+
HeaderValue::from_maybe_shared(bytes)
176+
.expect("base64 encoding is always a valid HeaderValue")
175177
}
176178
}
177179

src/common/cache_control.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use util::{self, csv, Seconds};
77
use HeaderValue;
88

99
/// `Cache-Control` header, defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2)
10+
/// with extensions in [RFC8246](https://www.rfc-editor.org/rfc/rfc8246)
1011
///
1112
/// The `Cache-Control` header field is used to specify directives for
1213
/// caches along the request/response chain. Such cache directives are
@@ -45,14 +46,15 @@ pub struct CacheControl {
4546

4647
bitflags! {
4748
struct Flags: u32 {
48-
const NO_CACHE = 0b00000001;
49-
const NO_STORE = 0b00000010;
50-
const NO_TRANSFORM = 0b00000100;
51-
const ONLY_IF_CACHED = 0b00001000;
52-
const MUST_REVALIDATE = 0b00010000;
53-
const PUBLIC = 0b00100000;
54-
const PRIVATE = 0b01000000;
55-
const PROXY_REVALIDATE = 0b10000000;
49+
const NO_CACHE = 0b000000001;
50+
const NO_STORE = 0b000000010;
51+
const NO_TRANSFORM = 0b000000100;
52+
const ONLY_IF_CACHED = 0b000001000;
53+
const MUST_REVALIDATE = 0b000010000;
54+
const PUBLIC = 0b000100000;
55+
const PRIVATE = 0b001000000;
56+
const PROXY_REVALIDATE = 0b010000000;
57+
const IMMUTABLE = 0b100000000;
5658
}
5759
}
5860

@@ -100,6 +102,11 @@ impl CacheControl {
100102
self.flags.contains(Flags::PRIVATE)
101103
}
102104

105+
/// Check if the `immutable` directive is set.
106+
pub fn immutable(&self) -> bool {
107+
self.flags.contains(Flags::IMMUTABLE)
108+
}
109+
103110
/// Get the value of the `max-age` directive if set.
104111
pub fn max_age(&self) -> Option<Duration> {
105112
self.max_age.map(Into::into)
@@ -158,27 +165,33 @@ impl CacheControl {
158165
self
159166
}
160167

168+
/// Set the `immutable` directive.
169+
pub fn with_immutable(mut self) -> Self {
170+
self.flags.insert(Flags::IMMUTABLE);
171+
self
172+
}
173+
161174
/// Set the `max-age` directive.
162-
pub fn with_max_age(mut self, seconds: Duration) -> Self {
163-
self.max_age = Some(seconds.into());
175+
pub fn with_max_age(mut self, duration: Duration) -> Self {
176+
self.max_age = Some(duration.into());
164177
self
165178
}
166179

167180
/// Set the `max-stale` directive.
168-
pub fn with_max_stale(mut self, seconds: Duration) -> Self {
169-
self.max_stale = Some(seconds.into());
181+
pub fn with_max_stale(mut self, duration: Duration) -> Self {
182+
self.max_stale = Some(duration.into());
170183
self
171184
}
172185

173186
/// Set the `min-fresh` directive.
174-
pub fn with_min_fresh(mut self, seconds: Duration) -> Self {
175-
self.min_fresh = Some(seconds.into());
187+
pub fn with_min_fresh(mut self, duration: Duration) -> Self {
188+
self.min_fresh = Some(duration.into());
176189
self
177190
}
178191

179192
/// Set the `s-maxage` directive.
180-
pub fn with_s_max_age(mut self, seconds: Duration) -> Self {
181-
self.s_max_age = Some(seconds.into());
193+
pub fn with_s_max_age(mut self, duration: Duration) -> Self {
194+
self.s_max_age = Some(duration.into());
182195
self
183196
}
184197
}
@@ -236,6 +249,9 @@ impl FromIterator<KnownDirective> for FromIter {
236249
Directive::Private => {
237250
cc.flags.insert(Flags::PRIVATE);
238251
}
252+
Directive::Immutable => {
253+
cc.flags.insert(Flags::IMMUTABLE);
254+
}
239255
Directive::ProxyRevalidate => {
240256
cc.flags.insert(Flags::PROXY_REVALIDATE);
241257
}
@@ -278,6 +294,7 @@ impl<'a> fmt::Display for Fmt<'a> {
278294
if_flag(Flags::MUST_REVALIDATE, Directive::MustRevalidate),
279295
if_flag(Flags::PUBLIC, Directive::Public),
280296
if_flag(Flags::PRIVATE, Directive::Private),
297+
if_flag(Flags::IMMUTABLE, Directive::Immutable),
281298
if_flag(Flags::PROXY_REVALIDATE, Directive::ProxyRevalidate),
282299
self.0
283300
.max_age
@@ -325,6 +342,7 @@ enum Directive {
325342
MustRevalidate,
326343
Public,
327344
Private,
345+
Immutable,
328346
ProxyRevalidate,
329347
SMaxAge(u64),
330348
}
@@ -345,6 +363,7 @@ impl fmt::Display for Directive {
345363
Directive::MustRevalidate => "must-revalidate",
346364
Directive::Public => "public",
347365
Directive::Private => "private",
366+
Directive::Immutable => "immutable",
348367
Directive::ProxyRevalidate => "proxy-revalidate",
349368
Directive::SMaxAge(secs) => return write!(f, "s-maxage={}", secs),
350369
},
@@ -364,6 +383,7 @@ impl FromStr for KnownDirective {
364383
"must-revalidate" => Directive::MustRevalidate,
365384
"public" => Directive::Public,
366385
"private" => Directive::Private,
386+
"immutable" => Directive::Immutable,
367387
"proxy-revalidate" => Directive::ProxyRevalidate,
368388
"" => return Err(()),
369389
_ => match s.find('=') {
@@ -428,9 +448,18 @@ mod tests {
428448
);
429449
}
430450

451+
#[test]
452+
fn test_immutable() {
453+
let cc = CacheControl::new().with_immutable();
454+
let headers = test_encode(cc.clone());
455+
assert_eq!(headers["cache-control"], "immutable");
456+
assert_eq!(test_decode::<CacheControl>(&["immutable"]).unwrap(), cc);
457+
assert!(cc.immutable());
458+
}
459+
431460
#[test]
432461
fn test_parse_bad_syntax() {
433-
assert_eq!(test_decode::<CacheControl>(&["max-age=lolz"]), None,);
462+
assert_eq!(test_decode::<CacheControl>(&["max-age=lolz"]), None);
434463
}
435464

436465
#[test]

src/common/content_range.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -178,22 +178,23 @@ fn split_in_two(s: &str, separator: char) -> Option<(&str, &str)> {
178178
}
179179

180180
/*
181-
test_header!(test_bytes,
182-
vec![b"bytes 0-499/500"],
183-
Some(ContentRange(ContentRangeSpec::Bytes {
184-
range: Some((0, 499)),
185-
complete_length: Some(500)
186-
})));
187-
188-
test_header!(test_bytes_unknown_len,
189-
vec![b"bytes 0-499/*"],
190-
Some(ContentRange(ContentRangeSpec::Bytes {
191-
range: Some((0, 499)),
192-
complete_length: None
193-
})));
194-
195-
test_header!(test_bytes_unknown_range,
196-
vec![b"bytes */500"],
181+
test_header!(test_bytes,
182+
vec![b"bytes 0-499/500"],
183+
Some(ContentRange(ContentRangeSpec::Bytes {
184+
range: Some((0, 499)),
185+
complete_length: Some(500)
186+
})));
187+
188+
test_header!(test_bytes_unknown_len,
189+
vec![b"bytes 0-499/*"],
190+
Some(ContentRange(ContentRangeSpec::Bytes {
191+
range: Some((0, 499)),
192+
complete_length: None
193+
})));
194+
195+
test_header!(test_bytes_unknown_range,
196+
vec![b"bytes */
197+
500"],
197198
Some(ContentRange(ContentRangeSpec::Bytes {
198199
range: None,
199200
complete_length: Some(500)

src/common/content_type.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ impl fmt::Display for ContentType {
135135
}
136136
}
137137

138+
impl std::str::FromStr for ContentType {
139+
type Err = ::Error;
140+
141+
fn from_str(s: &str) -> Result<ContentType, Self::Err> {
142+
s.parse::<Mime>()
143+
.map(|m| m.into())
144+
.map_err(|_| ::Error::invalid())
145+
}
146+
}
147+
138148
#[cfg(test)]
139149
mod tests {
140150
use super::super::test_decode;
@@ -148,6 +158,15 @@ mod tests {
148158
);
149159
}
150160

161+
#[test]
162+
fn from_str() {
163+
assert_eq!(
164+
"application/json".parse::<ContentType>().unwrap(),
165+
ContentType::json(),
166+
);
167+
assert!("invalid-mimetype".parse::<ContentType>().is_err());
168+
}
169+
151170
bench_header!(bench_plain, ContentType, "text/plain");
152171
bench_header!(bench_json, ContentType, "application/json");
153172
bench_header!(

src/common/etag.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ error_type!(InvalidETag);
5050
impl FromStr for ETag {
5151
type Err = InvalidETag;
5252
fn from_str(src: &str) -> Result<Self, Self::Err> {
53-
let val = src
54-
.parse()
55-
.map_err(|_| InvalidETag { _inner: () })?;
53+
let val = src.parse().map_err(|_| InvalidETag { _inner: () })?;
5654

5755
EntityTag::from_owned(val)
5856
.map(ETag)

src/common/host.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use std::fmt;
21
use std::convert::TryFrom;
2+
use std::fmt;
33

44
use http::uri::Authority;
55

src/common/if_range.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ impl IfRange {
6464
pub fn is_modified(&self, etag: Option<&ETag>, last_modified: Option<&LastModified>) -> bool {
6565
match self.0 {
6666
IfRange_::Date(since) => last_modified.map(|time| since < time.0).unwrap_or(true),
67-
IfRange_::EntityTag(ref entity) => etag.map(|etag| !etag.0.strong_eq(entity)).unwrap_or(true),
67+
IfRange_::EntityTag(ref entity) => {
68+
etag.map(|etag| !etag.0.strong_eq(entity)).unwrap_or(true)
69+
}
6870
}
6971
}
7072
}

src/util/entity.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,7 @@ impl EntityTag {
167167
}
168168

169169
pub(crate) fn from_val(val: &HeaderValue) -> Option<EntityTag> {
170-
EntityTag::parse(val.as_bytes()).map(|_entity| {
171-
EntityTag(val.clone())
172-
})
170+
EntityTag::parse(val.as_bytes()).map(|_entity| EntityTag(val.clone()))
173171
}
174172
}
175173

@@ -239,11 +237,10 @@ impl EntityTagRange {
239237
{
240238
match *self {
241239
EntityTagRange::Any => true,
242-
EntityTagRange::Tags(ref tags) => {
243-
tags.iter()
244-
.flat_map(EntityTag::<&str>::parse)
245-
.any(|tag| func(&tag, entity))
246-
},
240+
EntityTagRange::Tags(ref tags) => tags
241+
.iter()
242+
.flat_map(EntityTag::<&str>::parse)
243+
.any(|tag| func(&tag, entity)),
247244
}
248245
}
249246
}

src/util/flat_csv.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ impl<'a, Sep: Separator> FromIterator<&'a HeaderValue> for FlatCsv<Sep> {
120120
buf.extend_from_slice(val.as_bytes());
121121
}
122122

123-
let val =
124-
HeaderValue::from_maybe_shared(buf.freeze()).expect("comma separated HeaderValues are valid");
123+
let val = HeaderValue::from_maybe_shared(buf.freeze())
124+
.expect("comma separated HeaderValues are valid");
125125

126126
val.into()
127127
}
@@ -151,8 +151,8 @@ impl<Sep: Separator> FromIterator<HeaderValue> for FlatCsv<Sep> {
151151
buf.extend_from_slice(val.as_bytes());
152152
}
153153

154-
let val =
155-
HeaderValue::from_maybe_shared(buf.freeze()).expect("comma separated HeaderValues are valid");
154+
let val = HeaderValue::from_maybe_shared(buf.freeze())
155+
.expect("comma separated HeaderValues are valid");
156156

157157
val.into()
158158
}

0 commit comments

Comments
 (0)