feat(lib): switch to non-blocking (asynchronous) IO

BREAKING CHANGE: This breaks a lot of the Client and Server APIs.
  Check the documentation for how Handlers can be used for asynchronous
  events.
This commit is contained in:
Sean McArthur
2016-05-03 20:45:43 -07:00
parent 1ec56fe6b6
commit d35992d019
65 changed files with 5599 additions and 5023 deletions

View File

@@ -1,7 +1,7 @@
use std::fmt::{self, Display};
use std::str;
use unicase::UniCase;
use header::{Header, HeaderFormat};
use header::{Header};
/// `Access-Control-Allow-Credentials` header, part of
/// [CORS](http://www.w3.org/TR/cors/#access-control-allow-headers-response-header)
@@ -62,9 +62,7 @@ impl Header for AccessControlAllowCredentials {
}
Err(::Error::Header)
}
}
impl HeaderFormat for AccessControlAllowCredentials {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("true")
}
@@ -86,4 +84,4 @@ mod test_access_control_allow_credentials {
test_header!(not_bool, vec![b"false"], None);
test_header!(only_single, vec![b"true", b"true"], None);
test_header!(no_gibberish, vec!["\u{645}\u{631}\u{62d}\u{628}\u{627}".as_bytes()], None);
}
}

View File

@@ -1,6 +1,6 @@
use std::fmt::{self, Display};
use header::{Header, HeaderFormat};
use header::{Header};
/// The `Access-Control-Allow-Origin` response header,
/// part of [CORS](http://www.w3.org/TR/cors/#access-control-allow-origin-response-header)
@@ -70,9 +70,7 @@ impl Header for AccessControlAllowOrigin {
_ => AccessControlAllowOrigin::Value(try!(String::from_utf8(value.clone())))
})
}
}
impl HeaderFormat for AccessControlAllowOrigin {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
AccessControlAllowOrigin::Any => f.write_str("*"),

View File

@@ -3,7 +3,7 @@ use std::fmt::{self, Display};
use std::str::{FromStr, from_utf8};
use std::ops::{Deref, DerefMut};
use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline};
use header::{Header, HeaderFormat};
use header::{Header};
/// `Authorization` header, defined in [RFC7235](https://tools.ietf.org/html/rfc7235#section-4.2)
///
@@ -97,9 +97,7 @@ impl<S: Scheme + Any> Header for Authorization<S> where <S as FromStr>::Err: 'st
}
}
}
}
impl<S: Scheme + Any> HeaderFormat for Authorization<S> where <S as FromStr>::Err: 'static {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(scheme) = <S as Scheme>::scheme() {
try!(write!(f, "{} ", scheme))

View File

@@ -1,6 +1,6 @@
use std::fmt;
use std::str::FromStr;
use header::{Header, HeaderFormat};
use header::Header;
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
/// `Cache-Control` header, defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2)
@@ -62,9 +62,7 @@ impl Header for CacheControl {
Err(::Error::Header)
}
}
}
impl HeaderFormat for CacheControl {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt_comma_delimited(f, &self[..])
}

View File

@@ -11,7 +11,7 @@ use std::fmt;
use unicase::UniCase;
use url::percent_encoding;
use header::{Header, HeaderFormat, parsing};
use header::{Header, parsing};
use header::parsing::{parse_extended_value, HTTP_VALUE};
use header::shared::Charset;
@@ -144,9 +144,7 @@ impl Header for ContentDisposition {
Ok(cd)
})
}
}
impl HeaderFormat for ContentDisposition {
#[inline]
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self, f)

View File

@@ -1,6 +1,6 @@
use std::fmt;
use header::{HeaderFormat, Header, parsing};
use header::{Header, parsing};
/// `Content-Length` header, defined in
/// [RFC7230](http://tools.ietf.org/html/rfc7230#section-3.3.2)
@@ -55,9 +55,7 @@ impl Header for ContentLength {
.unwrap_or(Err(::Error::Header))
.map(ContentLength)
}
}
impl HeaderFormat for ContentLength {
#[inline]
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)

View File

