Skip to content

Commit c238890

Browse files
committed
Merge pull request #503 from pyfisch/nice2
refactor(headers): Improve docs, fix nits, make formatting faster
2 parents 33146bd + db4d891 commit c238890

26 files changed

+279
-131
lines changed

src/header/common/accept.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ header! {
4848
Some(HeaderField(vec![
4949
QualityItem::new(Mime(TopLevel::Text, SubLevel::Plain, vec![]), Quality(500)),
5050
qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])),
51-
QualityItem::new(Mime(TopLevel::Text, SubLevel::Ext("x-dvi".to_string()), vec![]), Quality(800)),
51+
QualityItem::new(
52+
Mime(TopLevel::Text, SubLevel::Ext("x-dvi".to_string()), vec![]),
53+
Quality(800)),
5254
qitem(Mime(TopLevel::Text, SubLevel::Ext("x-c".to_string()), vec![])),
5355
])));
5456
// Custom tests
@@ -62,7 +64,9 @@ header! {
6264
test4,
6365
vec![b"text/plain; charset=utf-8; q=0.5"],
6466
Some(Accept(vec![
65-
QualityItem::new(Mime(TopLevel::Text, SubLevel::Plain, vec![(Attr::Charset, Value::Utf8)]), Quality(500)),
67+
QualityItem::new(Mime(TopLevel::Text,
68+
SubLevel::Plain, vec![(Attr::Charset, Value::Utf8)]),
69+
Quality(500)),
6670
])));
6771
}
6872
}

src/header/common/access_control_allow_headers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use unicase::UniCase;
22

