Merge branch 'master' into accesscontrol

This commit is contained in:
Pyfisch
2015-01-06 20:37:23 +01:00
43 changed files with 201 additions and 180 deletions

View File

@@ -25,7 +25,7 @@ use mime;
/// qitem(Mime(Text, Html, vec![])),
/// qitem(Mime(Text, Xml, vec![])) ]));
/// ```
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Accept(pub Vec<shared::QualityItem<mime::Mime>>);
deref!(Accept -> Vec<shared::QualityItem<mime::Mime>>);

View File

@@ -7,7 +7,7 @@ use header::shared;
///
/// The `Accept-Encoding` header can be used by clients to indicate what
/// response encodings they accept.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct AcceptEncoding(pub Vec<shared::QualityItem<shared::Encoding>>);
deref!(AcceptEncoding -> Vec<shared::QualityItem<shared::Encoding>>);

View File

@@ -1,12 +1,12 @@
use header::{Header, HeaderFormat};
use method::Method;
use std::fmt::{mod};
use std::fmt::{self};
use header::shared::util::{from_comma_delimited, fmt_comma_delimited};
/// The `Allow` header.
/// See also https://tools.ietf.org/html/rfc7231#section-7.4.1
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Allow(pub Vec<Method>);
deref!(Allow -> Vec<Method>);
@@ -31,7 +31,7 @@ impl HeaderFormat for Allow {
mod tests {
use super::Allow;
use header::Header;
use method::Method::{mod, Options, Get, Put, Post, Delete, Head, Trace, Connect, Patch, Extension};
use method::Method::{self, Options, Get, Put, Post, Delete, Head, Trace, Connect, Patch, Extension};
#[test]
fn test_allow() {

View File

@@ -1,19 +1,22 @@
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::{FromStr, from_utf8};
use std::ops::{Deref, DerefMut};
use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline};
use header::{Header, HeaderFormat};
/// The `Authorization` header field.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Authorization<S: Scheme>(pub S);
impl<S: Scheme> Deref<S> for Authorization<S> {
impl<S: Scheme> Deref for Authorization<S> {
type Target = S;
fn deref<'a>(&'a self) -> &'a S {
&self.0
}
}
impl<S: Scheme> DerefMut<S> for Authorization<S> {
impl<S: Scheme> DerefMut for Authorization<S> {
fn deref_mut<'a>(&'a mut self) -> &'a mut S {
&mut self.0
}
@@ -72,7 +75,7 @@ impl Scheme for String {
}
/// Credential holder for Basic Authentication
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Basic {
/// The username as a possibly empty string
pub username: String,

View File

@@ -4,7 +4,7 @@ use header::{Header, HeaderFormat};
use header::shared::util::{from_one_comma_delimited, fmt_comma_delimited};
/// The Cache-Control header.
#[deriving(PartialEq, Clone, Show)]
#[derive(PartialEq, Clone, Show)]
pub struct CacheControl(pub Vec<CacheDirective>);
deref!(CacheControl -> Vec<CacheDirective>);
@@ -34,7 +34,7 @@ impl HeaderFormat for CacheControl {
}
/// CacheControl contains a list of these directives.
#[deriving(PartialEq, Clone)]
#[derive(PartialEq, Clone)]
pub enum CacheDirective {
/// "no-cache"
NoCache,

View File

@@ -1,18 +1,18 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::FromStr;
use header::shared::util::{from_comma_delimited, fmt_comma_delimited};
pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader};
/// The `Connection` header.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Connection(pub Vec<ConnectionOption>);
deref!(Connection -> Vec<ConnectionOption>);
/// Values that can be in the `Connection` header.
#[deriving(Clone, PartialEq)]
#[derive(Clone, PartialEq)]
pub enum ConnectionOption {
/// The `keep-alive` connection value.
KeepAlive,

View File

@@ -1,4 +1,4 @@
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use header::{Header, HeaderFormat};
use header::shared::util::from_one_raw_str;
@@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str;
/// The `Content-Length` header.
///
/// Simply a wrapper around a `uint`.
#[deriving(Copy, Clone, PartialEq, Show)]
#[derive(Copy, Clone, PartialEq, Show)]
pub struct ContentLength(pub uint);
deref!(ContentLength -> uint);

View File

@@ -1,5 +1,5 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use header::shared::util::from_one_raw_str;
use mime::Mime;
@@ -7,7 +7,7 @@ use mime::Mime;
///
/// Used to describe the MIME type of message body. Can be used with both
/// requests and responses.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct ContentType(pub Mime);
deref!(ContentType -> Mime);

View File

@@ -1,5 +1,5 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::from_utf8;
use cookie::Cookie;
@@ -13,7 +13,7 @@ use cookie::CookieJar;
///
/// > When the user agent generates an HTTP request, the user agent MUST NOT
/// > attach more than one Cookie header field.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Cookies(pub Vec<Cookie>);
//TODO: remove when fixed in libstd

View File

@@ -1,4 +1,4 @@
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::FromStr;
use time::Tm;
use header::{Header, HeaderFormat};
@@ -7,7 +7,7 @@ use header::shared::time::tm_from_str;
// Egh, replace as soon as something better than time::Tm exists.
/// The `Date` header field.
#[deriving(Copy, PartialEq, Clone)]
#[derive(Copy, PartialEq, Clone)]
pub struct Date(pub Tm);
deref!(Date -> Tm);

View File

@@ -1,5 +1,5 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod};
use std::fmt::{self};
use header::shared::util::from_one_raw_str;
/// The `Etag` header.
@@ -8,7 +8,7 @@ use header::shared::util::from_one_raw_str;
/// Preceding the first double quote is an optional weakness indicator,
/// which always looks like this: W/
/// See also: https://tools.ietf.org/html/rfc7232#section-2.3
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Etag {
/// Weakness indicator for the tag
pub weak: bool,
@@ -81,7 +81,7 @@ impl Header for Etag {
impl HeaderFormat for Etag {
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
if self.weak {
try!(fmt.write(b"W/"));
try!(fmt.write_str("W/"));
}
write!(fmt, "\"{}\"", self.tag)
}

View File

@@ -1,4 +1,4 @@
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::FromStr;
use time::Tm;
use header::{Header, HeaderFormat};
@@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str;
use header::shared::time::tm_from_str;
/// The `Expires` header field.
#[deriving(Copy, PartialEq, Clone)]
#[derive(Copy, PartialEq, Clone)]
pub struct Expires(pub Tm);
deref!(Expires -> Tm);

View File

@@ -1,6 +1,6 @@
use header::{Header, HeaderFormat};
use Port;
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use header::shared::util::from_one_raw_str;
/// The `Host` header.
@@ -10,7 +10,7 @@ use header::shared::util::from_one_raw_str;
///
/// Currently is just a String, but it should probably become a better type,
/// like url::Host or something.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Host {
/// The hostname, such a example.domain.
pub hostname: String,

View File

@@ -1,4 +1,4 @@
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::FromStr;
use time::Tm;
use header::{Header, HeaderFormat};
@@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str;
use header::shared::time::tm_from_str;
/// The `If-Modified-Since` header field.
#[deriving(Copy, PartialEq, Clone)]
#[derive(Copy, PartialEq, Clone)]
pub struct IfModifiedSince(pub Tm);
deref!(IfModifiedSince -> Tm);

View File

@@ -1,4 +1,4 @@
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::FromStr;
use time::Tm;
use header::{Header, HeaderFormat};
@@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str;
use header::shared::time::tm_from_str;
/// The `LastModified` header field.
#[deriving(Copy, PartialEq, Clone)]
#[derive(Copy, PartialEq, Clone)]
pub struct LastModified(pub Tm);
deref!(LastModified -> Tm);

View File

@@ -1,5 +1,5 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use header::shared::util::from_one_raw_str;
/// The `Location` header.
@@ -13,7 +13,7 @@ use header::shared::util::from_one_raw_str;
///
/// Currently is just a String, but it should probably become a better type,
/// like url::Url or something.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Location(pub String);
deref!(Location -> String);

View File

@@ -60,13 +60,15 @@ macro_rules! bench_header(
macro_rules! deref(
($from:ty -> $to:ty) => {
impl Deref<$to> for $from {
impl ::std::ops::Deref for $from {
type Target = $to;
fn deref<'a>(&'a self) -> &'a $to {
&self.0
}
}
impl DerefMut<$to> for $from {
impl ::std::ops::DerefMut for $from {
fn deref_mut<'a>(&'a mut self) -> &'a mut $to {
&mut self.0
}

View File

@@ -1,11 +1,11 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use header::shared::util::from_one_raw_str;
/// The `Server` header field.
///
/// They can contain any value, so it just wraps a `String`.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Server(pub String);
deref!(Server -> String);

View File

@@ -1,5 +1,5 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::from_utf8;
use cookie::Cookie;
@@ -10,7 +10,7 @@ use cookie::CookieJar;
/// Informally, the Set-Cookie response header contains the header name
/// "Set-Cookie" followed by a ":" and a cookie. Each cookie begins with
/// a name-value-pair, followed by zero or more attribute-value pairs.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct SetCookie(pub Vec<Cookie>);
//TODO: remove when fixed in libstd
@@ -52,7 +52,7 @@ impl HeaderFormat for SetCookie {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, cookie) in self.0.iter().enumerate() {
if i != 0 {
try!(f.write(b"\r\nSet-Cookie: "));
try!(f.write_str("\r\nSet-Cookie: "));
}
try!(cookie.fmt(f));
}

View File

@@ -18,7 +18,7 @@ use self::Encoding::{Chunked, Gzip, Deflate, Compress, EncodingExt};
/// this header should include `chunked` as the last encoding.
///
/// The implementation uses a vector of `Encoding` values.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct TransferEncoding(pub Vec<Encoding>);
deref!(TransferEncoding -> Vec<Encoding>);
@@ -33,7 +33,7 @@ deref!(TransferEncoding -> Vec<Encoding>);
/// # use hyper::header::Headers;
/// # let mut headers = Headers::new();
/// headers.set(TransferEncoding(vec![Gzip, Chunked]));
#[deriving(Clone, PartialEq)]
#[derive(Clone, PartialEq)]
pub enum Encoding {
/// The `chunked` encoding.
Chunked,

View File

@@ -1,18 +1,18 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::str::FromStr;
use header::shared::util::{from_comma_delimited, fmt_comma_delimited};
use self::Protocol::{WebSocket, ProtocolExt};
/// The `Upgrade` header.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct Upgrade(pub Vec<Protocol>);
deref!(Upgrade -> Vec<Protocol>);
/// Protocol values that can appear in the Upgrade header.
#[deriving(Clone, PartialEq)]
#[derive(Clone, PartialEq)]
pub enum Protocol {
/// The websocket protocol.
WebSocket,

View File

@@ -1,11 +1,11 @@
use header::{Header, HeaderFormat};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use header::shared::util::from_one_raw_str;
/// The `User-Agent` header field.
///
/// They can contain any value, so it just wraps a `String`.
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub struct UserAgent(pub String);
deref!(UserAgent -> String);

View File

@@ -1,11 +1,11 @@
use header::{Header, HeaderFormat, CaseInsensitive};
use std::fmt::{mod};
use std::fmt::{self};
use header::shared::util::{from_comma_delimited, fmt_comma_delimited, from_one_raw_str};
/// The `Allow` header.
/// See also https://tools.ietf.org/html/rfc7231#section-7.1.4
#[deriving(Clone, PartialEq, Show)]
#[derive(Clone, PartialEq, Show)]
pub enum Vary {
/// This corresponds to '*'.
Any,

View File

@@ -7,18 +7,21 @@
use std::any::Any;
use std::ascii::AsciiExt;
use std::borrow::Cow::{Borrowed, Owned};
use std::fmt::{mod, Show};
use std::fmt::{self, Show};
use std::intrinsics::TypeId;
use std::raw::TraitObject;
use std::str::{SendStr, FromStr};
use std::str::{FromStr, from_utf8};
use std::string::CowString;
use std::collections::HashMap;
use std::collections::hash_map::{Iter, Entry};
use std::{hash, mem};
use std::iter::FromIterator;
use std::borrow::IntoCow;
use std::{hash, mem, raw};
use mucell::MuCell;
use uany::{UncheckedAnyDowncast, UncheckedAnyMutDowncast};
use uany::{UnsafeAnyExt};
use http::{mod, LineEnding};
use http::{self, LineEnding};
use {HttpResult};
pub use self::common::*;
@@ -81,19 +84,20 @@ impl HeaderFormat {
}
}
impl<'a> UncheckedAnyDowncast<'a> for &'a HeaderFormat {
impl UnsafeAnyExt for HeaderFormat {
#[inline]
unsafe fn downcast_ref_unchecked<T: 'static>(self) -> &'a T {
let to: TraitObject = mem::transmute_copy(&self);
mem::transmute(to.data)
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
mem::transmute(mem::transmute::<&HeaderFormat, raw::TraitObject>(self).data)
}
}
impl<'a> UncheckedAnyMutDowncast<'a> for &'a mut HeaderFormat {
#[inline]
unsafe fn downcast_mut_unchecked<T: 'static>(self) -> &'a mut T {
let to: TraitObject = mem::transmute_copy(&self);
mem::transmute(to.data)
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
mem::transmute(mem::transmute::<&mut HeaderFormat, raw::TraitObject>(self).data)
}
#[inline]
unsafe fn downcast_unchecked<T: 'static>(self: Box<HeaderFormat>) -> Box<T> {
mem::transmute(mem::transmute::<Box<HeaderFormat>, raw::TraitObject>(self).data)
}
}
@@ -110,7 +114,7 @@ fn header_name<T: Header>() -> &'static str {
}
/// A map of header fields on requests and responses.
#[deriving(Clone)]
#[derive(Clone)]
pub struct Headers {
data: HashMap<CaseInsensitive, MuCell<Item>>
}
@@ -132,8 +136,8 @@ impl Headers {
Some((name, value)) => {
debug!("raw header: {}={}", name, value[]);
let name = CaseInsensitive(Owned(name));
let mut item = match headers.data.entry(name) {
Entry::Vacant(entry) => entry.set(MuCell::new(Item::raw(vec![]))),
let mut item = match headers.data.entry(&name) {
Entry::Vacant(entry) => entry.insert(MuCell::new(Item::raw(vec![]))),
Entry::Occupied(entry) => entry.into_mut()
};
@@ -278,7 +282,9 @@ pub struct HeadersItems<'a> {
inner: Iter<'a, CaseInsensitive, MuCell<Item>>
}
impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> {
impl<'a> Iterator for HeadersItems<'a> {
type Item = HeaderView<'a>;
fn next(&mut self) -> Option<HeaderView<'a>> {
match self.inner.next() {
Some((k, v)) => Some(HeaderView(k, v)),
@@ -327,7 +333,7 @@ impl<'a> fmt::Show for HeaderView<'a> {
}
impl<'a> Extend<HeaderView<'a>> for Headers {
fn extend<I: Iterator<HeaderView<'a>>>(&mut self, mut iter: I) {
fn extend<I: Iterator<Item=HeaderView<'a>>>(&mut self, mut iter: I) {
for header in iter {
self.data.insert((*header.0).clone(), (*header.1).clone());
}
@@ -335,14 +341,14 @@ impl<'a> Extend<HeaderView<'a>> for Headers {
}
impl<'a> FromIterator<HeaderView<'a>> for Headers {
fn from_iter<I: Iterator<HeaderView<'a>>>(iter: I) -> Headers {
fn from_iter<I: Iterator<Item=HeaderView<'a>>>(iter: I) -> Headers {
let mut headers = Headers::new();
headers.extend(iter);
headers
}
}
#[deriving(Clone)]
#[derive(Clone)]
struct Item {
raw: Option<Vec<Vec<u8>>>,
typed: Option<Box<HeaderFormat + Send + Sync>>
@@ -433,7 +439,13 @@ impl fmt::Show for Item {
None => match self.raw {
Some(ref raw) => {
for part in raw.iter() {
try!(fmt.write(part.as_slice()));
match from_utf8(part[]) {
Ok(s) => try!(fmt.write_str(s)),
Err(e) => {
error!("raw header value is not utf8. header={}, error={}", part[], e);
return Err(fmt::Error);
}
}
}
Ok(())
},
@@ -450,8 +462,7 @@ impl fmt::Show for Box<HeaderFormat + Send + Sync> {
}
/// Case-insensitive string.
//#[deriving(Clone)]
pub struct CaseInsensitive(SendStr);
pub struct CaseInsensitive(CowString<'static>);
impl FromStr for CaseInsensitive {
fn from_str(s: &str) -> Option<CaseInsensitive> {
@@ -562,7 +573,7 @@ mod tests {
assert_eq!(accept, Some(Accept(vec![application_vendor, text_plain])));
}
#[deriving(Clone, Show)]
#[derive(Clone, Show)]
struct CrazyLength(Option<bool>, uint);
impl Header for CrazyLength {
@@ -641,6 +652,13 @@ mod tests {
assert_eq!(s[], "Host: foo.bar\r\nContent-Length: 15\r\n");
}
#[test]
fn test_headers_show_raw() {
let headers = Headers::from_raw(&mut mem("Content-Length: 10\r\n\r\n")).unwrap();
let s = headers.to_string();
assert_eq!(s, "Content-Length: 10\r\n");
}
#[test]
fn test_set_raw() {
let mut headers = Headers::new();

View File

@@ -7,7 +7,7 @@ pub use self::Encoding::{Chunked, Gzip, Deflate, Compress, Identity, EncodingExt
/// A value to represent an encoding used in `Transfer-Encoding`
/// or `Accept-Encoding` header.
#[deriving(Clone, PartialEq)]
#[derive(Clone, PartialEq)]
pub enum Encoding {
/// The `chunked` encoding.
Chunked,

View File

@@ -9,7 +9,7 @@ use std::str;
/// Represents an item with a quality value as defined in
/// [RFC7231](https://tools.ietf.org/html/rfc7231#section-5.3.1).
#[deriving(Clone, PartialEq)]
#[derive(Clone, PartialEq)]
pub struct QualityItem<T> {
/// The actual contents of the field.
pub item: T,
@@ -79,7 +79,7 @@ pub fn qitem<T>(item: T) -> QualityItem<T> {
#[test]
fn test_quality_item_show1() {
let x = qitem(Chunked);
assert_eq!(format!("{}", x), "chunked; q=1.000");
assert_eq!(format!("{}", x), "chunked; q=1");
}
#[test]
fn test_quality_item_show2() {
@@ -93,7 +93,7 @@ fn test_quality_item_show3() {
item: EncodingExt("identity".to_string()),
quality: 0.5f32,
};
assert_eq!(format!("{}", x), "identity; q=0.500");
assert_eq!(format!("{}", x), "identity; q=0.5");
}
#[test]

View File

@@ -9,7 +9,7 @@ pub fn from_one_raw_str<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<T> {
return None;
}
// we JUST checked that raw.len() == 1, so raw[0] WILL exist.
match str::from_utf8(unsafe { raw[].unsafe_get(0)[] }) {
match str::from_utf8(raw[0][]) {
Ok(s) => str::FromStr::from_str(s),
Err(_) => None
}
@@ -22,7 +22,7 @@ pub fn from_comma_delimited<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<Vec<T>>
return None;
}
// we JUST checked that raw.len() == 1, so raw[0] WILL exist.
from_one_comma_delimited(unsafe { raw.as_slice().unsafe_get(0).as_slice() })
from_one_comma_delimited(raw[0][])
}
/// Reads a comma-delimited raw string into a Vec.