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:
Pyfisch
2015-01-20 13:04:42 +01:00
parent 7a5813b4b2
commit 8d0e5bc302
37 changed files with 223 additions and 272 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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]))
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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())
}
}

View File

@@ -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())
}
}

View File

@@ -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),
}

View File

@@ -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)
}
}

View File

@@ -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;

View File

@@ -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())
}
}

View File

@@ -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)
}
}

View File

@@ -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

View File

@@ -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()] });

View File

@@ -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};

View File

@@ -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.
///

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.
///

View File

@@ -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)]

View File

@@ -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.
///

View File

@@ -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)]

View File

@@ -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)]

View File

@@ -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.
///

View File

@@ -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;

View File

@@ -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.
///

View File

@@ -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()] });

View File

@@ -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};

View File

@@ -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.
///

View File

@@ -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.

View File

@@ -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;

View File

@@ -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()
}

View File

@@ -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;

View File

@@ -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)
}
}

View File

@@ -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;

View File

@@ -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()
}
}