33
header! {
44
#[doc="`Access-Control-Allow-Headers` header, part of"]
5-
#[doc="[CORS](www.w3.org/TR/cors/#access-control-allow-headers-response-header)"]
5+
#[doc="[CORS](http://www.w3.org/TR/cors/#access-control-allow-headers-response-header)"]
66
#[doc=""]
77
#[doc="The `Access-Control-Allow-Headers` header indicates, as part of the"]
88
#[doc="response to a preflight request, which header field names can be used"]

src/header/common/access_control_allow_methods.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use method::Method;
22

33
header! {
44
#[doc="`Access-Control-Allow-Methods` header, part of"]
5-
#[doc="[CORS](www.w3.org/TR/cors/#access-control-allow-methods-response-header)"]
5+
#[doc="[CORS](http://www.w3.org/TR/cors/#access-control-allow-methods-response-header)"]
66
#[doc=""]
77
#[doc="The `Access-Control-Allow-Methods` header indicates, as part of the"]
88
#[doc="response to a preflight request, which methods can be used during the"]

src/header/common/access_control_max_age.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
header! {
22
#[doc="`Access-Control-Max-Age` header, part of"]
3-
#[doc="[CORS](www.w3.org/TR/cors/#access-control-max-age-response-header)"]
3+
#[doc="[CORS](http://www.w3.org/TR/cors/#access-control-max-age-response-header)"]
44
#[doc=""]
55
#[doc="The `Access-Control-Max-Age` header indicates how long the results of a"]
66
#[doc="preflight request can be cached in a preflight result cache."]

src/header/common/access_control_request_headers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use unicase::UniCase;
22

33
header! {
44
#[doc="`Access-Control-Request-Headers` header, part of"]
5-
#[doc="[CORS](www.w3.org/TR/cors/#access-control-request-headers-request-header)"]
5+
#[doc="[CORS](http://www.w3.org/TR/cors/#access-control-request-headers-request-header)"]
66
#[doc=""]
77
#[doc="The `Access-Control-Request-Headers` header indicates which headers will"]
88
#[doc="be used in the actual request as part of the preflight request."]

src/header/common/access_control_request_method.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use method::Method;
22

33
header! {
44
#[doc="`Access-Control-Request-Method` header, part of"]
5-
#[doc="[CORS](www.w3.org/TR/cors/#access-control-request-method-request-header)"]
5+
#[doc="[CORS](http://www.w3.org/TR/cors/#access-control-request-method-request-header)"]
66
#[doc=""]
77
#[doc="The `Access-Control-Request-Method` header indicates which method will be"]
88
#[doc="used in the actual request as part of the preflight request."]

src/header/common/allow.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ header! {
4747
}
4848
}
4949

50-
bench_header!(bench, Allow, { vec![b"OPTIONS,GET,PUT,POST,DELETE,HEAD,TRACE,CONNECT,PATCH,fOObAr".to_vec()] });
50+
bench_header!(bench,
51+
Allow, { vec![b"OPTIONS,GET,PUT,POST,DELETE,HEAD,TRACE,CONNECT,PATCH,fOObAr".to_vec()] });

src/header/common/authorization.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
use std::any::Any;
2-
use std::fmt;
2+
use std::fmt::{self, Display};
33
use std::str::{FromStr, from_utf8};
44
use std::ops::{Deref, DerefMut};
55
use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline};
66
use header::{Header, HeaderFormat};
77

8-
/// The `Authorization` header field.
8+
/// `Authorization` header, defined in [RFC7235](https://tools.ietf.org/html/rfc7235#section-4.2)
9+
///
10+
/// The `Authorization` header field allows a user agent to authenticate
11+
/// itself with an origin server -- usually, but not necessarily, after
12+
/// receiving a 401 (Unauthorized) response. Its value consists of
13+
/// credentials containing the authentication information of the user
14+
/// agent for the realm of the resource being requested.
15+
///
16+
/// # ABNF
17+
/// ```plain
18+
/// Authorization = credentials
19+
/// ```
20+
///
21+
/// # Example values
22+
/// * `Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==`
923
#[derive(Clone, PartialEq, Debug)]
1024
pub struct Authorization<S: Scheme>(pub S);
1125

@@ -69,7 +83,7 @@ impl Scheme for String {
6983
}
7084

7185
fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result {
72-
fmt::Display::fmt(self, f)
86+
Display::fmt(self, f)
7387
}
7488
}
7589

@@ -97,12 +111,12 @@ impl Scheme for Basic {
97111
if let Some(ref pass) = self.password {
98112
text.push_str(&pass[..]);
99113
}
100-
write!(f, "{}", text.as_bytes().to_base64(Config {
114+
f.write_str(&text.as_bytes().to_base64(Config {
101115
char_set: Standard,
102116
newline: Newline::CRLF,
103117
pad: true,
104118
line_length: None
105-
}))
119+
})[..])
106120
}
107121
}
108122

@@ -153,15 +167,19 @@ mod tests {
153167

154168
#[test]
155169
fn test_raw_auth_parse() {
156-
let header: Authorization<String> = Header::parse_header(&[b"foo bar baz".to_vec()]).unwrap();
170+
let header: Authorization<String> = Header::parse_header(
171+
&[b"foo bar baz".to_vec()]).unwrap();
157172
assert_eq!(header.0, "foo bar baz");
158173
}
159174

160175
#[test]
161176
fn test_basic_auth() {
162177
let mut headers = Headers::new();
163-
headers.set(Authorization(Basic { username: "Aladdin".to_string(), password: Some("open sesame".to_string()) }));
164-
assert_eq!(headers.to_string(), "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n".to_string());
178+
headers.set(Authorization(
179+
Basic { username: "Aladdin".to_string(), password: Some("open sesame".to_string()) }));
180+
assert_eq!(
181+
headers.to_string(),
182+
"Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n".to_string());
165183
}
166184

167185
#[test]
@@ -173,19 +191,21 @@ mod tests {
173191

174192
#[test]
175193
fn test_basic_auth_parse() {
176-
let auth: Authorization<Basic> = Header::parse_header(&[b"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==".to_vec()]).unwrap();
194+
let auth: Authorization<Basic> = Header::parse_header(
195+
&[b"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==".to_vec()]).unwrap();
177196
assert_eq!(auth.0.username, "Aladdin");
178197
assert_eq!(auth.0.password, Some("open sesame".to_string()));
179198
}
180199

181200
#[test]
182201
fn test_basic_auth_parse_no_password() {
183-
let auth: Authorization<Basic> = Header::parse_header(&[b"Basic QWxhZGRpbjo=".to_vec()]).unwrap();
202+
let auth: Authorization<Basic> = Header::parse_header(
203+
&[b"Basic QWxhZGRpbjo=".to_vec()]).unwrap();
184204
assert_eq!(auth.0.username, "Aladdin");
185205
assert_eq!(auth.0.password, Some("".to_string()));
186206
}
187207

188208
}
189209

190210
bench_header!(raw, Authorization<String>, { vec![b"foo bar baz".to_vec()] });
191-
bench_header!(basic, Authorization<Basic>, { vec![b"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==".to_vec()] });
211+
bench_header!(basic, Authorization<Basic>, { vec![b"Basic QWxhZGRpbjpuIHNlc2FtZQ==".to_vec()] });

src/header/common/cache_control.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,23 @@ use std::str::FromStr;
33
use header::{Header, HeaderFormat};
44
use header::parsing::{from_one_comma_delimited, fmt_comma_delimited};
55

6-
/// The Cache-Control header.
6+
/// `Cache-Control` header, defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2)
7+
///
8+
/// The `Cache-Control` header field is used to specify directives for
9+
/// caches along the request/response chain. Such cache directives are
10+
/// unidirectional in that the presence of a directive in a request does
11+
/// not imply that the same directive is to be given in the response.
12+
///
13+
/// # ABNF
14+
/// ```plain
15+
/// Cache-Control = 1#cache-directive
16+
/// cache-directive = token [ "=" ( token / quoted-string ) ]
17+
/// ```
18+
///
19+
/// # Example values
20+
/// * `no-cache`
21+
/// * `private, community="UCI"`
22+
/// * `max-age=30`
723
#[derive(PartialEq, Clone, Debug)]
824
pub struct CacheControl(pub Vec<CacheDirective>);
925

@@ -28,8 +44,8 @@ impl Header for CacheControl {
2844
}
2945

3046
impl HeaderFormat for CacheControl {
31-
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
32-
fmt_comma_delimited(fmt, &self[..])
47+
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
48+
fmt_comma_delimited(f, &self[..])
3349
}
3450
}
3551

@@ -152,8 +168,9 @@ mod tests {
152168
#[test]
153169
fn test_parse_extension() {
154170
let cache = Header::parse_header(&[b"foo, bar=baz".to_vec()]);
155-
assert_eq!(cache, Some(CacheControl(vec![CacheDirective::Extension("foo".to_string(), None),
156-
CacheDirective::Extension("bar".to_string(), Some("baz".to_string()))])))
171+
assert_eq!(cache, Some(CacheControl(vec![
172+
CacheDirective::Extension("foo".to_string(), None),
173+
CacheDirective::Extension("bar".to_string(), Some("baz".to_string()))])))
157174
}
158175

159176
#[test]
@@ -163,4 +180,5 @@ mod tests {
163180
}
164181
}
165182

166-
bench_header!(normal, CacheControl, { vec![b"no-cache, private".to_vec(), b"max-age=100".to_vec()] });
183+
bench_header!(normal,
184+
CacheControl, { vec![b"no-cache, private".to_vec(), b"max-age=100".to_vec()] });

src/header/common/connection.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
use header::{Header, HeaderFormat};
2-
use std::fmt;
2+
use std::fmt::{self, Display};
33
use std::str::FromStr;
44
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
55
use unicase::UniCase;
66

77
pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader};
88

