Skip to content

Commit 2d6c881

Browse files
committed
Merge pull request #193 from wenderen/vary-header
add vary header, first draft
2 parents 9e99c57 + 258e739 commit 2d6c881

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

src/header/common/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub use self::location::Location;
2424
pub use self::transfer_encoding::TransferEncoding;
2525
pub use self::upgrade::Upgrade;
2626
pub use self::user_agent::UserAgent;
27+
pub use self::vary::Vary;
2728
pub use self::server::Server;
2829
pub use self::set_cookie::SetCookie;
2930

@@ -132,4 +133,7 @@ pub mod upgrade;
132133
/// Exposes the UserAgent header.
133134
pub mod user_agent;
134135

136+
/// Exposes the Vary header.
137+
pub mod vary;
138+
135139
pub mod util;

src/header/common/vary.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use header::{Header, HeaderFormat, CaseInsensitive};
2+
use std::fmt::{mod};
3+
use super::util::{from_comma_delimited, fmt_comma_delimited, from_one_raw_str};
4+
5+
/// The `Allow` header.
6+
/// See also https://tools.ietf.org/html/rfc7231#section-7.1.4
7+
8+
#[deriving(Clone, PartialEq, Show)]
9+
pub enum Vary {
10+
/// This corresponds to '*'.
11+
Any,
12+
/// The header field names which will influence the response representation.
13+
Headers(Vec<CaseInsensitive>),
14+
}
15+
16+
impl Header for Vary {
17+
fn header_name(_: Option<Vary>) -> &'static str {
18+
"Vary"
19+
}
20+
21+
fn parse_header(raw: &[Vec<u8>]) -> Option<Vary> {
22+
from_one_raw_str(raw).and_then(|s: String| {
23+
let slice = s[];
24+
match slice {
25+
"" => None,
26+
"*" => Some(Vary::Any),
27+
_ => from_comma_delimited(raw).map(|vec| Vary::Headers(vec)),
28+
}
29+
})
30+
}
31+
}
32+
33+
impl HeaderFormat for Vary {
34+
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
35+
match *self {
36+
Vary::Any => { write!(fmt, "*") }
37+
Vary::Headers(ref fields) => { fmt_comma_delimited(fmt, fields[]) }
38+
}
39+
}
40+
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
use super::Vary;
45+
use header::{Header, CaseInsensitive};
46+
47+
#[test]
48+
fn test_vary() {
49+
let mut vary: Option<Vary>;
50+
51+
vary = Header::parse_header([b"*".to_vec()].as_slice());
52+
assert_eq!(vary, Some(Vary::Any));
53+
54+
vary = Header::parse_header([b"etag,cookie,allow".to_vec()].as_slice());
55+
assert_eq!(vary, Some(Vary::Headers(vec![from_str::<CaseInsensitive>("eTag").unwrap(),
56+
from_str::<CaseInsensitive>("cookIE").unwrap(),
57+
from_str::<CaseInsensitive>("AlLOw").unwrap(),])));
58+
}
59+
}

src/header/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::borrow::Cow::{Borrowed, Owned};
1010
use std::fmt::{mod, Show};
1111
use std::intrinsics::TypeId;
1212
use std::raw::TraitObject;
13-
use std::str::SendStr;
13+
use std::str::{SendStr, FromStr};
1414
use std::collections::HashMap;
1515
use std::collections::hash_map::{Entries, Occupied, Vacant};
1616
use std::{hash, mem};
@@ -446,8 +446,15 @@ impl fmt::Show for Box<HeaderFormat + Send + Sync> {
446446
}
447447
}
448448

449+
/// Case-insensitive string.
449450
//#[deriving(Clone)]
450-
struct CaseInsensitive(SendStr);
451+
pub struct CaseInsensitive(SendStr);
452+
453+
impl FromStr for CaseInsensitive {
454+
fn from_str(s: &str) -> Option<CaseInsensitive> {
455+
Some(CaseInsensitive(Owned(s.to_string())))
456+
}
457+
}
451458

452459
impl Clone for CaseInsensitive {
453460
fn clone(&self) -> CaseInsensitive {

0 commit comments

Comments
 (0)