@@ -1,4 +1,4 @@
use header::{Header, HeaderFormat, CookiePair, CookieJar};
use header::{Header, CookiePair, CookieJar};
use std::fmt::{self, Display};
use std::str::from_utf8;
@@ -61,9 +61,7 @@ impl Header for Cookie {
Err(::Error::Header)
}
}
}
impl HeaderFormat for Cookie {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
let cookies = &self.0;
for (i, cookie) in cookies.iter().enumerate() {

View File

@@ -3,7 +3,7 @@ use std::str;
use unicase::UniCase;
use header::{Header, HeaderFormat};
use header::{Header};
/// The `Expect` header.
///
@@ -53,9 +53,7 @@ impl Header for Expect {
Err(::Error::Header)
}
}
}
impl HeaderFormat for Expect {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("100-continue")
}

View File

@@ -1,4 +1,4 @@
use header::{Header, HeaderFormat};
use header::{Header};
use std::fmt;
use header::parsing::from_one_raw_str;
@@ -52,9 +52,7 @@ impl Header for Host {
// https://github.com/servo/rust-url/issues/42
let idx = {
let slice = &s[..];
let mut chars = slice.chars();
chars.next();
if chars.next().unwrap() == '[' {
if slice.starts_with('[') {
match slice.rfind(']') {
Some(idx) => {
if slice.len() > idx + 2 {
@@ -86,9 +84,7 @@ impl Header for Host {
})
})
}
}
impl HeaderFormat for Host {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.port {
None | Some(80) | Some(443) => f.write_str(&self.hostname[..]),

View File

@@ -1,5 +1,5 @@
use std::fmt::{self, Display};
use header::{self, Header, HeaderFormat, EntityTag, HttpDate};
use header::{self, Header, EntityTag, HttpDate};
/// `If-Range` header, defined in [RFC7233](http://tools.ietf.org/html/rfc7233#section-3.2)
///
@@ -59,18 +59,16 @@ impl Header for IfRange {
}
fn parse_header(raw: &[Vec<u8>]) -> ::Result<IfRange> {
let etag: ::Result<EntityTag> = header::parsing::from_one_raw_str(raw);
if etag.is_ok() {
return Ok(IfRange::EntityTag(etag.unwrap()));
if let Ok(etag) = etag {
return Ok(IfRange::EntityTag(etag));
}
let date: ::Result<HttpDate> = header::parsing::from_one_raw_str(raw);
if date.is_ok() {
return Ok(IfRange::Date(date.unwrap()));
if let Ok(date) = date {
return Ok(IfRange::Date(date));
}
Err(::Error::Header)
}
}
impl HeaderFormat for IfRange {
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self {
IfRange::EntityTag(ref x) => Display::fmt(x, f),

View File

@@ -66,7 +66,7 @@ macro_rules! bench_header(
use test::Bencher;
use super::*;
use header::{Header, HeaderFormatter};
use header::{Header};
#[bench]
fn bench_parse(b: &mut Bencher) {
@@ -79,7 +79,7 @@ macro_rules! bench_header(
#[bench]
fn bench_format(b: &mut Bencher) {
let val: $ty = Header::parse_header(&$value[..]).unwrap();
let fmt = HeaderFormatter(&val);
let fmt = ::header::HeaderFormatter(&val);
b.iter(|| {
format!("{}", fmt);
});
@@ -222,15 +222,13 @@ macro_rules! header {
fn parse_header(raw: &[Vec<u8>]) -> $crate::Result<Self> {
$crate::header::parsing::from_comma_delimited(raw).map($id)
}
}
impl $crate::header::HeaderFormat for $id {
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
$crate::header::parsing::fmt_comma_delimited(f, &self.0[..])
}
}
impl ::std::fmt::Display for $id {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use $crate::header::HeaderFormat;
use $crate::header::Header;
self.fmt_header(f)
}
}
@@ -250,15 +248,13 @@ macro_rules! header {
fn parse_header(raw: &[Vec<u8>]) -> $crate::Result<Self> {
$crate::header::parsing::from_comma_delimited(raw).map($id)
}
}
impl $crate::header::HeaderFormat for $id {
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
$crate::header::parsing::fmt_comma_delimited(f, &self.0[..])
}
}
impl ::std::fmt::Display for $id {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use $crate::header::HeaderFormat;
use $crate::header::Header;
self.fmt_header(f)
}
}
@@ -277,8 +273,6 @@ macro_rules! header {
fn parse_header(raw: &[Vec<u8>]) -> $crate::Result<Self> {
$crate::header::parsing::from_one_raw_str(raw).map($id)
}
}
impl $crate::header::HeaderFormat for $id {
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::std::fmt::Display::fmt(&**self, f)
}
@@ -313,8 +307,6 @@ macro_rules! header {
}
$crate::header::parsing::from_comma_delimited(raw).map($id::Items)
}
}
impl $crate::header::HeaderFormat for $id {
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self {
$id::Any => f.write_str("*"),
@@ -325,7 +317,7 @@ macro_rules! header {
}
impl ::std::fmt::Display for $id {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use $crate::header::HeaderFormat;
use $crate::header::Header;
self.fmt_header(f)
}
}

View File

@@ -1,7 +1,7 @@
use std::fmt;
use std::ascii::AsciiExt;
use header::{Header, HeaderFormat, parsing};
use header::{Header, parsing};
/// The `Pragma` header defined by HTTP/1.0.
///
@@ -52,9 +52,7 @@ impl Header for Pragma {
}
})
}
}
impl HeaderFormat for Pragma {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
Pragma::NoCache => "no-cache",

View File

@@ -1,6 +1,6 @@
use std::fmt;
use std::str::FromStr;
use header::{Header, HeaderFormat};
use header::{Header};
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
/// `Prefer` header, defined in [RFC7240](http://tools.ietf.org/html/rfc7240)
@@ -64,9 +64,7 @@ impl Header for Prefer {
Err(::Error::Header)
}
}
}
impl HeaderFormat for Prefer {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt_comma_delimited(f, &self[..])
}

View File

@@ -1,5 +1,5 @@
use std::fmt;
use header::{Header, HeaderFormat, Preference};
use header::{Header, Preference};
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
/// `Preference-Applied` header, defined in [RFC7240](http://tools.ietf.org/html/rfc7240)
@@ -61,9 +61,7 @@ impl Header for PreferenceApplied {
Err(::Error::Header)
}
}
}
impl HeaderFormat for PreferenceApplied {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
let preferences: Vec<_> = self.0.iter().map(|pref| match pref {
// The spec ignores parameters in `Preferences-Applied`
@@ -80,7 +78,7 @@ impl HeaderFormat for PreferenceApplied {
#[cfg(test)]
mod tests {
use header::{HeaderFormat, Preference};
use header::{Header, Preference};
use super::*;
#[test]
@@ -90,7 +88,7 @@ mod tests {
"foo".to_owned(),
"bar".to_owned(),
vec![("bar".to_owned(), "foo".to_owned()), ("buz".to_owned(), "".to_owned())]
)]) as &(HeaderFormat + Send + Sync)),
)]) as &(Header + Send + Sync)),
"foo=bar".to_owned()
);
}

