refactor(headers): export all headers and utils directly under header
Currently headers are exported at many places. For example you can access `Transfer-Encoding` header at `header`, `header::common` and `header::common::transfer_encoding`. Per discussion on IRC with @seanmonstar and @reem, all contents of headers will be exposed at `header` directly. Parsing utilities will be exposed at `header::parsing`. Header macros can now be used from other crates. This breaks much code using headers. It should use everything it needs directly from `header::`, encodings are exposed at `header::Encoding::`, connection options are exposed at `header::ConnectionOption`.
This commit is contained in:
@@ -6,7 +6,7 @@ use std::io::util::copy;
|
||||
use std::io::net::ip::Ipv4Addr;
|
||||
|
||||
use hyper::{Get, Post};
|
||||
use hyper::header::common::ContentLength;
|
||||
use hyper::header::ContentLength;
|
||||
use hyper::server::{Server, Request, Response};
|
||||
use hyper::uri::RequestUri::AbsolutePath;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use url::UrlParser;
|
||||
use url::ParseError as UrlError;
|
||||
|
||||
use header::{Headers, Header, HeaderFormat};
|
||||
use header::common::{ContentLength, Location};
|
||||
use header::{ContentLength, Location};
|
||||
use method::Method;
|
||||
use net::{NetworkConnector, HttpConnector, ContextVerifier};
|
||||
use status::StatusClass::Redirection;
|
||||
@@ -353,7 +353,7 @@ fn get_host_and_port(url: &Url) -> HttpResult<(String, Port)> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use header::common::Server;
|
||||
use header::Server;
|
||||
use super::{Client, RedirectPolicy};
|
||||
use url::Url;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use url::Url;
|
||||
|
||||
use method::{self, Method};
|
||||
use header::Headers;
|
||||
use header::common::{self, Host};
|
||||
use header::{self, Host};
|
||||
use net::{NetworkStream, NetworkConnector, HttpConnector, Fresh, Streaming};
|
||||
use http::{HttpWriter, LINE_ENDING};
|
||||
use http::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter, EmptyWriter};
|
||||
@@ -95,7 +95,7 @@ impl Request<Fresh> {
|
||||
let mut chunked = true;
|
||||
let mut len = 0;
|
||||
|
||||
match self.headers.get::<common::ContentLength>() {
|
||||
match self.headers.get::<header::ContentLength>() {
|
||||
Some(cl) => {
|
||||
chunked = false;
|
||||
len = **cl;
|
||||
@@ -105,18 +105,18 @@ impl Request<Fresh> {
|
||||
|
||||
// cant do in match above, thanks borrowck
|
||||
if chunked {
|
||||
let encodings = match self.headers.get_mut::<common::TransferEncoding>() {
|
||||
Some(&mut common::TransferEncoding(ref mut encodings)) => {
|
||||
let encodings = match self.headers.get_mut::<header::TransferEncoding>() {
|
||||
Some(&mut header::TransferEncoding(ref mut encodings)) => {
|
||||
//TODO: check if chunked is already in encodings. use HashSet?
|
||||
encodings.push(common::transfer_encoding::Encoding::Chunked);
|
||||
encodings.push(header::Encoding::Chunked);
|
||||
false
|
||||
},
|
||||
None => true
|
||||
};
|
||||
|
||||
if encodings {
|
||||
self.headers.set::<common::TransferEncoding>(
|
||||
common::TransferEncoding(vec![common::transfer_encoding::Encoding::Chunked]))
|
||||
self.headers.set::<header::TransferEncoding>(
|
||||
header::TransferEncoding(vec![header::Encoding::Chunked]))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::num::FromPrimitive;
|
||||
use std::io::{BufferedReader, IoResult};
|
||||
|
||||
use header;
|
||||
use header::common::{ContentLength, TransferEncoding};
|
||||
use header::common::transfer_encoding::Encoding::Chunked;
|
||||
use header::{ContentLength, TransferEncoding};
|
||||
use header::Encoding::Chunked;
|
||||
use net::{NetworkStream, HttpStream};
|
||||
use http::{read_status_line, HttpReader, RawStatus};
|
||||
use http::HttpReader::{SizedReader, ChunkedReader, EofReader};
|
||||
@@ -100,8 +100,8 @@ mod tests {
|
||||
use std::io::BufferedReader;
|
||||
|
||||
use header::Headers;
|
||||
use header::common::TransferEncoding;
|
||||
use header::common::transfer_encoding::Encoding;
|
||||
use header::TransferEncoding;
|
||||
use header::Encoding;
|
||||
use http::HttpReader::EofReader;
|
||||
use http::RawStatus;
|
||||
use mock::MockStream;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use header;
|
||||
use header::shared;
|
||||
use header::parsing;
|
||||
|
||||
use mime;
|
||||
|
||||
@@ -15,8 +15,8 @@ use mime;
|
||||
///
|
||||
/// ```
|
||||
/// # use hyper::header::Headers;
|
||||
/// # use hyper::header::common::Accept;
|
||||
/// # use hyper::header::shared::qitem;
|
||||
/// # use hyper::header::Accept;
|
||||
/// # use hyper::header::qitem;
|
||||
/// use hyper::mime::Mime;
|
||||
/// use hyper::mime::TopLevel::Text;
|
||||
/// use hyper::mime::SubLevel::{Html, Xml};
|
||||
@@ -26,9 +26,9 @@ use mime;
|
||||
/// qitem(Mime(Text, Xml, vec![])) ]));
|
||||
/// ```
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct Accept(pub Vec<shared::QualityItem<mime::Mime>>);
|
||||
pub struct Accept(pub Vec<header::QualityItem<mime::Mime>>);
|
||||
|
||||
deref!(Accept => Vec<shared::QualityItem<mime::Mime>>);
|
||||
deref!(Accept => Vec<header::QualityItem<mime::Mime>>);
|
||||
|
||||
impl header::Header for Accept {
|
||||
fn header_name(_: Option<Accept>) -> &'static str {
|
||||
@@ -37,13 +37,13 @@ impl header::Header for Accept {
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<Accept> {
|
||||
// TODO: Return */* if no value is given.
|
||||
shared::from_comma_delimited(raw).map(Accept)
|
||||
parsing::from_comma_delimited(raw).map(Accept)
|
||||
}
|
||||
}
|
||||
|
||||
impl header::HeaderFormat for Accept {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
shared::fmt_comma_delimited(fmt, &self[])
|
||||
parsing::fmt_comma_delimited(fmt, &self[])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ bench_header!(bench, Accept, { vec![b"text/plain; q=0.5, text/html".to_vec()] })
|
||||
fn test_parse_header_no_quality() {
|
||||
let a: Accept = header::Header::parse_header([b"text/plain; charset=utf-8".to_vec()].as_slice()).unwrap();
|
||||
let b = Accept(vec![
|
||||
shared::QualityItem{item: mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, vec![(mime::Attr::Charset, mime::Value::Utf8)]), quality: 1f32},
|
||||
header::QualityItem{item: mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, vec![(mime::Attr::Charset, mime::Value::Utf8)]), quality: 1f32},
|
||||
]);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ fn test_parse_header_no_quality() {
|
||||
fn test_parse_header_with_quality() {
|
||||
let a: Accept = header::Header::parse_header([b"text/plain; charset=utf-8; q=0.5".to_vec()].as_slice()).unwrap();
|
||||
let b = Accept(vec![
|
||||
shared::QualityItem{item: mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, vec![(mime::Attr::Charset, mime::Value::Utf8)]), quality: 0.5f32},
|
||||
header::QualityItem{item: mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, vec![(mime::Attr::Charset, mime::Value::Utf8)]), quality: 0.5f32},
|
||||
]);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
use header::{self, shared};
|
||||
use header::{self, Encoding, QualityItem};
|
||||
|
||||
/// The `Accept-Encoding` header
|
||||
///
|
||||
/// The `Accept-Encoding` header can be used by clients to indicate what
|
||||
/// response encodings they accept.
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct AcceptEncoding(pub Vec<shared::QualityItem<shared::Encoding>>);
|
||||
pub struct AcceptEncoding(pub Vec<QualityItem<Encoding>>);
|
||||
|
||||
impl_list_header!(AcceptEncoding,
|
||||
"Accept-Encoding",
|
||||
Vec<shared::QualityItem<shared::Encoding>>);
|
||||
Vec<QualityItem<Encoding>>);
|
||||
|
||||
#[test]
|
||||
fn test_parse_header() {
|
||||
let a: AcceptEncoding = header::Header::parse_header([b"gzip;q=1.0, identity; q=0.5".to_vec()].as_slice()).unwrap();
|
||||
let b = AcceptEncoding(vec![
|
||||
shared::QualityItem{item: shared::Gzip, quality: 1f32},
|
||||
shared::QualityItem{item: shared::Identity, quality: 0.5f32},
|
||||
QualityItem{item: Encoding::Gzip, quality: 1f32},
|
||||
QualityItem{item: Encoding::Identity, quality: 0.5f32},
|
||||
]);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
use std::fmt::{self};
|
||||
|
||||
use header;
|
||||
use header::shared;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AccessControlAllowHeaders(pub Vec<String>);
|
||||
/// The `Access-Control-Allow-Headers` response header,
|
||||
/// part of [CORS](http://www.w3.org/TR/cors/).
|
||||
///
|
||||
/// > The `Access-Control-Allow-Headers` header indicates, as part of the
|
||||
/// > response to a preflight request, which header field names can be used
|
||||
/// > during the actual request.
|
||||
///
|
||||
/// Spec: www.w3.org/TR/cors/#access-control-allow-headers-response-header
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct AccessControlAllowHeaders(pub Vec<String>);
|
||||
|
||||
impl header::Header for AccessControlAllowHeaders {
|
||||
#[inline]
|
||||
@@ -13,13 +20,13 @@ impl header::Header for AccessControlAllowHeaders {
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowHeaders> {
|
||||
shared::from_comma_delimited(raw).map(AccessControlAllowHeaders)
|
||||
header::parsing::from_comma_delimited(raw).map(AccessControlAllowHeaders)
|
||||
}
|
||||
}
|
||||
|
||||
impl header::HeaderFormat for AccessControlAllowHeaders {
|
||||
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let AccessControlAllowHeaders(ref parts) = *self;
|
||||
shared::fmt_comma_delimited(f, parts.as_slice())
|
||||
header::parsing::fmt_comma_delimited(f, parts.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
use std::fmt::{self};
|
||||
|
||||
use header;
|
||||
use header::shared;
|
||||
use method;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AccessControlAllowMethods(pub Vec<method::Method>);
|
||||
/// The `Access-Control-Allow-Methods` response header,
|
||||
/// part of [CORS](http://www.w3.org/TR/cors/).
|
||||
///
|
||||
/// > The `Access-Control-Allow-Methods` header indicates, as part of the
|
||||
/// > response to a preflight request, which methods can be used during the
|
||||
/// > actual request.
|
||||
///
|
||||
/// Spec: www.w3.org/TR/cors/#access-control-allow-methods-response-header
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct AccessControlAllowMethods(pub Vec<method::Method>);
|
||||
|
||||
impl header::Header for AccessControlAllowMethods {
|
||||
#[inline]
|
||||
@@ -14,13 +21,13 @@ impl header::Header for AccessControlAllowMethods {
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowMethods> {
|
||||
shared::from_comma_delimited(raw).map(AccessControlAllowMethods)
|
||||
header::parsing::from_comma_delimited(raw).map(AccessControlAllowMethods)
|
||||
}
|
||||
}
|
||||
|
||||
impl header::HeaderFormat for AccessControlAllowMethods {
|
||||
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let AccessControlAllowMethods(ref parts) = *self;
|
||||
shared::fmt_comma_delimited(f, parts.as_slice())
|
||||
header::parsing::fmt_comma_delimited(f, parts.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,19 @@ use std::str;
|
||||
|
||||
use header;
|
||||
|
||||
#[derive(Clone)]
|
||||
enum AccessControlAllowOrigin {
|
||||
/// The `Access-Control-Allow-Origin` response header,
|
||||
/// part of [CORS](http://www.w3.org/TR/cors/).
|
||||
///
|
||||
/// > The `Access-Control-Allow-Origin` header indicates whether a resource
|
||||
/// > can be shared based by returning the value of the Origin request header,
|
||||
/// > "*", or "null" in the response.
|
||||
///
|
||||
/// Spec: www.w3.org/TR/cors/#access-control-allow-origin-response-header
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub enum AccessControlAllowOrigin {
|
||||
/// Allow all origins
|
||||
AllowStar,
|
||||
/// Allow one particular origin
|
||||
AllowOrigin(url::Url),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
use std::fmt;
|
||||
|
||||
use header;
|
||||
use header::shared;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AccessControlMaxAge(pub u32);
|
||||
/// The `Access-Control-Max-Age` response header,
|
||||
/// part of [CORS](http://www.w3.org/TR/cors/).
|
||||
///
|
||||
/// > The `Access-Control-Max-Age` header indicates how long the results of a
|
||||
/// > preflight request can be cached in a preflight result cache.
|
||||
///
|
||||
/// Spec: www.w3.org/TR/cors/#access-control-max-age-response-header
|
||||
#[derive(Clone, Copy, PartialEq, Show)]
|
||||
pub struct AccessControlMaxAge(pub u32);
|
||||
|
||||
impl header::Header for AccessControlMaxAge {
|
||||
#[inline]
|
||||
@@ -13,7 +19,7 @@ impl header::Header for AccessControlMaxAge {
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlMaxAge> {
|
||||
shared::from_one_raw_str(raw).map(AccessControlMaxAge)
|
||||
header::parsing::from_one_raw_str(raw).map(AccessControlMaxAge)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
/// Exposes the AccessControlAllowHeaders header
|
||||
pub mod allow_headers;
|
||||
pub use self::allow_headers::AccessControlAllowHeaders;
|
||||
pub use self::allow_methods::AccessControlAllowMethods;
|
||||
pub use self::allow_origin::AccessControlAllowOrigin;
|
||||
pub use self::max_age::AccessControlMaxAge;
|
||||
pub use self::request_headers::AccessControlRequestHeaders;
|
||||
pub use self::request_method::AccessControlRequestMethod;
|
||||
|
||||
/// Exposes the AccessControlAllowMethods header
|
||||
pub mod allow_methods;
|
||||
|
||||
/// Exposes the AccessControlAllowOrigin header
|
||||
pub mod allow_origin;
|
||||
|
||||
/// Exposes the AccessControlMaxAge header
|
||||
pub mod max_age;
|
||||
|
||||
/// Exposes the AccessControlRequestHeaders header
|
||||
pub mod request_headers;
|
||||
|
||||
/// Exposes the AccessControlRequestMethod header
|
||||
pub mod request_method;
|
||||
mod allow_headers;
|
||||
mod allow_methods;
|
||||
mod allow_origin;
|
||||
mod max_age;
|
||||
mod request_headers;
|
||||
mod request_method;
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
use std::fmt::{self};
|
||||
|
||||
use header;
|
||||
use header::shared;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AccessControlRequestHeaders(pub Vec<String>);
|
||||
/// The `Access-Control-Request-Headers` request header,
|
||||
/// part of [CORS](http://www.w3.org/TR/cors/).
|
||||
///
|
||||
/// > The `Access-Control-Request-Headers` header indicates which headers will
|
||||
/// > be used in the actual request as part of the preflight request.
|
||||
///
|
||||
/// Spec: www.w3.org/TR/cors/#access-control-request-headers-request-header
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct AccessControlRequestHeaders(pub Vec<String>);
|
||||
|
||||
impl header::Header for AccessControlRequestHeaders {
|
||||
#[inline]
|
||||
@@ -13,13 +19,13 @@ impl header::Header for AccessControlRequestHeaders {
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlRequestHeaders> {
|
||||
shared::from_comma_delimited(raw).map(AccessControlRequestHeaders)
|
||||
header::parsing::from_comma_delimited(raw).map(AccessControlRequestHeaders)
|
||||
}
|
||||
}
|
||||
|
||||
impl header::HeaderFormat for AccessControlRequestHeaders {
|
||||
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let AccessControlRequestHeaders(ref parts) = *self;
|
||||
shared::fmt_comma_delimited(f, parts.as_slice())
|
||||
header::parsing::fmt_comma_delimited(f, parts.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
use std::fmt;
|
||||
|
||||
use header;
|
||||
use header::shared;
|
||||
use method::Method;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AccessControlRequestMethod(pub Method);
|
||||
/// The `Access-Control-Request-Method` request header,
|
||||
/// part of [CORS](http://www.w3.org/TR/cors/).
|
||||
///
|
||||
/// > The `Access-Control-Request-Method` header indicates which method will be
|
||||
/// > used in the actual request as part of the preflight request.
|
||||
///
|
||||
/// Spec: www.w3.org/TR/cors/#access-control-request-method-request-header
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct AccessControlRequestMethod(pub Method);
|
||||
|
||||
impl header::Header for AccessControlRequestMethod {
|
||||
#[inline]
|
||||
@@ -14,7 +20,7 @@ impl header::Header for AccessControlRequestMethod {
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlRequestMethod> {
|
||||
shared::from_one_raw_str(raw).map(AccessControlRequestMethod)
|
||||
header::parsing::from_one_raw_str(raw).map(AccessControlRequestMethod)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use method::Method;
|
||||
use std::fmt::{self};
|
||||
use header::shared::util::{from_comma_delimited, fmt_comma_delimited};
|
||||
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
|
||||
|
||||
/// The `Allow` header.
|
||||
/// See also https://tools.ietf.org/html/rfc7231#section-7.4.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use header::{Header, HeaderFormat};
|
||||
use header::shared::util::{from_one_comma_delimited, fmt_comma_delimited};
|
||||
use header::parsing::{from_one_comma_delimited, fmt_comma_delimited};
|
||||
|
||||
/// The Cache-Control header.
|
||||
#[derive(PartialEq, Clone, Show)]
|
||||
@@ -163,4 +163,3 @@ mod tests {
|
||||
}
|
||||
|
||||
bench_header!(normal, CacheControl, { vec![b"no-cache, private".to_vec(), b"max-age=100".to_vec()] });
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use header::shared::util::{from_comma_delimited, fmt_comma_delimited};
|
||||
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
|
||||
|
||||
pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use header::{Header, HeaderFormat};
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
|
||||
/// The `Content-Length` header.
|
||||
///
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt;
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
use mime::Mime;
|
||||
|
||||
/// The `Content-Type` header.
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use time::Tm;
|
||||
use header::{Header, HeaderFormat};
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::shared::time::tm_from_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
use header::parsing::tm_from_str;
|
||||
|
||||
// Egh, replace as soon as something better than time::Tm exists.
|
||||
/// The `Date` header field.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt::{self};
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
|
||||
/// The `Etag` header.
|
||||
///
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use time::Tm;
|
||||
use header::{Header, HeaderFormat};
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::shared::time::tm_from_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
use header::parsing::tm_from_str;
|
||||
|
||||
/// The `Expires` header field.
|
||||
#[derive(Copy, PartialEq, Clone, Show)]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use Port;
|
||||
use std::fmt;
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
|
||||
/// The `Host` header.
|
||||
///
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use time::Tm;
|
||||
use header::{Header, HeaderFormat};
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::shared::time::tm_from_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
use header::parsing::tm_from_str;
|
||||
|
||||
/// The `If-Modified-Since` header field.
|
||||
#[derive(Copy, PartialEq, Clone, Show)]
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use time::Tm;
|
||||
use header::{Header, HeaderFormat};
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::shared::time::tm_from_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
use header::parsing::tm_from_str;
|
||||
|
||||
/// The `LastModified` header field.
|
||||
#[derive(Copy, PartialEq, Clone, Show)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt;
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
|
||||
/// The `Location` header.
|
||||
///
|
||||
|
||||
@@ -6,30 +6,34 @@
|
||||
//! strongly-typed theme, the [mime](http://seanmonstar.github.io/mime.rs) crate
|
||||
//! is used, such as `ContentType(pub Mime)`.
|
||||
|
||||
pub use self::access_control::*;
|
||||
pub use self::accept::Accept;
|
||||
pub use self::accept_encoding::AcceptEncoding;
|
||||
pub use self::allow::Allow;
|
||||
pub use self::authorization::Authorization;
|
||||
pub use self::cache_control::CacheControl;
|
||||
pub use self::cookie::Cookies;
|
||||
pub use self::connection::Connection;
|
||||
pub use self::content_length::ContentLength;
|
||||
pub use self::content_type::ContentType;
|
||||
pub use self::cookie::Cookies;
|
||||
pub use self::date::Date;
|
||||
pub use self::etag::Etag;
|
||||
pub use self::expires::Expires;
|
||||
pub use self::host::Host;
|
||||
pub use self::last_modified::LastModified;
|
||||
pub use self::if_modified_since::IfModifiedSince;
|
||||
pub use self::last_modified::LastModified;
|
||||
pub use self::location::Location;
|
||||
pub use self::referer::Referer;
|
||||
pub use self::server::Server;
|
||||
pub use self::set_cookie::SetCookie;
|
||||
pub use self::transfer_encoding::TransferEncoding;
|
||||
pub use self::upgrade::Upgrade;
|
||||
pub use self::user_agent::UserAgent;
|
||||
pub use self::vary::Vary;
|
||||
pub use self::server::Server;
|
||||
pub use self::set_cookie::SetCookie;
|
||||
pub use self::referer::Referer;
|
||||
|
||||
pub use self::connection::ConnectionOption;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! bench_header(
|
||||
($name:ident, $ty:ty, $value:expr) => {
|
||||
#[cfg(test)]
|
||||
@@ -59,6 +63,7 @@ macro_rules! bench_header(
|
||||
}
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! deref(
|
||||
($from:ty => $to:ty) => {
|
||||
impl ::std::ops::Deref for $from {
|
||||
@@ -77,6 +82,7 @@ macro_rules! deref(
|
||||
}
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_list_header(
|
||||
($from:ident, $name:expr, $item:ty) => {
|
||||
deref!($from => $item);
|
||||
@@ -87,13 +93,13 @@ macro_rules! impl_list_header(
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<$from> {
|
||||
$crate::header::shared::from_comma_delimited(raw).map($from)
|
||||
$crate::header::parsing::from_comma_delimited(raw).map($from)
|
||||
}
|
||||
}
|
||||
|
||||
impl header::HeaderFormat for $from {
|
||||
fn fmt_header(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
$crate::header::shared::fmt_comma_delimited(fmt, &self[])
|
||||
$crate::header::parsing::fmt_comma_delimited(fmt, &self[])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +112,7 @@ macro_rules! impl_list_header(
|
||||
}
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_header(
|
||||
($from:ident, $name:expr, $item:ty) => {
|
||||
deref!($from => $item);
|
||||
@@ -116,7 +123,7 @@ macro_rules! impl_header(
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<$from> {
|
||||
$crate::header::shared::from_one_raw_str(raw).map($from)
|
||||
$crate::header::parsing::from_one_raw_str(raw).map($from)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,75 +142,28 @@ macro_rules! impl_header(
|
||||
}
|
||||
);
|
||||
|
||||
/// Exposes the AccessControl* family of headers.
|
||||
pub mod access_control;
|
||||
|
||||
/// Exposes the Accept header.
|
||||
pub mod accept;
|
||||
|
||||
/// Exposes the AcceptEncoding header.
|
||||
pub mod accept_encoding;
|
||||
|
||||
/// Exposes the Allow header.
|
||||
pub mod allow;
|
||||
|
||||
/// Exposes the Authorization header.
|
||||
pub mod authorization;
|
||||
|
||||
/// Exposes the CacheControl header.
|
||||
pub mod cache_control;
|
||||
|
||||
/// Exposes the Cookie header.
|
||||
pub mod cookie;
|
||||
|
||||
/// Exposes the Connection header.
|
||||
pub mod connection;
|
||||
|
||||
/// Exposes the ContentLength header.
|
||||
pub mod content_length;
|
||||
|
||||
/// Exposes the ContentType header.
|
||||
pub mod content_type;
|
||||
|
||||
/// Exposes the Date header.
|
||||
pub mod date;
|
||||
|
||||
/// Exposes the Etag header.
|
||||
pub mod etag;
|
||||
|
||||
/// Exposes the Expires header.
|
||||
pub mod expires;
|
||||
|
||||
/// Exposes the Host header.
|
||||
pub mod host;
|
||||
|
||||
/// Exposes the LastModified header.
|
||||
pub mod last_modified;
|
||||
|
||||
/// Exposes the If-Modified-Since header.
|
||||
pub mod if_modified_since;
|
||||
|
||||
/// Exposes the Location header.
|
||||
pub mod location;
|
||||
|
||||
/// Exposes the Server header.
|
||||
pub mod server;
|
||||
|
||||
/// Exposes the Set-Cookie header.
|
||||
pub mod set_cookie;
|
||||
|
||||
/// Exposes the TransferEncoding header.
|
||||
pub mod transfer_encoding;
|
||||
|
||||
/// Exposes the Upgrade header.
|
||||
pub mod upgrade;
|
||||
|
||||
/// Exposes the UserAgent header.
|
||||
pub mod user_agent;
|
||||
|
||||
/// Exposes the Vary header.
|
||||
pub mod vary;
|
||||
|
||||
/// Exposes the Referer header
|
||||
pub mod referer;
|
||||
mod access_control;
|
||||
mod accept;
|
||||
mod accept_encoding;
|
||||
mod allow;
|
||||
mod authorization;
|
||||
mod cache_control;
|
||||
mod cookie;
|
||||
mod connection;
|
||||
mod content_length;
|
||||
mod content_type;
|
||||
mod date;
|
||||
mod etag;
|
||||
mod expires;
|
||||
mod host;
|
||||
mod last_modified;
|
||||
mod if_modified_since;
|
||||
mod location;
|
||||
mod referer;
|
||||
mod server;
|
||||
mod set_cookie;
|
||||
mod transfer_encoding;
|
||||
mod upgrade;
|
||||
mod user_agent;
|
||||
mod vary;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt::{self, Show};
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
|
||||
/// The `Referer` header.
|
||||
///
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use header::shared::util::{from_comma_delimited, fmt_comma_delimited};
|
||||
|
||||
use self::Encoding::{Chunked, Gzip, Deflate, Compress, EncodingExt};
|
||||
use header::Encoding;
|
||||
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
|
||||
|
||||
/// The `Transfer-Encoding` header.
|
||||
///
|
||||
@@ -23,54 +21,6 @@ pub struct TransferEncoding(pub Vec<Encoding>);
|
||||
|
||||
deref!(TransferEncoding => Vec<Encoding>);
|
||||
|
||||
/// A value to be used with the `Transfer-Encoding` header.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```
|
||||
/// # use hyper::header::TransferEncoding;
|
||||
/// # use hyper::header::transfer_encoding::Encoding::{Gzip, Chunked};
|
||||
/// # use hyper::header::Headers;
|
||||
/// # let mut headers = Headers::new();
|
||||
/// headers.set(TransferEncoding(vec![Gzip, Chunked]));
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub enum Encoding {
|
||||
/// The `chunked` encoding.
|
||||
Chunked,
|
||||
/// The `gzip` encoding.
|
||||
Gzip,
|
||||
/// The `deflate` encoding.
|
||||
Deflate,
|
||||
/// The `compress` encoding.
|
||||
Compress,
|
||||
/// Some other encoding that is less common, can be any String.
|
||||
EncodingExt(String)
|
||||
}
|
||||
|
||||
impl fmt::String for Encoding {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{}", match *self {
|
||||
Chunked => "chunked",
|
||||
Gzip => "gzip",
|
||||
Deflate => "deflate",
|
||||
Compress => "compress",
|
||||
EncodingExt(ref s) => s.as_slice()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Encoding {
|
||||
fn from_str(s: &str) -> Option<Encoding> {
|
||||
match s {
|
||||
"chunked" => Some(Chunked),
|
||||
"deflate" => Some(Deflate),
|
||||
"gzip" => Some(Gzip),
|
||||
"compress" => Some(Compress),
|
||||
_ => Some(EncodingExt(s.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Header for TransferEncoding {
|
||||
fn header_name(_: Option<TransferEncoding>) -> &'static str {
|
||||
"Transfer-Encoding"
|
||||
@@ -89,4 +39,3 @@ impl HeaderFormat for TransferEncoding {
|
||||
|
||||
bench_header!(normal, TransferEncoding, { vec![b"chunked, gzip".to_vec()] });
|
||||
bench_header!(ext, TransferEncoding, { vec![b"ext".to_vec()] });
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use header::shared::util::{from_comma_delimited, fmt_comma_delimited};
|
||||
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
|
||||
|
||||
use self::Protocol::{WebSocket, ProtocolExt};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt;
|
||||
use header::shared::util::from_one_raw_str;
|
||||
use header::parsing::from_one_raw_str;
|
||||
|
||||
/// The `User-Agent` header field.
|
||||
///
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use header::{Header, HeaderFormat};
|
||||
use std::fmt::{self};
|
||||
use header::shared::util::{from_comma_delimited, fmt_comma_delimited, from_one_raw_str};
|
||||
use header::parsing::{from_comma_delimited, fmt_comma_delimited, from_one_raw_str};
|
||||
use unicase::UniCase;
|
||||
|
||||
/// The `Allow` header.
|
||||
|
||||
@@ -23,13 +23,12 @@ use unicase::UniCase;
|
||||
|
||||
use {http, HttpResult};
|
||||
|
||||
pub use self::shared::{Encoding, QualityItem, qitem};
|
||||
pub use self::common::*;
|
||||
pub use self::shared::*;
|
||||
|
||||
/// Common Headers
|
||||
pub mod common;
|
||||
|
||||
pub mod shared;
|
||||
mod common;
|
||||
mod shared;
|
||||
pub mod parsing;
|
||||
|
||||
type HeaderName = UniCase<CowString<'static>>;
|
||||
|
||||
@@ -237,7 +236,7 @@ impl Headers {
|
||||
///
|
||||
/// ```
|
||||
/// # use hyper::header::Headers;
|
||||
/// # use hyper::header::common::ContentType;
|
||||
/// # use hyper::header::ContentType;
|
||||
/// # let mut headers = Headers::new();
|
||||
/// let has_type = headers.has::<ContentType>();
|
||||
/// ```
|
||||
@@ -515,9 +514,8 @@ mod tests {
|
||||
use mime::TopLevel::Text;
|
||||
use mime::SubLevel::Plain;
|
||||
use unicase::UniCase;
|
||||
use super::{Headers, Header, HeaderFormat};
|
||||
use super::common::{ContentLength, ContentType, Accept, Host};
|
||||
use super::shared::{QualityItem};
|
||||
use super::{Headers, Header, HeaderFormat, ContentLength, ContentType,
|
||||
Accept, Host, QualityItem};
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! Utility functions for Header implementations.
|
||||
|
||||
extern crate time;
|
||||
|
||||
use std::str;
|
||||
use std::fmt;
|
||||
|
||||
@@ -50,3 +52,34 @@ pub fn fmt_comma_delimited<T: fmt::String>(fmt: &mut fmt::Formatter, parts: &[T]
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get a Tm from HTTP date formats.
|
||||
// Prior to 1995, there were three different formats commonly used by
|
||||
// servers to communicate timestamps. For compatibility with old
|
||||
// implementations, all three are defined here. The preferred format is
|
||||
// a fixed-length and single-zone subset of the date and time
|
||||
// specification used by the Internet Message Format [RFC5322].
|
||||
//
|
||||
// HTTP-date = IMF-fixdate / obs-date
|
||||
//
|
||||
// An example of the preferred format is
|
||||
//
|
||||
// Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate
|
||||
//
|
||||
// Examples of the two obsolete formats are
|
||||
//
|
||||
// Sunday, 06-Nov-94 08:49:37 GMT ; obsolete RFC 850 format
|
||||
// Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
|
||||
//
|
||||
// A recipient that parses a timestamp value in an HTTP header field
|
||||
// MUST accept all three HTTP-date formats. When a sender generates a
|
||||
// header field that contains one or more timestamps defined as
|
||||
// HTTP-date, the sender MUST generate those timestamps in the
|
||||
// IMF-fixdate format.
|
||||
pub fn tm_from_str(s: &str) -> Option<time::Tm> {
|
||||
time::strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| {
|
||||
time::strptime(s, "%A, %d-%b-%y %T %Z")
|
||||
}).or_else(|_| {
|
||||
time::strptime(s, "%c")
|
||||
}).ok()
|
||||
}
|
||||
@@ -1,26 +1,5 @@
|
||||
//! Various functions, structs and enums useful for many headers.
|
||||
|
||||
pub use self::encoding::Encoding;
|
||||
pub use self::encoding::Encoding::{
|
||||
Chunked,
|
||||
Gzip,
|
||||
Deflate,
|
||||
Compress,
|
||||
Identity,
|
||||
EncodingExt};
|
||||
pub use self::quality_item::{QualityItem, qitem};
|
||||
|
||||
pub use self::quality_item::QualityItem;
|
||||
pub use self::quality_item::qitem;
|
||||
|
||||
pub use self::time::tm_from_str;
|
||||
|
||||
pub use self::util::{
|
||||
from_one_raw_str,
|
||||
from_comma_delimited,
|
||||
from_one_comma_delimited,
|
||||
fmt_comma_delimited};
|
||||
|
||||
pub mod encoding;
|
||||
pub mod quality_item;
|
||||
pub mod time;
|
||||
pub mod util;
|
||||
mod encoding;
|
||||
mod quality_item;
|
||||
|
||||
@@ -13,8 +13,8 @@ pub use net::{Fresh, Streaming};
|
||||
|
||||
use HttpError::HttpIoError;
|
||||
use {HttpResult};
|
||||
use header::common::Connection;
|
||||
use header::common::connection::{KeepAlive, Close};
|
||||
use header::Connection;
|
||||
use header::ConnectionOption::{Close, KeepAlive};
|
||||
use net::{NetworkListener, NetworkStream, NetworkAcceptor,
|
||||
HttpAcceptor, HttpListener};
|
||||
use version::HttpVersion::{Http10, Http11};
|
||||
@@ -183,4 +183,3 @@ impl<F> Handler for F where F: Fn(Request, Response<Fresh>), F: Sync + Send {
|
||||
(*self)(req, res)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ use std::io::net::ip::SocketAddr;
|
||||
use {HttpResult};
|
||||
use version::{HttpVersion};
|
||||
use method::Method::{self, Get, Head};
|
||||
use header::Headers;
|
||||
use header::common::{ContentLength, TransferEncoding};
|
||||
use header::{Headers, ContentLength, TransferEncoding};
|
||||
use http::{read_request_line};
|
||||
use http::HttpReader;
|
||||
use http::HttpReader::{SizedReader, ChunkedReader, EmptyReader};
|
||||
@@ -74,8 +73,7 @@ impl<'a> Reader for Request<'a> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use header::common::{Host, TransferEncoding};
|
||||
use header::common::transfer_encoding::Encoding;
|
||||
use header::{Host, TransferEncoding, Encoding};
|
||||
use mock::MockStream;
|
||||
use super::Request;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ use std::io::IoResult;
|
||||
use time::now_utc;
|
||||
|
||||
use header;
|
||||
use header::common;
|
||||
use http::{CR, LF, LINE_ENDING, HttpWriter};
|
||||
use http::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter};
|
||||
use status;
|
||||
@@ -70,15 +69,15 @@ impl<'a> Response<'a, Fresh> {
|
||||
debug!("writing head: {:?} {:?}", self.version, self.status);
|
||||
try!(write!(&mut self.body, "{} {}{}{}", self.version, self.status, CR as char, LF as char));
|
||||
|
||||
if !self.headers.has::<common::Date>() {
|
||||
self.headers.set(common::Date(now_utc()));
|
||||
if !self.headers.has::<header::Date>() {
|
||||
self.headers.set(header::Date(now_utc()));
|
||||
}
|
||||
|
||||
|
||||
let mut chunked = true;
|
||||
let mut len = 0;
|
||||
|
||||
match self.headers.get::<common::ContentLength>() {
|
||||
match self.headers.get::<header::ContentLength>() {
|
||||
Some(cl) => {
|
||||
chunked = false;
|
||||
len = **cl;
|
||||
@@ -88,18 +87,18 @@ impl<'a> Response<'a, Fresh> {
|
||||
|
||||
// cant do in match above, thanks borrowck
|
||||
if chunked {
|
||||
let encodings = match self.headers.get_mut::<common::TransferEncoding>() {
|
||||
Some(&mut common::TransferEncoding(ref mut encodings)) => {
|
||||
let encodings = match self.headers.get_mut::<header::TransferEncoding>() {
|
||||
Some(&mut header::TransferEncoding(ref mut encodings)) => {
|
||||
//TODO: check if chunked is already in encodings. use HashSet?
|
||||
encodings.push(common::transfer_encoding::Encoding::Chunked);
|
||||
encodings.push(header::Encoding::Chunked);
|
||||
false
|
||||
},
|
||||
None => true
|
||||
};
|
||||
|
||||
if encodings {
|
||||
self.headers.set::<common::TransferEncoding>(
|
||||
common::TransferEncoding(vec![common::transfer_encoding::Encoding::Chunked]))
|
||||
self.headers.set::<header::TransferEncoding>(
|
||||
header::TransferEncoding(vec![header::Encoding::Chunked]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,4 +150,3 @@ impl<'a> Writer for Response<'a, Streaming> {
|
||||
self.body.flush()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user