diff --git a/src/client/request.rs b/src/client/request.rs index e83ed7c5..8b97034b 100644 --- a/src/client/request.rs +++ b/src/client/request.rs @@ -114,15 +114,14 @@ impl Request { } debug!("writing head: {} {} {}", self.method, uri, self.version); - try!(write!(&mut self.body, "{} {} {}", self.method, uri, self.version)); - try!(self.body.write(LINE_ENDING)); + try!(write!(&mut self.body, "{} {} {}{}", + self.method, uri, self.version, LINE_ENDING)); let stream = match self.method { Get | Head => { debug!("headers [\n{}]", self.headers); - try!(write!(&mut self.body, "{}", self.headers)); - try!(self.body.write(LINE_ENDING)); + try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING)); EmptyWriter(self.body.unwrap()) }, _ => { @@ -155,8 +154,7 @@ impl Request { } debug!("headers [\n{}]", self.headers); - try!(write!(&mut self.body, "{}", self.headers)); - try!(self.body.write(LINE_ENDING)); + try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING)); if chunked { ChunkedWriter(self.body.unwrap()) @@ -217,7 +215,8 @@ mod tests { Get, Url::parse("http://example.dom").unwrap(), &mut MockConnector ).unwrap(); let req = req.start().unwrap(); - let stream = *req.body.end().unwrap().into_inner().downcast::().unwrap(); + let stream = *req.body.end().unwrap() + .into_inner().downcast::().ok().unwrap(); let bytes = stream.write.into_inner(); let s = from_utf8(bytes[]).unwrap(); assert!(!s.contains("Content-Length:")); @@ -230,7 +229,8 @@ mod tests { Head, Url::parse("http://example.dom").unwrap(), &mut MockConnector ).unwrap(); let req = req.start().unwrap(); - let stream = *req.body.end().unwrap().into_inner().downcast::().unwrap(); + let stream = *req.body.end().unwrap() + .into_inner().downcast::().ok().unwrap(); let bytes = stream.write.into_inner(); let s = from_utf8(bytes[]).unwrap(); assert!(!s.contains("Content-Length:")); diff --git a/src/client/response.rs b/src/client/response.rs index 7bffe22d..f87dd936 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -120,7 +120,7 @@ mod tests { status_raw: RawStatus(200, Borrowed("OK")) }; - let b = res.into_inner().downcast::().unwrap(); + let b = res.into_inner().downcast::().ok().unwrap(); assert_eq!(b, box MockStream::new()); } diff --git a/src/header/mod.rs b/src/header/mod.rs index 89e7dc42..10ec5d83 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -10,7 +10,8 @@ use std::borrow::Cow::{Borrowed, Owned}; use std::fmt::{self, Show}; use std::intrinsics::TypeId; use std::raw::TraitObject; -use std::str::{SendStr, FromStr}; +use std::str::FromStr; +use std::string::CowString; use std::collections::HashMap; use std::collections::hash_map::{Iter, Entry}; use std::iter::FromIterator; @@ -135,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() }; @@ -438,7 +439,7 @@ impl fmt::Show for Item { None => match self.raw { Some(ref raw) => { for part in raw.iter() { - try!(fmt.write(part.as_slice())); + try!(write!(fmt, "{}", part.as_slice())); } Ok(()) }, @@ -455,8 +456,7 @@ impl fmt::Show for Box { } /// Case-insensitive string. -//#[derive(Clone)] -pub struct CaseInsensitive(SendStr); +pub struct CaseInsensitive(CowString<'static>); impl FromStr for CaseInsensitive { fn from_str(s: &str) -> Option { diff --git a/src/header/shared/util.rs b/src/header/shared/util.rs index 86359d66..73d0422c 100644 --- a/src/header/shared/util.rs +++ b/src/header/shared/util.rs @@ -9,7 +9,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(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(raw: &[Vec]) -> Option> 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. diff --git a/src/http.rs b/src/http.rs index 610303ec..d0c63e3a 100644 --- a/src/http.rs +++ b/src/http.rs @@ -5,7 +5,8 @@ use std::cmp::min; use std::fmt; use std::io::{self, Reader, IoResult, BufWriter}; use std::num::from_u16; -use std::str::{self, SendStr, FromStr}; +use std::str::{self, FromStr}; +use std::string::CowString; use url::Url; use url::ParseError as UrlError; @@ -108,7 +109,7 @@ impl Reader for HttpReader { *opt_remaining = if rem > 0 { Some(rem) } else { - try!(eat(body, LINE_ENDING)); + try!(eat(body, LINE_ENDING.as_bytes())); None }; Ok(count) @@ -237,9 +238,9 @@ impl Writer for HttpWriter { ChunkedWriter(ref mut w) => { let chunk_size = msg.len(); debug!("chunked write, size = {}", chunk_size); - try!(write!(w, "{:X}{}{}", chunk_size, CR as char, LF as char)); + try!(write!(w, "{:X}{}", chunk_size, LINE_ENDING)); try!(w.write(msg)); - w.write(LINE_ENDING) + w.write_str(LINE_ENDING) }, SizedWriter(ref mut w, ref mut remaining) => { let len = msg.len(); @@ -283,7 +284,7 @@ pub const SP: u8 = b' '; pub const CR: u8 = b'\r'; pub const LF: u8 = b'\n'; pub const STAR: u8 = b'*'; -pub const LINE_ENDING: &'static [u8] = &[CR, LF]; +pub const LINE_ENDING: &'static str = "\r\n"; /// A `Show`able struct to easily write line endings to a formatter. pub struct LineEnding; @@ -292,13 +293,7 @@ impl Copy for LineEnding {} impl fmt::Show for LineEnding { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write(LINE_ENDING) - } -} - -impl AsSlice for LineEnding { - fn as_slice(&self) -> &[u8] { - LINE_ENDING + fmt.write_str(LINE_ENDING) } } @@ -584,7 +579,7 @@ pub type StatusLine = (HttpVersion, RawStatus); /// The raw status code and reason-phrase. #[derive(PartialEq, Show)] -pub struct RawStatus(pub u16, pub SendStr); +pub struct RawStatus(pub u16, pub CowString<'static>); impl Clone for RawStatus { fn clone(&self) -> RawStatus { diff --git a/src/lib.rs b/src/lib.rs index 9ad7b217..4b72a1c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -145,12 +145,9 @@ pub use method::Method::{Get, Head, Post, Delete}; pub use status::StatusCode::{Ok, BadRequest, NotFound}; pub use server::Server; -use std::fmt; use std::error::{Error, FromError}; use std::io::IoError; -use std::rt::backtrace; - use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError, HttpHeaderError, HttpStatusError, HttpIoError}; @@ -160,23 +157,6 @@ macro_rules! todo( }) ); -// FIXME(reem): Uncomment this when backtrace::write can write to a fmt::Formatter. -// #[allow(dead_code)] -// struct Trace; -// -// impl fmt::Show for Trace { -// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { -// let _ = backtrace::write(fmt); -// Result::Ok(()) -// } -// } -// -// macro_rules! trace( -// ($($arg:tt)*) => (if cfg!(not(ndebug)) { -// log!(5, "{}\n{}", format_args!($($arg)*), ::Trace) -// }) -// ); - macro_rules! inspect( ($name:expr, $value:expr) => ({ let v = $value; diff --git a/src/mock.rs b/src/mock.rs index db1fe05a..714c4ac1 100644 --- a/src/mock.rs +++ b/src/mock.rs @@ -92,7 +92,7 @@ macro_rules! mock_connector ( let key = format!("{}://{}", scheme, host); // ignore port for now - match map.find(&&*key) { + match map.get(&&*key) { Some(res) => Ok(::mock::MockStream { write: ::std::io::MemWriter::new(), read: ::std::io::MemReader::new(res.to_string().into_bytes()) diff --git a/src/server/request.rs b/src/server/request.rs index c302706e..5c808441 100644 --- a/src/server/request.rs +++ b/src/server/request.rs @@ -78,9 +78,11 @@ mod tests { use mock::MockStream; use super::Request; - macro_rules! sock( - ($s:expr) => (::std::str::from_str::<::std::io::net::ip::SocketAddr>($s).unwrap()) - ); + use std::io::net::ip::SocketAddr; + + fn sock(s: &str) -> SocketAddr { + s.parse().unwrap() + } #[test] fn test_get_empty_body() { @@ -91,7 +93,7 @@ mod tests { I'm a bad request.\r\n\ "); - let mut req = Request::new(&mut stream, sock!("127.0.0.1:80")).unwrap(); + let mut req = Request::new(&mut stream, sock("127.0.0.1:80")).unwrap(); assert_eq!(req.read_to_string(), Ok("".to_string())); } @@ -104,7 +106,7 @@ mod tests { I'm a bad request.\r\n\ "); - let mut req = Request::new(&mut stream, sock!("127.0.0.1:80")).unwrap(); + let mut req = Request::new(&mut stream, sock("127.0.0.1:80")).unwrap(); assert_eq!(req.read_to_string(), Ok("".to_string())); } @@ -117,7 +119,7 @@ mod tests { I'm a bad request.\r\n\ "); - let mut req = Request::new(&mut stream, sock!("127.0.0.1:80")).unwrap(); + let mut req = Request::new(&mut stream, sock("127.0.0.1:80")).unwrap(); assert_eq!(req.read_to_string(), Ok("".to_string())); } } diff --git a/src/server/response.rs b/src/server/response.rs index 7934dc23..9204e9cd 100644 --- a/src/server/response.rs +++ b/src/server/response.rs @@ -107,7 +107,7 @@ impl<'a> Response<'a, Fresh> { debug!("headers [\n{}]", self.headers); try!(write!(&mut self.body, "{}", self.headers)); - try!(self.body.write(LINE_ENDING)); + try!(self.body.write_str(LINE_ENDING)); let stream = if chunked { ChunkedWriter(self.body.unwrap())