@@ -1,4 +1,4 @@
|
||||
#![feature(core, io, test)]
|
||||
#![feature(core, old_io, test)]
|
||||
extern crate hyper;
|
||||
|
||||
extern crate test;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(collections, io, test)]
|
||||
#![feature(collections, old_io, test)]
|
||||
extern crate hyper;
|
||||
|
||||
extern crate test;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(io, test)]
|
||||
#![feature(old_io, test)]
|
||||
extern crate hyper;
|
||||
extern crate test;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(env, io)]
|
||||
#![feature(env, old_io)]
|
||||
extern crate hyper;
|
||||
|
||||
use std::env;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(io)]
|
||||
#![feature(old_io)]
|
||||
extern crate hyper;
|
||||
|
||||
use std::old_io::net::ip::Ipv4Addr;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(io)]
|
||||
#![feature(old_io)]
|
||||
extern crate hyper;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
@@ -21,7 +21,7 @@ macro_rules! try_return(
|
||||
|
||||
fn echo(mut req: Request, mut res: Response) {
|
||||
match req.uri {
|
||||
AbsolutePath(ref path) => match (&req.method, &path[]) {
|
||||
AbsolutePath(ref path) => match (&req.method, &path[..]) {
|
||||
(&Get, "/") | (&Get, "/echo") => {
|
||||
let out = b"Try POST /echo";
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ impl<'a, U: IntoUrl, C: NetworkConnector> RequestBuilder<'a, U, C> {
|
||||
// punching borrowck here
|
||||
let loc = match res.headers.get::<Location>() {
|
||||
Some(&Location(ref loc)) => {
|
||||
Some(UrlParser::new().base_url(&url).parse(&loc[]))
|
||||
Some(UrlParser::new().base_url(&url).parse(&loc[..]))
|
||||
}
|
||||
None => {
|
||||
debug!("no Location header");
|
||||
@@ -394,7 +394,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_redirect_followif() {
|
||||
fn follow_if(url: &Url) -> bool {
|
||||
!url.serialize()[].contains("127.0.0.3")
|
||||
!url.serialize().contains("127.0.0.3")
|
||||
}
|
||||
let mut client = Client::with_connector(MockRedirectPolicy);
|
||||
client.set_redirect_policy(RedirectPolicy::FollowIf(follow_if));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Client Requests
|
||||
use std::old_io::{BufferedWriter, IoResult};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use url::Url;
|
||||
|
||||
@@ -25,8 +26,13 @@ pub struct Request<W> {
|
||||
body: HttpWriter<BufferedWriter<Box<NetworkStream + Send>>>,
|
||||
headers: Headers,
|
||||
method: method::Method,
|
||||
|
||||
_marker: PhantomData<W>,
|
||||
}
|
||||
|
||||
//FIXME: remove once https://github.com/rust-lang/issues/22629 is fixed
|
||||
unsafe impl<W> Send for Request<W> {}
|
||||
|
||||
impl<W> Request<W> {
|
||||
/// Read the Request headers.
|
||||
#[inline]
|
||||
@@ -66,7 +72,8 @@ impl Request<Fresh> {
|
||||
headers: headers,
|
||||
url: url,
|
||||
version: version::HttpVersion::Http11,
|
||||
body: stream
|
||||
body: stream,
|
||||
_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -77,7 +84,7 @@ impl Request<Fresh> {
|
||||
//TODO: this needs a test
|
||||
if let Some(ref q) = self.url.query {
|
||||
uri.push('?');
|
||||
uri.push_str(&q[]);
|
||||
uri.push_str(&q[..]);
|
||||
}
|
||||
|
||||
debug!("writing head: {:?} {:?} {:?}", self.method, uri, self.version);
|
||||
@@ -136,7 +143,8 @@ impl Request<Fresh> {
|
||||
headers: self.headers,
|
||||
url: self.url,
|
||||
version: self.version,
|
||||
body: stream
|
||||
body: stream,
|
||||
_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -185,7 +193,7 @@ mod tests {
|
||||
let stream = *req.body.end().unwrap()
|
||||
.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||
let bytes = stream.write.into_inner();
|
||||
let s = from_utf8(&bytes[]).unwrap();
|
||||
let s = from_utf8(&bytes[..]).unwrap();
|
||||
assert!(!s.contains("Content-Length:"));
|
||||
assert!(!s.contains("Transfer-Encoding:"));
|
||||
}
|
||||
@@ -199,7 +207,7 @@ mod tests {
|
||||
let stream = *req.body.end().unwrap()
|
||||
.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||
let bytes = stream.write.into_inner();
|
||||
let s = from_utf8(&bytes[]).unwrap();
|
||||
let s = from_utf8(&bytes[..]).unwrap();
|
||||
assert!(!s.contains("Content-Length:"));
|
||||
assert!(!s.contains("Transfer-Encoding:"));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Client Responses
|
||||
use std::num::FromPrimitive;
|
||||
use std::old_io::{BufferedReader, IoResult};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use header;
|
||||
use header::{ContentLength, TransferEncoding};
|
||||
@@ -23,8 +24,13 @@ pub struct Response<S = HttpStream> {
|
||||
pub version: version::HttpVersion,
|
||||
status_raw: RawStatus,
|
||||
body: HttpReader<BufferedReader<Box<NetworkStream + Send>>>,
|
||||
|
||||
_marker: PhantomData<S>,
|
||||
}
|
||||
|
||||
//FIXME: remove once https://github.com/rust-lang/issues/22629 is fixed
|
||||
unsafe impl<S: Send> Send for Response<S> {}
|
||||
|
||||
impl Response {
|
||||
|
||||
/// Creates a new response from a server.
|
||||
@@ -72,6 +78,7 @@ impl Response {
|
||||
headers: headers,
|
||||
body: body,
|
||||
status_raw: raw_status,
|
||||
_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -98,6 +105,7 @@ mod tests {
|
||||
use std::borrow::Cow::Borrowed;
|
||||
use std::boxed::BoxAny;
|
||||
use std::old_io::BufferedReader;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use header::Headers;
|
||||
use header::TransferEncoding;
|
||||
@@ -119,7 +127,8 @@ mod tests {
|
||||
headers: Headers::new(),
|
||||
version: version::HttpVersion::Http11,
|
||||
body: EofReader(BufferedReader::new(box MockStream::new() as Box<NetworkStream + Send>)),
|
||||
status_raw: RawStatus(200, Borrowed("OK"))
|
||||
status_raw: RawStatus(200, Borrowed("OK")),
|
||||
_marker: PhantomData,
|
||||
};
|
||||
|
||||
let b = res.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||
|
||||
@@ -29,7 +29,7 @@ impl header::Header for AccessControlAllowOrigin {
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowOrigin> {
|
||||
if raw.len() == 1 {
|
||||
match str::from_utf8(unsafe { &raw[].get_unchecked(0)[] }) {
|
||||
match str::from_utf8(unsafe { &raw.get_unchecked(0)[..] }) {
|
||||
Ok(s) => {
|
||||
if s == "*" {
|
||||
Some(AccessControlAllowOrigin::AllowStar)
|
||||
|
||||
@@ -22,14 +22,14 @@ impl<S: Scheme> DerefMut for Authorization<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Scheme> Header for Authorization<S> {
|
||||
impl<S: Scheme + 'static> Header for Authorization<S> where <S as FromStr>::Err: 'static {
|
||||
fn header_name() -> &'static str {
|
||||
"Authorization"
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<Authorization<S>> {
|
||||
if raw.len() == 1 {
|
||||
match (from_utf8(unsafe { &raw[].get_unchecked(0)[] }), Scheme::scheme(None::<S>)) {
|
||||
match (from_utf8(unsafe { &raw.get_unchecked(0)[..] }), Scheme::scheme(None::<S>)) {
|
||||
(Ok(header), Some(scheme))
|
||||
if header.starts_with(scheme) && header.len() > scheme.len() + 1 => {
|
||||
header[scheme.len() + 1..].parse::<S>().map(|s| Authorization(s)).ok()
|
||||
@@ -43,7 +43,7 @@ impl<S: Scheme> Header for Authorization<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Scheme> HeaderFormat for Authorization<S> {
|
||||
impl<S: Scheme + 'static> HeaderFormat for Authorization<S> where <S as FromStr>::Err: 'static {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match Scheme::scheme(None::<S>) {
|
||||
Some(scheme) => try!(write!(fmt, "{} ", scheme)),
|
||||
@@ -96,7 +96,7 @@ impl Scheme for Basic {
|
||||
let mut text = self.username.clone();
|
||||
text.push(':');
|
||||
if let Some(ref pass) = self.password {
|
||||
text.push_str(&pass[]);
|
||||
text.push_str(&pass[..]);
|
||||
}
|
||||
write!(f, "{}", text.as_bytes().to_base64(Config {
|
||||
char_set: Standard,
|
||||
@@ -113,7 +113,7 @@ impl FromStr for Basic {
|
||||
match s.from_base64() {
|
||||
Ok(decoded) => match String::from_utf8(decoded) {
|
||||
Ok(text) => {
|
||||
let mut parts = &mut text[].split(':');
|
||||
let mut parts = &mut text.split(':');
|
||||
let user = match parts.next() {
|
||||
Some(part) => part.to_string(),
|
||||
None => return Err(())
|
||||
@@ -160,7 +160,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_raw_auth_parse() {
|
||||
let headers = Headers::from_raw(&mut mem("Authorization: foo bar baz\r\n\r\n")).unwrap();
|
||||
assert_eq!(&headers.get::<Authorization<String>>().unwrap().0[], "foo bar baz");
|
||||
assert_eq!(&headers.get::<Authorization<String>>().unwrap().0[..], "foo bar baz");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -181,7 +181,7 @@ mod tests {
|
||||
fn test_basic_auth_parse() {
|
||||
let headers = Headers::from_raw(&mut mem("Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n\r\n")).unwrap();
|
||||
let auth = headers.get::<Authorization<Basic>>().unwrap();
|
||||
assert_eq!(&auth.0.username[], "Aladdin");
|
||||
assert_eq!(&auth.0.username[..], "Aladdin");
|
||||
assert_eq!(auth.0.password, Some("open sesame".to_string()));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ impl Header for CacheControl {
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<CacheControl> {
|
||||
let directives = raw.iter()
|
||||
.filter_map(|line| from_one_comma_delimited(&line[]))
|
||||
.filter_map(|line| from_one_comma_delimited(&line[..]))
|
||||
.collect::<Vec<Vec<CacheDirective>>>()
|
||||
.concat();
|
||||
if directives.len() > 0 {
|
||||
@@ -29,7 +29,7 @@ impl Header for CacheControl {
|
||||
|
||||
impl HeaderFormat for CacheControl {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt_comma_delimited(fmt, &self[])
|
||||
fmt_comma_delimited(fmt, &self[..])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ impl fmt::Display for CacheDirective {
|
||||
ProxyRevalidate => "proxy-revalidate",
|
||||
SMaxAge(secs) => return write!(f, "s-maxage={}", secs),
|
||||
|
||||
Extension(ref name, None) => &name[],
|
||||
Extension(ref name, None) => &name[..],
|
||||
Extension(ref name, Some(ref arg)) => return write!(f, "{}={}", name, arg),
|
||||
|
||||
}, f)
|
||||
|
||||
@@ -64,7 +64,7 @@ impl Header for Connection {
|
||||
impl HeaderFormat for Connection {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Connection(ref parts) = *self;
|
||||
fmt_comma_delimited(fmt, &parts[])
|
||||
fmt_comma_delimited(fmt, &parts[..])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ impl Header for Cookie {
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<Cookie> {
|
||||
let mut cookies = Vec::with_capacity(raw.len());
|
||||
for cookies_raw in raw.iter() {
|
||||
match from_utf8(&cookies_raw[]) {
|
||||
match from_utf8(&cookies_raw[..]) {
|
||||
Ok(cookies_str) => {
|
||||
for cookie_str in cookies_str.split(';') {
|
||||
match cookie_str.trim().parse() {
|
||||
@@ -82,7 +82,7 @@ impl Cookie {
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let h = Header::parse_header(&[b"foo=bar; baz=quux".to_vec()][]);
|
||||
let h = Header::parse_header(&[b"foo=bar; baz=quux".to_vec()][..]);
|
||||
let c1 = CookiePair::new("foo".to_string(), "bar".to_string());
|
||||
let c2 = CookiePair::new("baz".to_string(), "quux".to_string());
|
||||
assert_eq!(h, Some(Cookie(vec![c1, c2])));
|
||||
@@ -99,7 +99,7 @@ fn test_fmt() {
|
||||
let mut headers = Headers::new();
|
||||
headers.set(cookie_header);
|
||||
|
||||
assert_eq!(&headers.to_string()[], "Cookie: foo=bar; baz=quux\r\n");
|
||||
assert_eq!(&headers.to_string()[..], "Cookie: foo=bar; baz=quux\r\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -28,7 +28,7 @@ impl Header for Host {
|
||||
// FIXME: use rust-url to parse this
|
||||
// https://github.com/servo/rust-url/issues/42
|
||||
let idx = {
|
||||
let slice = &s[];
|
||||
let slice = &s[..];
|
||||
if slice.char_at(1) == '[' {
|
||||
match slice.rfind(']') {
|
||||
Some(idx) => {
|
||||
|
||||
@@ -25,7 +25,7 @@ impl Header for IfMatch {
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<IfMatch> {
|
||||
from_one_raw_str(raw).and_then(|s: String| {
|
||||
let slice = &s[];
|
||||
let slice = &s[..];
|
||||
match slice {
|
||||
"" => None,
|
||||
"*" => Some(IfMatch::Any),
|
||||
@@ -39,7 +39,7 @@ impl HeaderFormat for IfMatch {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
IfMatch::Any => write!(fmt, "*"),
|
||||
IfMatch::EntityTags(ref fields) => fmt_comma_delimited(fmt, &fields[])
|
||||
IfMatch::EntityTags(ref fields) => fmt_comma_delimited(fmt, &fields[..])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ impl Header for IfNoneMatch {
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<IfNoneMatch> {
|
||||
from_one_raw_str(raw).and_then(|s: String| {
|
||||
let slice = &s[];
|
||||
let slice = &s[..];
|
||||
match slice {
|
||||
"" => None,
|
||||
"*" => Some(IfNoneMatch::Any),
|
||||
@@ -47,7 +47,7 @@ impl HeaderFormat for IfNoneMatch {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
IfNoneMatch::Any => { write!(fmt, "*") }
|
||||
IfNoneMatch::EntityTags(ref fields) => { fmt_comma_delimited(fmt, &fields[]) }
|
||||
IfNoneMatch::EntityTags(ref fields) => { fmt_comma_delimited(fmt, &fields[..]) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,13 +50,13 @@ macro_rules! bench_header(
|
||||
fn bench_parse(b: &mut Bencher) {
|
||||
let val = $value;
|
||||
b.iter(|| {
|
||||
let _: $ty = Header::parse_header(&val[]).unwrap();
|
||||
let _: $ty = Header::parse_header(&val[..]).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_format(b: &mut Bencher) {
|
||||
let val: $ty = Header::parse_header(&$value[]).unwrap();
|
||||
let val: $ty = Header::parse_header(&$value[..]).unwrap();
|
||||
let fmt = HeaderFormatter(&val);
|
||||
b.iter(|| {
|
||||
format!("{}", fmt);
|
||||
@@ -102,7 +102,7 @@ macro_rules! impl_list_header(
|
||||
|
||||
impl $crate::header::HeaderFormat for $from {
|
||||
fn fmt_header(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
$crate::header::parsing::fmt_comma_delimited(fmt, &self[])
|
||||
$crate::header::parsing::fmt_comma_delimited(fmt, &self[..])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ impl Header for Pragma {
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<Pragma> {
|
||||
parsing::from_one_raw_str(raw).and_then(|s: String| {
|
||||
let slice = &s.to_ascii_lowercase()[];
|
||||
let slice = &s.to_ascii_lowercase()[..];
|
||||
match slice {
|
||||
"" => None,
|
||||
"no-cache" => Some(Pragma::NoCache),
|
||||
|
||||
@@ -23,7 +23,7 @@ impl Header for SetCookie {
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<SetCookie> {
|
||||
let mut set_cookies = Vec::with_capacity(raw.len());
|
||||
for set_cookies_raw in raw.iter() {
|
||||
match from_utf8(&set_cookies_raw[]) {
|
||||
match from_utf8(&set_cookies_raw[..]) {
|
||||
Ok(s) if !s.is_empty() => {
|
||||
match s.parse() {
|
||||
Ok(cookie) => set_cookies.push(cookie),
|
||||
@@ -76,7 +76,7 @@ impl SetCookie {
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let h = Header::parse_header(&[b"foo=bar; HttpOnly".to_vec()][]);
|
||||
let h = Header::parse_header(&[b"foo=bar; HttpOnly".to_vec()][..]);
|
||||
let mut c1 = Cookie::new("foo".to_string(), "bar".to_string());
|
||||
c1.httponly = true;
|
||||
|
||||
@@ -94,7 +94,7 @@ fn test_fmt() {
|
||||
let mut headers = Headers::new();
|
||||
headers.set(cookies);
|
||||
|
||||
assert_eq!(&headers.to_string()[], "Set-Cookie: foo=bar; HttpOnly; Path=/p\r\nSet-Cookie: baz=quux; Path=/\r\n");
|
||||
assert_eq!(&headers.to_string()[..], "Set-Cookie: foo=bar; HttpOnly; Path=/p\r\nSet-Cookie: baz=quux; Path=/\r\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -55,7 +55,7 @@ impl Header for Upgrade {
|
||||
impl HeaderFormat for Upgrade {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Upgrade(ref parts) = *self;
|
||||
fmt_comma_delimited(fmt, &parts[])
|
||||
fmt_comma_delimited(fmt, &parts[..])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ impl Header for Vary {
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<Vary> {
|
||||
from_one_raw_str(raw).and_then(|s: String| {
|
||||
let slice = &s[];
|
||||
let slice = &s[..];
|
||||
match slice {
|
||||
"" => None,
|
||||
"*" => Some(Vary::Any),
|
||||
@@ -35,7 +35,7 @@ impl HeaderFormat for Vary {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Vary::Any => { write!(fmt, "*") }
|
||||
Vary::Headers(ref fields) => { fmt_comma_delimited(fmt, &fields[]) }
|
||||
Vary::Headers(ref fields) => { fmt_comma_delimited(fmt, &fields[..]) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,10 @@ use std::borrow::Cow::{Borrowed, Owned};
|
||||
use std::fmt;
|
||||
use std::raw::TraitObject;
|
||||
use std::str::from_utf8;
|
||||
use std::string::CowString;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::{Iter, Entry};
|
||||
use std::iter::FromIterator;
|
||||
use std::borrow::IntoCow;
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use std::borrow::{Cow, IntoCow};
|
||||
use std::{mem, raw};
|
||||
|
||||
use uany::{UnsafeAnyExt};
|
||||
@@ -30,7 +29,7 @@ mod common;
|
||||
mod shared;
|
||||
pub mod parsing;
|
||||
|
||||
type HeaderName = UniCase<CowString<'static>>;
|
||||
type HeaderName = UniCase<Cow<'static, str>>;
|
||||
|
||||
/// A trait for any object that will represent a header field and value.
|
||||
///
|
||||
@@ -139,7 +138,7 @@ impl Headers {
|
||||
loop {
|
||||
match try!(http::read_header(rdr)) {
|
||||
Some((name, value)) => {
|
||||
debug!("raw header: {:?}={:?}", name, &value[]);
|
||||
debug!("raw header: {:?}={:?}", name, &value[..]);
|
||||
count += (name.len() + value.len()) as u32;
|
||||
if count > MAX_HEADERS_LENGTH {
|
||||
debug!("Max header size reached, aborting");
|
||||
@@ -183,14 +182,14 @@ impl Headers {
|
||||
.get(&UniCase(Borrowed(unsafe { mem::transmute::<&str, &str>(name) })))
|
||||
.and_then(|item| {
|
||||
if let Some(ref raw) = *item.raw {
|
||||
return Some(&raw[]);
|
||||
return Some(&raw[..]);
|
||||
}
|
||||
|
||||
let raw = vec![item.typed.as_ref().unwrap().to_string().into_bytes()];
|
||||
item.raw.set(raw);
|
||||
|
||||
let raw = item.raw.as_ref().unwrap();
|
||||
Some(&raw[])
|
||||
Some(&raw[..])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -203,7 +202,7 @@ impl Headers {
|
||||
/// # let mut headers = Headers::new();
|
||||
/// headers.set_raw("content-length", vec![b"5".to_vec()]);
|
||||
/// ```
|
||||
pub fn set_raw<K: IntoCow<'static, String, str>>(&mut self, name: K, value: Vec<Vec<u8>>) {
|
||||
pub fn set_raw<K: IntoCow<'static, str>>(&mut self, name: K, value: Vec<Vec<u8>>) {
|
||||
self.data.insert(UniCase(name.into_cow()), Item::new_raw(value));
|
||||
}
|
||||
|
||||
@@ -351,7 +350,7 @@ impl<'a> fmt::Debug for HeaderView<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Extend<HeaderView<'a>> for Headers {
|
||||
fn extend<I: Iterator<Item=HeaderView<'a>>>(&mut self, iter: I) {
|
||||
fn extend<I: IntoIterator<Item=HeaderView<'a>>>(&mut self, iter: I) {
|
||||
for header in iter {
|
||||
self.data.insert((*header.0).clone(), (*header.1).clone());
|
||||
}
|
||||
@@ -359,7 +358,7 @@ impl<'a> Extend<HeaderView<'a>> for Headers {
|
||||
}
|
||||
|
||||
impl<'a> FromIterator<HeaderView<'a>> for Headers {
|
||||
fn from_iter<I: Iterator<Item=HeaderView<'a>>>(iter: I) -> Headers {
|
||||
fn from_iter<I: IntoIterator<Item=HeaderView<'a>>>(iter: I) -> Headers {
|
||||
let mut headers = Headers::new();
|
||||
headers.extend(iter);
|
||||
headers
|
||||
@@ -451,7 +450,7 @@ fn get_or_parse_mut<H: Header + HeaderFormat>(item: &mut Item) -> Option<&mut It
|
||||
|
||||
fn parse<H: Header + HeaderFormat>(item: &Item) {
|
||||
match *item.raw {
|
||||
Some(ref raw) => match Header::parse_header(&raw[]) {
|
||||
Some(ref raw) => match Header::parse_header(&raw[..]) {
|
||||
Some::<H>(h) => item.typed.set(box h as Box<HeaderFormat + Send + Sync>),
|
||||
None => ()
|
||||
},
|
||||
@@ -476,7 +475,7 @@ impl fmt::Display for Item {
|
||||
None => match *self.raw {
|
||||
Some(ref raw) => {
|
||||
for part in raw.iter() {
|
||||
match from_utf8(&part[]) {
|
||||
match from_utf8(&part[..]) {
|
||||
Ok(s) => try!(fmt.write_str(s)),
|
||||
Err(e) => {
|
||||
error!("raw header value is not utf8. header={:?}, error={:?}", part, e);
|
||||
@@ -532,12 +531,9 @@ impl<'a, H: HeaderFormat> fmt::Debug for HeaderFormatter<'a, H> {
|
||||
mod tests {
|
||||
use std::old_io::MemReader;
|
||||
use std::fmt;
|
||||
use std::borrow::Cow::Borrowed;
|
||||
use std::hash::{SipHasher, hash};
|
||||
use mime::Mime;
|
||||
use mime::TopLevel::Text;
|
||||
use mime::SubLevel::Plain;
|
||||
use unicase::UniCase;
|
||||
use super::{Headers, Header, HeaderFormat, ContentLength, ContentType,
|
||||
Accept, Host, QualityItem};
|
||||
|
||||
@@ -547,15 +543,6 @@ mod tests {
|
||||
MemReader::new(s.as_bytes().to_vec())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_insensitive() {
|
||||
let a = UniCase(Borrowed("foobar"));
|
||||
let b = UniCase(Borrowed("FOOBAR"));
|
||||
|
||||
assert_eq!(a, b);
|
||||
assert_eq!(hash::<_, SipHasher>(&a), hash::<_, SipHasher>(&b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_raw() {
|
||||
let headers = Headers::from_raw(&mut mem("Content-Length: 10\r\n\r\n")).unwrap();
|
||||
@@ -595,7 +582,7 @@ mod tests {
|
||||
return None;
|
||||
}
|
||||
// we JUST checked that raw.len() == 1, so raw[0] WILL exist.
|
||||
match from_utf8(unsafe { &raw[].get_unchecked(0)[] }) {
|
||||
match from_utf8(unsafe { &raw.get_unchecked(0)[..] }) {
|
||||
Ok(s) => FromStr::from_str(s).ok(),
|
||||
Err(_) => None
|
||||
}.map(|u| CrazyLength(Some(false), u))
|
||||
@@ -671,7 +658,7 @@ mod tests {
|
||||
let mut headers = Headers::new();
|
||||
headers.set(ContentLength(10));
|
||||
headers.set_raw("content-LENGTH", vec![b"20".to_vec()]);
|
||||
assert_eq!(headers.get_raw("Content-length").unwrap(), &[b"20".to_vec()][]);
|
||||
assert_eq!(headers.get_raw("Content-length").unwrap(), &[b"20".to_vec()][..]);
|
||||
assert_eq!(headers.get(), Some(&ContentLength(20)));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,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(&raw[0][]) {
|
||||
match str::from_utf8(&raw[0][..]) {
|
||||
Ok(s) => str::FromStr::from_str(s).ok(),
|
||||
Err(_) => None
|
||||
}
|
||||
@@ -24,7 +24,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(&raw[0][])
|
||||
from_one_comma_delimited(&raw[0][..])
|
||||
}
|
||||
|
||||
/// Reads a comma-delimited raw string into a Vec.
|
||||
|
||||
@@ -42,7 +42,7 @@ impl FromStr for EntityTag {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<EntityTag, ()> {
|
||||
let length: usize = s.len();
|
||||
let slice = &s[];
|
||||
let slice = &s[..];
|
||||
|
||||
// Early exits:
|
||||
// 1. The string is empty, or,
|
||||
|
||||
@@ -39,7 +39,7 @@ impl<T: fmt::Display> fmt::Display for QualityItem<T> {
|
||||
write!(f, "{}", self.item)
|
||||
} else {
|
||||
write!(f, "{}; q={}", self.item,
|
||||
format!("{:.3}", self.quality).trim_right_matches(&['0', '.'][]))
|
||||
format!("{:.3}", self.quality).trim_right_matches(&['0', '.'][..]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
//! Pieces pertaining to the HTTP message protocol.
|
||||
use std::borrow::Cow::{Borrowed, Owned};
|
||||
use std::borrow::Cow::{self, Borrowed, Owned};
|
||||
use std::borrow::IntoCow;
|
||||
use std::cmp::min;
|
||||
use std::old_io::{self, Reader, IoResult, BufWriter};
|
||||
use std::num::from_u16;
|
||||
use std::str;
|
||||
use std::string::CowString;
|
||||
|
||||
use url::Url;
|
||||
use url::ParseError as UrlError;
|
||||
@@ -395,7 +394,7 @@ pub fn read_method<R: Reader>(stream: &mut R) -> HttpResult<method::Method> {
|
||||
|
||||
debug!("maybe_method = {:?}", maybe_method);
|
||||
|
||||
match (maybe_method, &buf[]) {
|
||||
match (maybe_method, &buf[..]) {
|
||||
(Some(method), _) => Ok(method),
|
||||
(None, ext) => {
|
||||
// We already checked that the buffer is ASCII
|
||||
@@ -587,7 +586,7 @@ pub type StatusLine = (HttpVersion, RawStatus);
|
||||
|
||||
/// The raw status code and reason-phrase.
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct RawStatus(pub u16, pub CowString<'static>);
|
||||
pub struct RawStatus(pub u16, pub Cow<'static, str>);
|
||||
|
||||
impl Clone for RawStatus {
|
||||
fn clone(&self) -> RawStatus {
|
||||
@@ -664,7 +663,7 @@ pub fn read_status<R: Reader>(stream: &mut R) -> HttpResult<RawStatus> {
|
||||
}
|
||||
}
|
||||
|
||||
let reason = match str::from_utf8(&buf[]) {
|
||||
let reason = match str::from_utf8(&buf[..]) {
|
||||
Ok(s) => s.trim(),
|
||||
Err(_) => return Err(HttpStatusError)
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#![feature(core, collections, hash, io, os, path, std_misc,
|
||||
slicing_syntax, box_syntax, unsafe_destructor)]
|
||||
#![feature(core, collections, io, old_io, os, old_path,
|
||||
std_misc, box_syntax, unsafe_destructor)]
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![cfg_attr(test, feature(alloc, test))]
|
||||
|
||||
@@ -58,7 +58,7 @@ pub trait NetworkAcceptor: Clone + Send {
|
||||
}
|
||||
|
||||
/// An iterator wrapper over a NetworkAcceptor.
|
||||
pub struct NetworkConnections<'a, N: NetworkAcceptor>(&'a mut N);
|
||||
pub struct NetworkConnections<'a, N: NetworkAcceptor + 'a>(&'a mut N);
|
||||
|
||||
impl<'a, N: NetworkAcceptor> Iterator for NetworkConnections<'a, N> {
|
||||
type Item = IoResult<N::Stream>;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use std::thread::{Thread, JoinGuard};
|
||||
use std::sync::Arc;
|
||||
use std::thread::{self, JoinGuard};
|
||||
use std::sync::mpsc;
|
||||
use std::collections::VecMap;
|
||||
use net::NetworkAcceptor;
|
||||
|
||||
pub struct AcceptorPool<A: NetworkAcceptor> {
|
||||
acceptor: A
|
||||
}
|
||||
|
||||
impl<A: NetworkAcceptor> AcceptorPool<A> {
|
||||
impl<'a, A: NetworkAcceptor + 'a> AcceptorPool<A> {
|
||||
/// Create a thread pool to manage the acceptor.
|
||||
pub fn new(acceptor: A) -> AcceptorPool<A> {
|
||||
AcceptorPool { acceptor: acceptor }
|
||||
@@ -18,34 +18,39 @@ impl<A: NetworkAcceptor> AcceptorPool<A> {
|
||||
/// ## Panics
|
||||
///
|
||||
/// Panics if threads == 0.
|
||||
pub fn accept<F: Fn(A::Stream) + Send + Sync>(self,
|
||||
work: F,
|
||||
threads: usize) -> JoinGuard<'static, ()> {
|
||||
pub fn accept<F>(self, work: F, threads: usize)
|
||||
where F: Fn(A::Stream) + Send + Sync + 'a {
|
||||
assert!(threads != 0, "Can't accept on 0 threads.");
|
||||
|
||||
// Replace with &F when Send changes land.
|
||||
let work = Arc::new(work);
|
||||
|
||||
let (super_tx, supervisor_rx) = mpsc::channel();
|
||||
|
||||
let spawn =
|
||||
move || spawn_with(super_tx.clone(), work.clone(), self.acceptor.clone());
|
||||
let counter = &mut 0;
|
||||
let work = &work;
|
||||
let mut spawn = move || {
|
||||
let id = *counter;
|
||||
let guard = spawn_with(super_tx.clone(), work, self.acceptor.clone(), id);
|
||||
*counter += 1;
|
||||
(id, guard)
|
||||
};
|
||||
|
||||
// Go
|
||||
for _ in 0..threads { spawn() }
|
||||
let mut guards: VecMap<_> = (0..threads).map(|_| spawn()).collect();
|
||||
|
||||
// Spawn the supervisor
|
||||
Thread::scoped(move || for () in supervisor_rx.iter() { spawn() })
|
||||
for id in supervisor_rx.iter() {
|
||||
guards.remove(&id);
|
||||
let (id, guard) = spawn();
|
||||
guards.insert(id, guard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_with<A, F>(supervisor: mpsc::Sender<()>, work: Arc<F>, mut acceptor: A)
|
||||
where A: NetworkAcceptor,
|
||||
F: Fn(<A as NetworkAcceptor>::Stream) + Send + Sync {
|
||||
fn spawn_with<'a, A, F>(supervisor: mpsc::Sender<usize>, work: &'a F, mut acceptor: A, id: usize) -> JoinGuard<'a, ()>
|
||||
where A: NetworkAcceptor + 'a,
|
||||
F: Fn(<A as NetworkAcceptor>::Stream) + Send + Sync + 'a {
|
||||
use std::old_io::EndOfFile;
|
||||
|
||||
Thread::spawn(move || {
|
||||
let sentinel = Sentinel::new(supervisor, ());
|
||||
thread::scoped(move || {
|
||||
let sentinel = Sentinel::new(supervisor, id);
|
||||
|
||||
loop {
|
||||
match acceptor.accept() {
|
||||
@@ -61,7 +66,7 @@ where A: NetworkAcceptor,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
struct Sentinel<T: Send> {
|
||||
@@ -83,7 +88,7 @@ impl<T: Send> Sentinel<T> {
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<T: Send> Drop for Sentinel<T> {
|
||||
impl<T: Send + 'static> Drop for Sentinel<T> {
|
||||
fn drop(&mut self) {
|
||||
// If we were cancelled, get out of here.
|
||||
if !self.active { return; }
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use std::old_io::{Listener, BufferedReader, BufferedWriter};
|
||||
use std::old_io::net::ip::{IpAddr, Port, SocketAddr};
|
||||
use std::os;
|
||||
use std::thread::JoinGuard;
|
||||
use std::thread::{self, JoinGuard};
|
||||
|
||||
pub use self::request::Request;
|
||||
pub use self::response::Response;
|
||||
@@ -56,7 +56,7 @@ impl Server<HttpListener> {
|
||||
|
||||
impl<
|
||||
L: NetworkListener<Acceptor=A> + Send,
|
||||
A: NetworkAcceptor<Stream=S> + Send,
|
||||
A: NetworkAcceptor<Stream=S> + Send + 'static,
|
||||
S: NetworkStream + Clone + Send> Server<L> {
|
||||
/// Creates a new server that will handle `HttpStream`s.
|
||||
pub fn with_listener(ip: IpAddr, port: Port, listener: L) -> Server<L> {
|
||||
@@ -68,7 +68,7 @@ S: NetworkStream + Clone + Send> Server<L> {
|
||||
}
|
||||
|
||||
/// Binds to a socket, and starts handling connections using a task pool.
|
||||
pub fn listen_threads<H: Handler>(mut self, handler: H, threads: usize) -> HttpResult<Listening<L::Acceptor>> {
|
||||
pub fn listen_threads<H: Handler + 'static>(mut self, handler: H, threads: usize) -> HttpResult<Listening<L::Acceptor>> {
|
||||
debug!("binding to {:?}:{:?}", self.ip, self.port);
|
||||
let acceptor = try!(self.listener.listen((self.ip, self.port)));
|
||||
let socket = try!(acceptor.socket_name());
|
||||
@@ -77,15 +77,17 @@ S: NetworkStream + Clone + Send> Server<L> {
|
||||
let pool = AcceptorPool::new(acceptor.clone());
|
||||
let work = move |stream| handle_connection(stream, &handler);
|
||||
|
||||
let guard = thread::scoped(move || pool.accept(work, threads));
|
||||
|
||||
Ok(Listening {
|
||||
_guard: pool.accept(work, threads),
|
||||
_guard: guard,
|
||||
socket: socket,
|
||||
acceptor: acceptor
|
||||
})
|
||||
}
|
||||
|
||||
/// Binds to a socket and starts handling connections.
|
||||
pub fn listen<H: Handler>(self, handler: H) -> HttpResult<Listening<L::Acceptor>> {
|
||||
pub fn listen<H: Handler + 'static>(self, handler: H) -> HttpResult<Listening<L::Acceptor>> {
|
||||
self.listen_threads(handler, os::num_cpus() * 5 / 4)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//! These are responses sent by a `hyper::Server` to clients, after
|
||||
//! receiving a request.
|
||||
use std::old_io::IoResult;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use time::now_utc;
|
||||
|
||||
@@ -22,7 +23,9 @@ pub struct Response<'a, W = Fresh> {
|
||||
// The status code for the request.
|
||||
status: status::StatusCode,
|
||||
// The outgoing headers on this response.
|
||||
headers: header::Headers
|
||||
headers: header::Headers,
|
||||
|
||||
_marker: PhantomData<W>
|
||||
}
|
||||
|
||||
impl<'a, W> Response<'a, W> {
|
||||
@@ -42,7 +45,8 @@ impl<'a, W> Response<'a, W> {
|
||||
status: status,
|
||||
version: version,
|
||||
body: body,
|
||||
headers: headers
|
||||
headers: headers,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +64,8 @@ impl<'a> Response<'a, Fresh> {
|
||||
status: status::StatusCode::Ok,
|
||||
version: version::HttpVersion::Http11,
|
||||
headers: header::Headers::new(),
|
||||
body: ThroughWriter(stream)
|
||||
body: ThroughWriter(stream),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +124,8 @@ impl<'a> Response<'a, Fresh> {
|
||||
version: self.version,
|
||||
body: stream,
|
||||
status: self.status,
|
||||
headers: self.headers
|
||||
headers: self.headers,
|
||||
_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user