Miscellaneous fixes and test updates for all the other changes
- http::LINE_ENDING is now an &'static str
This commit is contained in:
@@ -114,15 +114,14 @@ impl Request<Fresh> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug!("writing head: {} {} {}", self.method, uri, self.version);
|
debug!("writing head: {} {} {}", self.method, uri, self.version);
|
||||||
try!(write!(&mut self.body, "{} {} {}", self.method, uri, self.version));
|
try!(write!(&mut self.body, "{} {} {}{}",
|
||||||
try!(self.body.write(LINE_ENDING));
|
self.method, uri, self.version, LINE_ENDING));
|
||||||
|
|
||||||
|
|
||||||
let stream = match self.method {
|
let stream = match self.method {
|
||||||
Get | Head => {
|
Get | Head => {
|
||||||
debug!("headers [\n{}]", self.headers);
|
debug!("headers [\n{}]", self.headers);
|
||||||
try!(write!(&mut self.body, "{}", self.headers));
|
try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING));
|
||||||
try!(self.body.write(LINE_ENDING));
|
|
||||||
EmptyWriter(self.body.unwrap())
|
EmptyWriter(self.body.unwrap())
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@@ -155,8 +154,7 @@ impl Request<Fresh> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug!("headers [\n{}]", self.headers);
|
debug!("headers [\n{}]", self.headers);
|
||||||
try!(write!(&mut self.body, "{}", self.headers));
|
try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING));
|
||||||
try!(self.body.write(LINE_ENDING));
|
|
||||||
|
|
||||||
if chunked {
|
if chunked {
|
||||||
ChunkedWriter(self.body.unwrap())
|
ChunkedWriter(self.body.unwrap())
|
||||||
@@ -217,7 +215,8 @@ mod tests {
|
|||||||
Get, Url::parse("http://example.dom").unwrap(), &mut MockConnector
|
Get, Url::parse("http://example.dom").unwrap(), &mut MockConnector
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let req = req.start().unwrap();
|
let req = req.start().unwrap();
|
||||||
let stream = *req.body.end().unwrap().into_inner().downcast::<MockStream>().unwrap();
|
let stream = *req.body.end().unwrap()
|
||||||
|
.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||||
let bytes = stream.write.into_inner();
|
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("Content-Length:"));
|
||||||
@@ -230,7 +229,8 @@ mod tests {
|
|||||||
Head, Url::parse("http://example.dom").unwrap(), &mut MockConnector
|
Head, Url::parse("http://example.dom").unwrap(), &mut MockConnector
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let req = req.start().unwrap();
|
let req = req.start().unwrap();
|
||||||
let stream = *req.body.end().unwrap().into_inner().downcast::<MockStream>().unwrap();
|
let stream = *req.body.end().unwrap()
|
||||||
|
.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||||
let bytes = stream.write.into_inner();
|
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("Content-Length:"));
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ mod tests {
|
|||||||
status_raw: RawStatus(200, Borrowed("OK"))
|
status_raw: RawStatus(200, Borrowed("OK"))
|
||||||
};
|
};
|
||||||
|
|
||||||
let b = res.into_inner().downcast::<MockStream>().unwrap();
|
let b = res.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||||
assert_eq!(b, box MockStream::new());
|
assert_eq!(b, box MockStream::new());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ use std::borrow::Cow::{Borrowed, Owned};
|
|||||||
use std::fmt::{self, Show};
|
use std::fmt::{self, Show};
|
||||||
use std::intrinsics::TypeId;
|
use std::intrinsics::TypeId;
|
||||||
use std::raw::TraitObject;
|
use std::raw::TraitObject;
|
||||||
use std::str::{SendStr, FromStr};
|
use std::str::FromStr;
|
||||||
|
use std::string::CowString;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::{Iter, Entry};
|
use std::collections::hash_map::{Iter, Entry};
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
@@ -135,8 +136,8 @@ impl Headers {
|
|||||||
Some((name, value)) => {
|
Some((name, value)) => {
|
||||||
debug!("raw header: {}={}", name, value[]);
|
debug!("raw header: {}={}", name, value[]);
|
||||||
let name = CaseInsensitive(Owned(name));
|
let name = CaseInsensitive(Owned(name));
|
||||||
let mut item = match headers.data.entry(name) {
|
let mut item = match headers.data.entry(&name) {
|
||||||
Entry::Vacant(entry) => entry.set(MuCell::new(Item::raw(vec![]))),
|
Entry::Vacant(entry) => entry.insert(MuCell::new(Item::raw(vec![]))),
|
||||||
Entry::Occupied(entry) => entry.into_mut()
|
Entry::Occupied(entry) => entry.into_mut()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -438,7 +439,7 @@ impl fmt::Show for Item {
|
|||||||
None => match self.raw {
|
None => match self.raw {
|
||||||
Some(ref raw) => {
|
Some(ref raw) => {
|
||||||
for part in raw.iter() {
|
for part in raw.iter() {
|
||||||
try!(fmt.write(part.as_slice()));
|
try!(write!(fmt, "{}", part.as_slice()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
@@ -455,8 +456,7 @@ impl fmt::Show for Box<HeaderFormat + Send + Sync> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Case-insensitive string.
|
/// Case-insensitive string.
|
||||||
//#[derive(Clone)]
|
pub struct CaseInsensitive(CowString<'static>);
|
||||||
pub struct CaseInsensitive(SendStr);
|
|
||||||
|
|
||||||
impl FromStr for CaseInsensitive {
|
impl FromStr for CaseInsensitive {
|
||||||
fn from_str(s: &str) -> Option<CaseInsensitive> {
|
fn from_str(s: &str) -> Option<CaseInsensitive> {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pub fn from_one_raw_str<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<T> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// we JUST checked that raw.len() == 1, so raw[0] WILL exist.
|
// 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),
|
Ok(s) => str::FromStr::from_str(s),
|
||||||
Err(_) => None
|
Err(_) => None
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ pub fn from_comma_delimited<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<Vec<T>>
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// we JUST checked that raw.len() == 1, so raw[0] WILL exist.
|
// 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.
|
/// Reads a comma-delimited raw string into a Vec.
|
||||||
|
|||||||
21
src/http.rs
21
src/http.rs
@@ -5,7 +5,8 @@ use std::cmp::min;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, Reader, IoResult, BufWriter};
|
use std::io::{self, Reader, IoResult, BufWriter};
|
||||||
use std::num::from_u16;
|
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::Url;
|
||||||
use url::ParseError as UrlError;
|
use url::ParseError as UrlError;
|
||||||
@@ -108,7 +109,7 @@ impl<R: Reader> Reader for HttpReader<R> {
|
|||||||
*opt_remaining = if rem > 0 {
|
*opt_remaining = if rem > 0 {
|
||||||
Some(rem)
|
Some(rem)
|
||||||
} else {
|
} else {
|
||||||
try!(eat(body, LINE_ENDING));
|
try!(eat(body, LINE_ENDING.as_bytes()));
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(count)
|
Ok(count)
|
||||||
@@ -237,9 +238,9 @@ impl<W: Writer> Writer for HttpWriter<W> {
|
|||||||
ChunkedWriter(ref mut w) => {
|
ChunkedWriter(ref mut w) => {
|
||||||
let chunk_size = msg.len();
|
let chunk_size = msg.len();
|
||||||
debug!("chunked write, size = {}", chunk_size);
|
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));
|
try!(w.write(msg));
|
||||||
w.write(LINE_ENDING)
|
w.write_str(LINE_ENDING)
|
||||||
},
|
},
|
||||||
SizedWriter(ref mut w, ref mut remaining) => {
|
SizedWriter(ref mut w, ref mut remaining) => {
|
||||||
let len = msg.len();
|
let len = msg.len();
|
||||||
@@ -283,7 +284,7 @@ pub const SP: u8 = b' ';
|
|||||||
pub const CR: u8 = b'\r';
|
pub const CR: u8 = b'\r';
|
||||||
pub const LF: u8 = b'\n';
|
pub const LF: u8 = b'\n';
|
||||||
pub const STAR: u8 = b'*';
|
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.
|
/// A `Show`able struct to easily write line endings to a formatter.
|
||||||
pub struct LineEnding;
|
pub struct LineEnding;
|
||||||
@@ -292,13 +293,7 @@ impl Copy for LineEnding {}
|
|||||||
|
|
||||||
impl fmt::Show for LineEnding {
|
impl fmt::Show for LineEnding {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt.write(LINE_ENDING)
|
fmt.write_str(LINE_ENDING)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsSlice<u8> for LineEnding {
|
|
||||||
fn as_slice(&self) -> &[u8] {
|
|
||||||
LINE_ENDING
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +579,7 @@ pub type StatusLine = (HttpVersion, RawStatus);
|
|||||||
|
|
||||||
/// The raw status code and reason-phrase.
|
/// The raw status code and reason-phrase.
|
||||||
#[derive(PartialEq, Show)]
|
#[derive(PartialEq, Show)]
|
||||||
pub struct RawStatus(pub u16, pub SendStr);
|
pub struct RawStatus(pub u16, pub CowString<'static>);
|
||||||
|
|
||||||
impl Clone for RawStatus {
|
impl Clone for RawStatus {
|
||||||
fn clone(&self) -> RawStatus {
|
fn clone(&self) -> RawStatus {
|
||||||
|
|||||||
20
src/lib.rs
20
src/lib.rs
@@ -145,12 +145,9 @@ pub use method::Method::{Get, Head, Post, Delete};
|
|||||||
pub use status::StatusCode::{Ok, BadRequest, NotFound};
|
pub use status::StatusCode::{Ok, BadRequest, NotFound};
|
||||||
pub use server::Server;
|
pub use server::Server;
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::error::{Error, FromError};
|
use std::error::{Error, FromError};
|
||||||
use std::io::IoError;
|
use std::io::IoError;
|
||||||
|
|
||||||
use std::rt::backtrace;
|
|
||||||
|
|
||||||
use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError,
|
use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError,
|
||||||
HttpHeaderError, HttpStatusError, HttpIoError};
|
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(
|
macro_rules! inspect(
|
||||||
($name:expr, $value:expr) => ({
|
($name:expr, $value:expr) => ({
|
||||||
let v = $value;
|
let v = $value;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ macro_rules! mock_connector (
|
|||||||
|
|
||||||
let key = format!("{}://{}", scheme, host);
|
let key = format!("{}://{}", scheme, host);
|
||||||
// ignore port for now
|
// ignore port for now
|
||||||
match map.find(&&*key) {
|
match map.get(&&*key) {
|
||||||
Some(res) => Ok(::mock::MockStream {
|
Some(res) => Ok(::mock::MockStream {
|
||||||
write: ::std::io::MemWriter::new(),
|
write: ::std::io::MemWriter::new(),
|
||||||
read: ::std::io::MemReader::new(res.to_string().into_bytes())
|
read: ::std::io::MemReader::new(res.to_string().into_bytes())
|
||||||
|
|||||||
@@ -78,9 +78,11 @@ mod tests {
|
|||||||
use mock::MockStream;
|
use mock::MockStream;
|
||||||
use super::Request;
|
use super::Request;
|
||||||
|
|
||||||
macro_rules! sock(
|
use std::io::net::ip::SocketAddr;
|
||||||
($s:expr) => (::std::str::from_str::<::std::io::net::ip::SocketAddr>($s).unwrap())
|
|
||||||
);
|
fn sock(s: &str) -> SocketAddr {
|
||||||
|
s.parse().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_empty_body() {
|
fn test_get_empty_body() {
|
||||||
@@ -91,7 +93,7 @@ mod tests {
|
|||||||
I'm a bad request.\r\n\
|
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()));
|
assert_eq!(req.read_to_string(), Ok("".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +106,7 @@ mod tests {
|
|||||||
I'm a bad request.\r\n\
|
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()));
|
assert_eq!(req.read_to_string(), Ok("".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +119,7 @@ mod tests {
|
|||||||
I'm a bad request.\r\n\
|
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()));
|
assert_eq!(req.read_to_string(), Ok("".to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ impl<'a> Response<'a, Fresh> {
|
|||||||
debug!("headers [\n{}]", self.headers);
|
debug!("headers [\n{}]", self.headers);
|
||||||
try!(write!(&mut self.body, "{}", 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 {
|
let stream = if chunked {
|
||||||
ChunkedWriter(self.body.unwrap())
|
ChunkedWriter(self.body.unwrap())
|
||||||
|
|||||||
Reference in New Issue
Block a user