Skip to content

Commit 8e23418

Browse files
committed
fix cache-control bugs & polish
1 parent 93c3f4c commit 8e23418

File tree

4 files changed

+59
-8
lines changed

4 files changed

+59
-8
lines changed

src/cache/cache_control/cache_control.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ use std::option;
77
use std::slice;
88

99
/// A Cache-Control header.
10+
///
11+
/// # Examples
12+
///
13+
/// ```
14+
/// # fn main() -> http_types::Result<()> {
15+
/// #
16+
/// use http_types::Response;
17+
/// use http_types::cache::{CacheControl, CacheDirective};
18+
/// let mut entries = CacheControl::new();
19+
/// entries.push(CacheDirective::Immutable);
20+
/// entries.push(CacheDirective::NoStore);
21+
///
22+
/// let mut res = Response::new(200);
23+
/// entries.apply(&mut res);
24+
///
25+
/// let entries = CacheControl::from_headers(res)?.unwrap();
26+
/// let mut entries = entries.iter();
27+
/// assert_eq!(entries.next().unwrap(), &CacheDirective::Immutable);
28+
/// assert_eq!(entries.next().unwrap(), &CacheDirective::NoStore);
29+
/// #
30+
/// # Ok(()) }
31+
/// ```
1032
pub struct CacheControl {
1133
entries: Vec<CacheDirective>,
1234
}
@@ -29,13 +51,12 @@ impl CacheControl {
2951
for part in value.as_str().trim().split(',') {
3052
// Try and parse a directive from a str. If the directive is
3153
// unkown we skip it.
32-
let s = part.trim_start();
33-
s.to_lowercase();
34-
if let Some(entry) = CacheDirective::from_str(s)? {
54+
if let Some(entry) = CacheDirective::from_str(part)? {
3555
entries.push(entry);
3656
}
3757
}
3858
}
59+
3960
Ok(Some(Self { entries }))
4061
}
4162

src/cache/cache_control/cache_directive.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::Status;
44
use std::time::Duration;
55

66
/// An HTTP `Cache-Control` directive.
7+
#[non_exhaustive]
78
#[derive(Debug, Clone, PartialEq, Eq)]
89
pub enum CacheDirective {
910
/// The response body will not change over time.
@@ -76,6 +77,15 @@ impl CacheDirective {
7677
// sense.
7778
pub(crate) fn from_str(s: &str) -> crate::Result<Option<Self>> {
7879
use CacheDirective::*;
80+
81+
let s = s.trim();
82+
83+
// We're dealing with an empty string.
84+
if s.is_empty() {
85+
return Ok(None);
86+
}
87+
88+
s.to_lowercase();
7989
let mut parts = s.split('=');
8090
let next = parts.next().unwrap().clone();
8191

@@ -104,9 +114,10 @@ impl CacheDirective {
104114
}
105115
None => Some(MaxStale(None)),
106116
},
107-
"min-fresh=<seconds>" => Some(MinFresh(get_dur()?)),
108-
"max-age=<seconds>" => Some(MaxAge(get_dur()?)),
109-
"s-maxage=<seconds>" => Some(SMaxAge(get_dur()?)),
117+
"min-fresh" => Some(MinFresh(get_dur()?)),
118+
"s-maxage" => Some(SMaxAge(get_dur()?)),
119+
"stale-if-error" => Some(StaleIfError(get_dur()?)),
120+
"stale-while-revalidate" => Some(StaleWhileRevalidate(get_dur()?)),
110121
_ => None,
111122
};
112123
Ok(res)

src/cache/cache_control/mod.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use cache_directive::CacheDirective;
1515
#[cfg(test)]
1616
mod test {
1717
use super::*;
18-
use crate::headers::Headers;
18+
use crate::headers::{Headers, CACHE_CONTROL};
1919

2020
#[test]
2121
fn smoke() -> crate::Result<()> {
@@ -32,4 +32,23 @@ mod test {
3232
assert_eq!(entries.next().unwrap(), &CacheDirective::NoStore);
3333
Ok(())
3434
}
35+
36+
#[test]
37+
fn ignore_unkonwn_directives() -> crate::Result<()> {
38+
let mut headers = Headers::new();
39+
headers.insert(CACHE_CONTROL, "barrel_roll");
40+
let entries = CacheControl::from_headers(headers)?.unwrap();
41+
let mut entries = entries.iter();
42+
assert!(entries.next().is_none());
43+
Ok(())
44+
}
45+
46+
#[test]
47+
fn bad_request_on_parse_error() -> crate::Result<()> {
48+
let mut headers = Headers::new();
49+
headers.insert(CACHE_CONTROL, "min-fresh=0.9"); // floats are not supported
50+
let err = CacheControl::from_headers(headers).unwrap_err();
51+
assert_eq!(err.status(), 400);
52+
Ok(())
53+
}
3554
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
#![deny(missing_debug_implementations, nonstandard_style)]
9797
#![warn(missing_docs, unreachable_pub)]
9898
#![allow(clippy::new_without_default)]
99-
// #![cfg_attr(test, deny(warnings))]
99+
#![cfg_attr(test, deny(warnings))]
100100
#![cfg_attr(feature = "docs", feature(doc_cfg))]
101101
#![doc(html_favicon_url = "https://yoshuawuyts.com/assets/http-rs/favicon.ico")]
102102
#![doc(html_logo_url = "https://yoshuawuyts.com/assets/http-rs/logo-rounded.png")]

0 commit comments

Comments
 (0)