diff --git a/benches/client.rs b/benches/client.rs index 060c53ab54..1582a02d8e 100644 --- a/benches/client.rs +++ b/benches/client.rs @@ -1,4 +1,4 @@ -#![feature(core, io, test)] +#![feature(core, old_io, test)] extern crate hyper; extern crate test; diff --git a/benches/client_mock_tcp.rs b/benches/client_mock_tcp.rs index 5caae756e5..370e73b942 100644 --- a/benches/client_mock_tcp.rs +++ b/benches/client_mock_tcp.rs @@ -1,4 +1,4 @@ -#![feature(collections, io, test)] +#![feature(collections, old_io, test)] extern crate hyper; extern crate test; diff --git a/benches/server.rs b/benches/server.rs index 2ffcd75ff9..57db9935a7 100644 --- a/benches/server.rs +++ b/benches/server.rs @@ -1,4 +1,4 @@ -#![feature(io, test)] +#![feature(old_io, test)] extern crate hyper; extern crate test; diff --git a/examples/client.rs b/examples/client.rs index 70edf87162..ea29965ac6 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -1,4 +1,4 @@ -#![feature(env, io)] +#![feature(env, old_io)] extern crate hyper; use std::env; diff --git a/examples/hello.rs b/examples/hello.rs index 8ed34e2bdd..188f93b084 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -1,4 +1,4 @@ -#![feature(io)] +#![feature(old_io)] extern crate hyper; use std::old_io::net::ip::Ipv4Addr; diff --git a/examples/server.rs b/examples/server.rs index 17c580bc84..3f7606ef19 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -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"; diff --git a/src/client/mod.rs b/src/client/mod.rs index 64a875105e..81fa9a6a79 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -197,7 +197,7 @@ impl<'a, U: IntoUrl, C: NetworkConnector> RequestBuilder<'a, U, C> { // punching borrowck here let loc = match res.headers.get::() { 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)); diff --git a/src/client/request.rs b/src/client/request.rs index 2a5c2ff72b..9862aeae66 100644 --- a/src/client/request.rs +++ b/src/client/request.rs @@ -1,5 +1,6 @@ //! Client Requests use std::old_io::{BufferedWriter, IoResult}; +use std::marker::PhantomData; use url::Url; @@ -25,6 +26,8 @@ pub struct Request { body: HttpWriter>>, headers: Headers, method: method::Method, + + _marker: PhantomData, } impl Request { @@ -66,7 +69,8 @@ impl Request { headers: headers, url: url, version: version::HttpVersion::Http11, - body: stream + body: stream, + _marker: PhantomData, }) } @@ -77,7 +81,7 @@ impl Request { //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 +140,8 @@ impl Request { headers: self.headers, url: self.url, version: self.version, - body: stream + body: stream, + _marker: PhantomData, }) } @@ -185,7 +190,7 @@ mod tests { let stream = *req.body.end().unwrap() .into_inner().downcast::().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 +204,7 @@ mod tests { let stream = *req.body.end().unwrap() .into_inner().downcast::().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:")); } diff --git a/src/client/response.rs b/src/client/response.rs index 763f36cd2c..5ded928ef3 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -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,6 +24,8 @@ pub struct Response { pub version: version::HttpVersion, status_raw: RawStatus, body: HttpReader>>, + + _marker: PhantomData, } impl Response { @@ -72,6 +75,7 @@ impl Response { headers: headers, body: body, status_raw: raw_status, + _marker: PhantomData, }) } @@ -98,6 +102,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 +124,8 @@ mod tests { headers: Headers::new(), version: version::HttpVersion::Http11, body: EofReader(BufferedReader::new(box MockStream::new() as Box)), - status_raw: RawStatus(200, Borrowed("OK")) + status_raw: RawStatus(200, Borrowed("OK")), + _marker: PhantomData, }; let b = res.into_inner().downcast::().ok().unwrap(); diff --git a/src/header/common/access_control/allow_origin.rs b/src/header/common/access_control/allow_origin.rs index 893b522b47..b7bde04d0e 100644 --- a/src/header/common/access_control/allow_origin.rs +++ b/src/header/common/access_control/allow_origin.rs @@ -29,7 +29,7 @@ impl header::Header for AccessControlAllowOrigin { fn parse_header(raw: &[Vec]) -> Option { 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) diff --git a/src/header/common/authorization.rs b/src/header/common/authorization.rs index 9999089e4f..b36183d7bc 100644 --- a/src/header/common/authorization.rs +++ b/src/header/common/authorization.rs @@ -22,14 +22,14 @@ impl DerefMut for Authorization { } } -impl Header for Authorization { +impl Header for Authorization where ::Err: 'static { fn header_name() -> &'static str { "Authorization" } fn parse_header(raw: &[Vec]) -> Option> { if raw.len() == 1 { - match (from_utf8(unsafe { &raw[].get_unchecked(0)[] }), Scheme::scheme(None::)) { + match (from_utf8(unsafe { &raw.get_unchecked(0)[..] }), Scheme::scheme(None::)) { (Ok(header), Some(scheme)) if header.starts_with(scheme) && header.len() > scheme.len() + 1 => { header[scheme.len() + 1..].parse::().map(|s| Authorization(s)).ok() @@ -43,7 +43,7 @@ impl Header for Authorization { } } -impl HeaderFormat for Authorization { +impl HeaderFormat for Authorization where ::Err: 'static { fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match Scheme::scheme(None::) { 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::>().unwrap().0[], "foo bar baz"); + assert_eq!(&headers.get::>().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::>().unwrap(); - assert_eq!(&auth.0.username[], "Aladdin"); + assert_eq!(&auth.0.username[..], "Aladdin"); assert_eq!(auth.0.password, Some("open sesame".to_string())); } diff --git a/src/header/common/cache_control.rs b/src/header/common/cache_control.rs index 50e4a4af4c..f1def9e112 100644 --- a/src/header/common/cache_control.rs +++ b/src/header/common/cache_control.rs @@ -16,7 +16,7 @@ impl Header for CacheControl { fn parse_header(raw: &[Vec]) -> Option { let directives = raw.iter() - .filter_map(|line| from_one_comma_delimited(&line[])) + .filter_map(|line| from_one_comma_delimited(&line[..])) .collect::>>() .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) diff --git a/src/header/common/connection.rs b/src/header/common/connection.rs index 3c1dd88dd2..981c30a8db 100644 --- a/src/header/common/connection.rs +++ b/src/header/common/connection.rs @@ -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[..]) } } diff --git a/src/header/common/cookie.rs b/src/header/common/cookie.rs index fa68ab2d18..16df67e5de 100644 --- a/src/header/common/cookie.rs +++ b/src/header/common/cookie.rs @@ -26,7 +26,7 @@ impl Header for Cookie { fn parse_header(raw: &[Vec]) -> Option { 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] diff --git a/src/header/common/host.rs b/src/header/common/host.rs index 6e0bb06d3d..c0c08ba568 100644 --- a/src/header/common/host.rs +++ b/src/header/common/host.rs @@ -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) => { diff --git a/src/header/common/if_match.rs b/src/header/common/if_match.rs index 30a3a802bf..467ac640a8 100644 --- a/src/header/common/if_match.rs +++ b/src/header/common/if_match.rs @@ -25,7 +25,7 @@ impl Header for IfMatch { fn parse_header(raw: &[Vec]) -> Option { 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[..]) } } } diff --git a/src/header/common/if_none_match.rs b/src/header/common/if_none_match.rs index ef1211d841..8159ed3495 100644 --- a/src/header/common/if_none_match.rs +++ b/src/header/common/if_none_match.rs @@ -33,7 +33,7 @@ impl Header for IfNoneMatch { fn parse_header(raw: &[Vec]) -> Option { 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[..]) } } } } diff --git a/src/header/common/mod.rs b/src/header/common/mod.rs index 718361e85a..b2ffa50192 100644 --- a/src/header/common/mod.rs +++ b/src/header/common/mod.rs @@ -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[..]) } } diff --git a/src/header/common/pragma.rs b/src/header/common/pragma.rs index d9551d9202..b080c412af 100644 --- a/src/header/common/pragma.rs +++ b/src/header/common/pragma.rs @@ -31,7 +31,7 @@ impl Header for Pragma { fn parse_header(raw: &[Vec]) -> Option { 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), diff --git a/src/header/common/set_cookie.rs b/src/header/common/set_cookie.rs index a0e37bc15f..419e4c8f31 100644 --- a/src/header/common/set_cookie.rs +++ b/src/header/common/set_cookie.rs @@ -23,7 +23,7 @@ impl Header for SetCookie { fn parse_header(raw: &[Vec]) -> Option { 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] diff --git a/src/header/common/upgrade.rs b/src/header/common/upgrade.rs index 9347d3a2da..e6260a37e0 100644 --- a/src/header/common/upgrade.rs +++ b/src/header/common/upgrade.rs @@ -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[..]) } } diff --git a/src/header/common/vary.rs b/src/header/common/vary.rs index 52482e7359..ff19ec6036 100644 --- a/src/header/common/vary.rs +++ b/src/header/common/vary.rs @@ -21,7 +21,7 @@ impl Header for Vary { fn parse_header(raw: &[Vec]) -> Option { 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[..]) } } } } diff --git a/src/header/mod.rs b/src/header/mod.rs index 2b08a924e3..b846a568d9 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -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>; +type HeaderName = UniCase>; /// 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>(&mut self, name: K, value: Vec>) { + pub fn set_raw>(&mut self, name: K, value: Vec>) { 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> for Headers { - fn extend>>(&mut self, iter: I) { + fn extend>>(&mut self, iter: I) { for header in iter { self.data.insert((*header.0).clone(), (*header.1).clone()); } @@ -359,7 +358,7 @@ impl<'a> Extend> for Headers { } impl<'a> FromIterator> for Headers { - fn from_iter>>(iter: I) -> Headers { + fn from_iter>>(iter: I) -> Headers { let mut headers = Headers::new(); headers.extend(iter); headers @@ -451,7 +450,7 @@ fn get_or_parse_mut(item: &mut Item) -> Option<&mut It fn parse(item: &Item) { match *item.raw { - Some(ref raw) => match Header::parse_header(&raw[]) { + Some(ref raw) => match Header::parse_header(&raw[..]) { Some::(h) => item.typed.set(box h as Box), 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); @@ -595,7 +594,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 +670,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))); } diff --git a/src/header/parsing.rs b/src/header/parsing.rs index 16964f261c..5727a2b9cc 100644 --- a/src/header/parsing.rs +++ b/src/header/parsing.rs @@ -11,7 +11,7 @@ pub fn from_one_raw_str(raw: &[Vec]) -> Option { 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(raw: &[Vec]) -> Option> 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. diff --git a/src/header/shared/entity.rs b/src/header/shared/entity.rs index 740ba2abab..2388b677d8 100644 --- a/src/header/shared/entity.rs +++ b/src/header/shared/entity.rs @@ -42,7 +42,7 @@ impl FromStr for EntityTag { type Err = (); fn from_str(s: &str) -> Result { let length: usize = s.len(); - let slice = &s[]; + let slice = &s[..]; // Early exits: // 1. The string is empty, or, diff --git a/src/header/shared/quality_item.rs b/src/header/shared/quality_item.rs index a83060d60f..199ef9a72f 100644 --- a/src/header/shared/quality_item.rs +++ b/src/header/shared/quality_item.rs @@ -39,7 +39,7 @@ impl fmt::Display for QualityItem { 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', '.'][..])) } } } diff --git a/src/http.rs b/src/http.rs index 2d081bcb43..7affb8bd92 100644 --- a/src/http.rs +++ b/src/http.rs @@ -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(stream: &mut R) -> HttpResult { 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(stream: &mut R) -> HttpResult { } } - let reason = match str::from_utf8(&buf[]) { + let reason = match str::from_utf8(&buf[..]) { Ok(s) => s.trim(), Err(_) => return Err(HttpStatusError) }; diff --git a/src/lib.rs b/src/lib.rs index 4af33e7d07..cc71b61108 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ -#![feature(core, collections, hash, io, os, path, std_misc, - slicing_syntax, box_syntax, unsafe_destructor)] +#![feature(core, collections, hash, 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))] diff --git a/src/net.rs b/src/net.rs index b11abfa327..f7ff2554f6 100644 --- a/src/net.rs +++ b/src/net.rs @@ -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; diff --git a/src/server/acceptor.rs b/src/server/acceptor.rs index 3c0e0b5e15..38e0652d9b 100644 --- a/src/server/acceptor.rs +++ b/src/server/acceptor.rs @@ -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 { acceptor: A } -impl AcceptorPool { +impl<'a, A: NetworkAcceptor + 'a> AcceptorPool { /// Create a thread pool to manage the acceptor. pub fn new(acceptor: A) -> AcceptorPool { AcceptorPool { acceptor: acceptor } @@ -18,34 +18,39 @@ impl AcceptorPool { /// ## Panics /// /// Panics if threads == 0. - pub fn accept(self, - work: F, - threads: usize) -> JoinGuard<'static, ()> { + pub fn accept(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(supervisor: mpsc::Sender<()>, work: Arc, mut acceptor: A) -where A: NetworkAcceptor, - F: Fn(::Stream) + Send + Sync { +fn spawn_with<'a, A, F>(supervisor: mpsc::Sender, work: &'a F, mut acceptor: A, id: usize) -> JoinGuard<'a, ()> +where A: NetworkAcceptor + 'a, + F: Fn(::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 { @@ -83,7 +88,7 @@ impl Sentinel { } #[unsafe_destructor] -impl Drop for Sentinel { +impl Drop for Sentinel { fn drop(&mut self) { // If we were cancelled, get out of here. if !self.active { return; } diff --git a/src/server/mod.rs b/src/server/mod.rs index 01fa9184bd..169979d4a4 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -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 { impl< L: NetworkListener + Send, -A: NetworkAcceptor + Send, +A: NetworkAcceptor + Send + 'static, S: NetworkStream + Clone + Send> Server { /// Creates a new server that will handle `HttpStream`s. pub fn with_listener(ip: IpAddr, port: Port, listener: L) -> Server { @@ -68,7 +68,7 @@ S: NetworkStream + Clone + Send> Server { } /// Binds to a socket, and starts handling connections using a task pool. - pub fn listen_threads(mut self, handler: H, threads: usize) -> HttpResult> { + pub fn listen_threads(mut self, handler: H, threads: usize) -> HttpResult> { 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 { 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(self, handler: H) -> HttpResult> { + pub fn listen(self, handler: H) -> HttpResult> { self.listen_threads(handler, os::num_cpus() * 5 / 4) } diff --git a/src/server/response.rs b/src/server/response.rs index 1e3604b0e7..e6fbb9cf99 100644 --- a/src/server/response.rs +++ b/src/server/response.rs @@ -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 } 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, }) }