Merge pull request #115 from tikue/master
impl Error and FromError for HttpError; replace instances of try_io! with try!
This commit is contained in:
@@ -56,7 +56,7 @@ impl Request<Fresh> {
|
|||||||
};
|
};
|
||||||
debug!("port={}", port);
|
debug!("port={}", port);
|
||||||
|
|
||||||
let stream: S = try_io!(NetworkConnector::connect((host[], port), url.scheme.as_slice()));
|
let stream: S = try!(NetworkConnector::connect((host[], port), url.scheme.as_slice()));
|
||||||
let stream = ThroughWriter(BufferedWriter::new(box stream as Box<NetworkStream + Send>));
|
let stream = ThroughWriter(BufferedWriter::new(box stream as Box<NetworkStream + Send>));
|
||||||
|
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
@@ -113,15 +113,15 @@ impl Request<Fresh> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug!("writing head: {} {} {}", self.method, uri, self.version);
|
debug!("writing head: {} {} {}", self.method, uri, self.version);
|
||||||
try_io!(write!(self.body, "{} {} {}", self.method, uri, self.version))
|
try!(write!(self.body, "{} {} {}", self.method, uri, self.version))
|
||||||
try_io!(self.body.write(LINE_ENDING));
|
try!(self.body.write(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_io!(write!(self.body, "{}", self.headers));
|
try!(write!(self.body, "{}", self.headers));
|
||||||
try_io!(self.body.write(LINE_ENDING));
|
try!(self.body.write(LINE_ENDING));
|
||||||
EmptyWriter(self.body.unwrap())
|
EmptyWriter(self.body.unwrap())
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@@ -154,8 +154,8 @@ impl Request<Fresh> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug!("headers [\n{}]", self.headers);
|
debug!("headers [\n{}]", self.headers);
|
||||||
try_io!(write!(self.body, "{}", self.headers));
|
try!(write!(self.body, "{}", self.headers));
|
||||||
try_io!(self.body.write(LINE_ENDING));
|
try!(self.body.write(LINE_ENDING));
|
||||||
|
|
||||||
if chunked {
|
if chunked {
|
||||||
ChunkedWriter(self.body.unwrap())
|
ChunkedWriter(self.body.unwrap())
|
||||||
@@ -184,7 +184,7 @@ impl Request<Streaming> {
|
|||||||
///
|
///
|
||||||
/// Consumes the Request.
|
/// Consumes the Request.
|
||||||
pub fn send(self) -> HttpResult<Response> {
|
pub fn send(self) -> HttpResult<Response> {
|
||||||
let raw = try_io!(self.body.end()).unwrap();
|
let raw = try!(self.body.end()).unwrap();
|
||||||
Response::new(raw)
|
Response::new(raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/http.rs
36
src/http.rs
@@ -301,7 +301,7 @@ fn read_until_space<R: Reader>(stream: &mut R, buf: &mut [u8]) -> HttpResult<boo
|
|||||||
let mut bufwrt = BufWriter::new(buf);
|
let mut bufwrt = BufWriter::new(buf);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let byte = try_io!(stream.read_byte());
|
let byte = try!(stream.read_byte());
|
||||||
|
|
||||||
if byte == SP {
|
if byte == SP {
|
||||||
break
|
break
|
||||||
@@ -359,9 +359,9 @@ fn is_valid_method(buf: &[u8]) -> bool {
|
|||||||
|
|
||||||
/// Read a `RequestUri` from a raw stream.
|
/// Read a `RequestUri` from a raw stream.
|
||||||
pub fn read_uri<R: Reader>(stream: &mut R) -> HttpResult<uri::RequestUri> {
|
pub fn read_uri<R: Reader>(stream: &mut R) -> HttpResult<uri::RequestUri> {
|
||||||
let mut b = try_io!(stream.read_byte());
|
let mut b = try!(stream.read_byte());
|
||||||
while b == SP {
|
while b == SP {
|
||||||
b = try_io!(stream.read_byte());
|
b = try!(stream.read_byte());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
@@ -371,7 +371,7 @@ pub fn read_uri<R: Reader>(stream: &mut R) -> HttpResult<uri::RequestUri> {
|
|||||||
} else {
|
} else {
|
||||||
s.push(b as char);
|
s.push(b as char);
|
||||||
loop {
|
loop {
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
SP => {
|
SP => {
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
@@ -422,7 +422,7 @@ pub fn read_http_version<R: Reader>(stream: &mut R) -> HttpResult<HttpVersion> {
|
|||||||
try!(expect(stream.read_byte(), b'P'));
|
try!(expect(stream.read_byte(), b'P'));
|
||||||
try!(expect(stream.read_byte(), b'/'));
|
try!(expect(stream.read_byte(), b'/'));
|
||||||
|
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
b'0' => {
|
b'0' => {
|
||||||
try!(expect(stream.read_byte(), b'.'));
|
try!(expect(stream.read_byte(), b'.'));
|
||||||
try!(expect(stream.read_byte(), b'9'));
|
try!(expect(stream.read_byte(), b'9'));
|
||||||
@@ -430,7 +430,7 @@ pub fn read_http_version<R: Reader>(stream: &mut R) -> HttpResult<HttpVersion> {
|
|||||||
},
|
},
|
||||||
b'1' => {
|
b'1' => {
|
||||||
try!(expect(stream.read_byte(), b'.'));
|
try!(expect(stream.read_byte(), b'.'));
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
b'0' => Ok(Http10),
|
b'0' => Ok(Http10),
|
||||||
b'1' => Ok(Http11),
|
b'1' => Ok(Http11),
|
||||||
_ => Err(HttpVersionError)
|
_ => Err(HttpVersionError)
|
||||||
@@ -476,9 +476,9 @@ pub fn read_header<R: Reader>(stream: &mut R) -> HttpResult<Option<RawHeaderLine
|
|||||||
let mut value = vec![];
|
let mut value = vec![];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
CR if name.len() == 0 => {
|
CR if name.len() == 0 => {
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
LF => return Ok(None),
|
LF => return Ok(None),
|
||||||
_ => return Err(HttpHeaderError)
|
_ => return Err(HttpHeaderError)
|
||||||
}
|
}
|
||||||
@@ -495,7 +495,7 @@ pub fn read_header<R: Reader>(stream: &mut R) -> HttpResult<Option<RawHeaderLine
|
|||||||
|
|
||||||
todo!("handle obs-folding (gross!)");
|
todo!("handle obs-folding (gross!)");
|
||||||
loop {
|
loop {
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
CR => break,
|
CR => break,
|
||||||
LF => return Err(HttpHeaderError),
|
LF => return Err(HttpHeaderError),
|
||||||
b' ' if ows => {},
|
b' ' if ows => {},
|
||||||
@@ -508,7 +508,7 @@ pub fn read_header<R: Reader>(stream: &mut R) -> HttpResult<Option<RawHeaderLine
|
|||||||
|
|
||||||
debug!("header value = {}", value);
|
debug!("header value = {}", value);
|
||||||
|
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
LF => Ok(Some((name, value))),
|
LF => Ok(Some((name, value))),
|
||||||
_ => Err(HttpHeaderError)
|
_ => Err(HttpHeaderError)
|
||||||
}
|
}
|
||||||
@@ -528,10 +528,10 @@ pub fn read_request_line<R: Reader>(stream: &mut R) -> HttpResult<RequestLine> {
|
|||||||
let version = try!(read_http_version(stream));
|
let version = try!(read_http_version(stream));
|
||||||
debug!("version = {}", version);
|
debug!("version = {}", version);
|
||||||
|
|
||||||
if try_io!(stream.read_byte()) != CR {
|
if try!(stream.read_byte()) != CR {
|
||||||
return Err(HttpVersionError);
|
return Err(HttpVersionError);
|
||||||
}
|
}
|
||||||
if try_io!(stream.read_byte()) != LF {
|
if try!(stream.read_byte()) != LF {
|
||||||
return Err(HttpVersionError);
|
return Err(HttpVersionError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,7 +557,7 @@ pub type StatusLine = (HttpVersion, status::StatusCode);
|
|||||||
/// >```
|
/// >```
|
||||||
pub fn read_status_line<R: Reader>(stream: &mut R) -> HttpResult<StatusLine> {
|
pub fn read_status_line<R: Reader>(stream: &mut R) -> HttpResult<StatusLine> {
|
||||||
let version = try!(read_http_version(stream));
|
let version = try!(read_http_version(stream));
|
||||||
if try_io!(stream.read_byte()) != SP {
|
if try!(stream.read_byte()) != SP {
|
||||||
return Err(HttpVersionError);
|
return Err(HttpVersionError);
|
||||||
}
|
}
|
||||||
let code = try!(read_status(stream));
|
let code = try!(read_status(stream));
|
||||||
@@ -568,9 +568,9 @@ pub fn read_status_line<R: Reader>(stream: &mut R) -> HttpResult<StatusLine> {
|
|||||||
/// Read the StatusCode from a stream.
|
/// Read the StatusCode from a stream.
|
||||||
pub fn read_status<R: Reader>(stream: &mut R) -> HttpResult<status::StatusCode> {
|
pub fn read_status<R: Reader>(stream: &mut R) -> HttpResult<status::StatusCode> {
|
||||||
let code = [
|
let code = [
|
||||||
try_io!(stream.read_byte()),
|
try!(stream.read_byte()),
|
||||||
try_io!(stream.read_byte()),
|
try!(stream.read_byte()),
|
||||||
try_io!(stream.read_byte()),
|
try!(stream.read_byte()),
|
||||||
];
|
];
|
||||||
|
|
||||||
let code = match str::from_utf8(code.as_slice()).and_then(from_str::<u16>) {
|
let code = match str::from_utf8(code.as_slice()).and_then(from_str::<u16>) {
|
||||||
@@ -583,8 +583,8 @@ pub fn read_status<R: Reader>(stream: &mut R) -> HttpResult<status::StatusCode>
|
|||||||
|
|
||||||
// reason is purely for humans, so just consume it till we get to CRLF
|
// reason is purely for humans, so just consume it till we get to CRLF
|
||||||
loop {
|
loop {
|
||||||
match try_io!(stream.read_byte()) {
|
match try!(stream.read_byte()) {
|
||||||
CR => match try_io!(stream.read_byte()) {
|
CR => match try!(stream.read_byte()) {
|
||||||
LF => break,
|
LF => break,
|
||||||
_ => return Err(HttpStatusError)
|
_ => return Err(HttpStatusError)
|
||||||
},
|
},
|
||||||
|
|||||||
31
src/lib.rs
31
src/lib.rs
@@ -145,15 +145,12 @@ pub use status::{Ok, BadRequest, NotFound};
|
|||||||
pub use server::Server;
|
pub use server::Server;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::error::{Error, FromError};
|
||||||
use std::io::IoError;
|
use std::io::IoError;
|
||||||
|
|
||||||
use std::rt::backtrace;
|
use std::rt::backtrace;
|
||||||
|
|
||||||
|
|
||||||
macro_rules! try_io(
|
|
||||||
($e:expr) => (match $e { Ok(v) => v, Err(e) => return Err(::HttpIoError(e)) })
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! todo(
|
macro_rules! todo(
|
||||||
($($arg:tt)*) => (if cfg!(not(ndebug)) {
|
($($arg:tt)*) => (if cfg!(not(ndebug)) {
|
||||||
format_args!(|args| log!(5, "TODO: {}", args), $($arg)*)
|
format_args!(|args| log!(5, "TODO: {}", args), $($arg)*)
|
||||||
@@ -222,6 +219,32 @@ pub enum HttpError {
|
|||||||
HttpIoError(IoError),
|
HttpIoError(IoError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Error for HttpError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
HttpMethodError => "Invalid Method specified",
|
||||||
|
HttpUriError => "Invalid Request URI specified",
|
||||||
|
HttpVersionError => "Invalid HTTP version specified",
|
||||||
|
HttpHeaderError => "Invalid Header provided",
|
||||||
|
HttpStatusError => "Invalid Status provided",
|
||||||
|
HttpIoError(_) => "An IoError occurred while connecting to the specified network",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cause(&self) -> Option<&Error> {
|
||||||
|
match *self {
|
||||||
|
HttpIoError(ref error) => Some(error as &Error),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromError<IoError> for HttpError {
|
||||||
|
fn from_error(err: IoError) -> HttpError {
|
||||||
|
HttpIoError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//FIXME: when Opt-in Built-in Types becomes a thing, we can force these structs
|
//FIXME: when Opt-in Built-in Types becomes a thing, we can force these structs
|
||||||
//to be Send. For now, this has the compiler do a static check.
|
//to be Send. For now, this has the compiler do a static check.
|
||||||
fn _assert_send<T: Send>() {
|
fn _assert_send<T: Send>() {
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ impl<L: NetworkListener<S, A>, S: NetworkStream, A: NetworkAcceptor<S>> Server<L
|
|||||||
A: NetworkAcceptor<S>,
|
A: NetworkAcceptor<S>,
|
||||||
L: NetworkListener<S, A>, {
|
L: NetworkListener<S, A>, {
|
||||||
debug!("binding to {}:{}", self.ip, self.port);
|
debug!("binding to {}:{}", self.ip, self.port);
|
||||||
let mut listener: L = try_io!(NetworkListener::<S, A>::bind((self.ip, self.port)));
|
let mut listener: L = try!(NetworkListener::<S, A>::bind((self.ip, self.port)));
|
||||||
|
|
||||||
let socket = try_io!(listener.socket_name());
|
let socket = try!(listener.socket_name());
|
||||||
|
|
||||||
let acceptor = try_io!(listener.listen());
|
let acceptor = try!(listener.listen());
|
||||||
|
|
||||||
let captured = acceptor.clone();
|
let captured = acceptor.clone();
|
||||||
TaskBuilder::new().named("hyper acceptor").spawn(proc() {
|
TaskBuilder::new().named("hyper acceptor").spawn(proc() {
|
||||||
@@ -131,7 +131,7 @@ impl<A: NetworkAcceptor<S>, S: NetworkStream> Listening<A> {
|
|||||||
/// and does not close the rest of the acceptors.
|
/// and does not close the rest of the acceptors.
|
||||||
pub fn close(&mut self) -> HttpResult<()> {
|
pub fn close(&mut self) -> HttpResult<()> {
|
||||||
debug!("closing server");
|
debug!("closing server");
|
||||||
try_io!(self.acceptor.close());
|
try!(self.acceptor.close());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl Request {
|
|||||||
/// Create a new Request, reading the StartLine and Headers so they are
|
/// Create a new Request, reading the StartLine and Headers so they are
|
||||||
/// immediately useful.
|
/// immediately useful.
|
||||||
pub fn new<S: NetworkStream>(mut stream: S) -> HttpResult<Request> {
|
pub fn new<S: NetworkStream>(mut stream: S) -> HttpResult<Request> {
|
||||||
let remote_addr = try_io!(stream.peer_name());
|
let remote_addr = try!(stream.peer_name());
|
||||||
debug!("remote addr = {}", remote_addr);
|
debug!("remote addr = {}", remote_addr);
|
||||||
let mut stream = BufferedReader::new(box stream as Box<NetworkStream + Send>);
|
let mut stream = BufferedReader::new(box stream as Box<NetworkStream + Send>);
|
||||||
let (method, uri, version) = try!(read_request_line(&mut stream));
|
let (method, uri, version) = try!(read_request_line(&mut stream));
|
||||||
|
|||||||
Reference in New Issue
Block a user