View File

@@ -1,7 +1,7 @@
use std::fmt::{self, Display};
use std::str::FromStr;
use header::{Header, HeaderFormat};
use header::Header;
use header::parsing::{from_one_raw_str, from_comma_delimited};
/// `Range` header, defined in [RFC7233](https://tools.ietf.org/html/rfc7233#section-3.1)
@@ -182,9 +182,6 @@ impl Header for Range {
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Range> {
from_one_raw_str(raw)
}
}
impl HeaderFormat for Range {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(self, f)

View File

@@ -1,4 +1,4 @@
use header::{Header, HeaderFormat, CookiePair, CookieJar};
use header::{Header, CookiePair, CookieJar};
use std::fmt::{self, Display};
use std::str::from_utf8;
@@ -104,10 +104,6 @@ impl Header for SetCookie {
}
}
}
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 {

View File

@@ -3,7 +3,7 @@ use std::str::{self, FromStr};
use unicase::UniCase;
use header::{Header, HeaderFormat, parsing};
use header::{Header, parsing};
/// `StrictTransportSecurity` header, defined in [RFC6797](https://tools.ietf.org/html/rfc6797)
///
@@ -127,9 +127,7 @@ impl Header for StrictTransportSecurity {
fn parse_header(raw: &[Vec<u8>]) -> ::Result<StrictTransportSecurity> {
parsing::from_one_raw_str(raw)
}
}
impl HeaderFormat for StrictTransportSecurity {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.include_subdomains {
write!(f, "max-age={}; includeSubdomains", self.max_age)

View File

@@ -49,5 +49,12 @@ header! {
}
}
impl TransferEncoding {
/// Constructor for the most common Transfer-Encoding, `chunked`.
pub fn chunked() -> TransferEncoding {
TransferEncoding(vec![Encoding::Chunked])
}
}
bench_header!(normal, TransferEncoding, { vec![b"chunked, gzip".to_vec()] });
bench_header!(ext, TransferEncoding, { vec![b"ext".to_vec()] });