9-
/// The `Connection` header.
9+
/// `Connection` header, defined in [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.1)
10+
///
11+
/// The `Connection` header field allows the sender to indicate desired
12+
/// control options for the current connection. In order to avoid
13+
/// confusing downstream recipients, a proxy or gateway MUST remove or
14+
/// replace any received connection options before forwarding the
15+
/// message.
16+
///
17+
/// # ABNF
18+
/// ```plain
19+
/// Connection = 1#connection-option
20+
/// connection-option = token
21+
/// ```
22+
///
23+
/// # Example values
24+
/// * `close`
25+
/// * `upgrade`
26+
/// * `keep-alive`
1027
#[derive(Clone, PartialEq, Debug)]
1128
pub struct Connection(pub Vec<ConnectionOption>);
1229

@@ -33,20 +50,20 @@ pub enum ConnectionOption {
3350
impl FromStr for ConnectionOption {
3451
type Err = ();
3552
fn from_str(s: &str) -> Result<ConnectionOption, ()> {
36-
match s {
37-
"keep-alive" => Ok(KeepAlive),
38-
"close" => Ok(Close),
39-
s => Ok(ConnectionHeader(UniCase(s.to_string())))
40-
}
53+
Ok(match s {
54+
"keep-alive" => KeepAlive,
55+
"close" => Close,
56+
s => ConnectionHeader(UniCase(s.to_string())),
57+
})
4158
}
4259
}
4360

44-
impl fmt::Display for ConnectionOption {
45-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
46-
write!(fmt, "{}", match *self {
61+
impl Display for ConnectionOption {
62+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63+
f.write_str(match *self {
4764
KeepAlive => "keep-alive",
4865
Close => "close",
49-
ConnectionHeader(UniCase(ref s)) => s.as_ref()
66+
ConnectionHeader(UniCase(ref s)) => s,
5067
})
5168
}
5269
}
@@ -62,13 +79,12 @@ impl Header for Connection {
6279
}
6380

6481
impl HeaderFormat for Connection {
65-
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
82+
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
6683
let Connection(ref parts) = *self;
67-
fmt_comma_delimited(fmt, &parts[..])
84+
fmt_comma_delimited(f, &parts[..])
6885
}
6986
}
7087

7188
bench_header!(close, Connection, { vec![b"close".to_vec()] });
7289
bench_header!(keep_alive, Connection, { vec![b"keep-alive".to_vec()] });
7390
bench_header!(header, Connection, { vec![b"authorization".to_vec()] });
74-

src/header/common/content_type.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ header! {
2727
// FIXME: Should be b"text/html; charset=ISO-8859-4" but mime crate lowercases
2828
// the whole value so parsing and formatting the value gives a different result
2929
vec![b"text/html; charset=iso-8859-4"],
30-
Some(HeaderField(Mime(TopLevel::Text, SubLevel::Html, vec![(Attr::Charset, Value::Ext("iso-8859-4".to_string()))]))));
30+
Some(HeaderField(Mime(
31+
TopLevel::Text,
32+
SubLevel::Html,
33+
vec![(Attr::Charset, Value::Ext("iso-8859-4".to_string()))]))));
3134
}
3235
}
3336

src/header/common/cookie.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
use header::{Header, HeaderFormat};
2-
use std::fmt;
2+
use std::fmt::{self, Display};
33
use std::str::from_utf8;
44

55
use cookie::Cookie as CookiePair;
66
use cookie::CookieJar;
77

8-
/// The `Cookie` header. Defined in [RFC6265](tools.ietf.org/html/rfc6265#section-5.4):
8+
/// `Cookie` header, defined in [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.4)
99
///
10-
/// > If the user agent does attach a Cookie header field to an HTTP
11-
/// > request, the user agent must send the cookie-string
12-
/// > as the value of the header field.
10+
/// If the user agent does attach a Cookie header field to an HTTP
11+
/// request, the user agent must send the cookie-string
12+
/// as the value of the header field.
1313
///
14-
/// > When the user agent generates an HTTP request, the user agent MUST NOT
15-
/// > attach more than one Cookie header field.
14+
/// When the user agent generates an HTTP request, the user agent MUST NOT
15+
/// attach more than one Cookie header field.
16+
///
17+
/// # Example values
18+
/// * `SID=31d4d96e407aad42`
19+
/// * `SID=31d4d96e407aad42; lang=en-US`
1620
#[derive(Clone, PartialEq, Debug)]
1721
pub struct Cookie(pub Vec<CookiePair>);
1822

@@ -48,13 +52,13 @@ impl Header for Cookie {
4852
}
4953

5054
impl HeaderFormat for Cookie {
51-
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
55+
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
5256
let cookies = &self.0;
5357
for (i, cookie) in cookies.iter().enumerate() {
5458
if i != 0 {
55-
try!(fmt.write_str("; "));
59+
try!(f.write_str("; "));
5660
}
57-
try!(write!(fmt, "{}", cookie.pair()));
61+
try!(Display::fmt(&cookie.pair(), f));
5862
}
5963
Ok(())
6064
}
@@ -94,7 +98,9 @@ fn test_fmt() {
9498
let mut cookie_pair = CookiePair::new("foo".to_string(), "bar".to_string());
9599
cookie_pair.httponly = true;
96100
cookie_pair.path = Some("/p".to_string());
97-
let cookie_header = Cookie(vec![cookie_pair, CookiePair::new("baz".to_string(), "quux".to_string())]);
101+
let cookie_header = Cookie(vec![
102+
cookie_pair,
103+
CookiePair::new("baz".to_string(),"quux".to_string())]);
98104
let mut headers = Headers::new();
99105
headers.set(cookie_header);
100106

0 commit comments

Comments
 (0)