From 5605ade5dce889a5c164b3ffd9eb8c0ef5c651cf Mon Sep 17 00:00:00 2001 From: Tim Kuehn Date: Mon, 10 Nov 2014 22:59:18 -0800 Subject: [PATCH] impl Error and FromError for HttpError; replace instances of try_io! with try! --- src/client/request.rs | 16 ++++++++-------- src/http.rs | 36 ++++++++++++++++++------------------ src/lib.rs | 31 +++++++++++++++++++++++++++---- src/server/mod.rs | 8 ++++---- src/server/request.rs | 2 +- 5 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/client/request.rs b/src/client/request.rs index 0ccecfc0..52c60cfd 100644 --- a/src/client/request.rs +++ b/src/client/request.rs @@ -56,7 +56,7 @@ impl Request { }; 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)); let mut headers = Headers::new(); @@ -113,15 +113,15 @@ impl Request { } debug!("writing head: {} {} {}", self.method, uri, self.version); - try_io!(write!(self.body, "{} {} {}", self.method, uri, self.version)) - try_io!(self.body.write(LINE_ENDING)); + try!(write!(self.body, "{} {} {}", self.method, uri, self.version)) + try!(self.body.write(LINE_ENDING)); let stream = match self.method { Get | Head => { debug!("headers [\n{}]", self.headers); - try_io!(write!(self.body, "{}", self.headers)); - try_io!(self.body.write(LINE_ENDING)); + try!(write!(self.body, "{}", self.headers)); + try!(self.body.write(LINE_ENDING)); EmptyWriter(self.body.unwrap()) }, _ => { @@ -154,8 +154,8 @@ impl Request { } debug!("headers [\n{}]", self.headers); - try_io!(write!(self.body, "{}", self.headers)); - try_io!(self.body.write(LINE_ENDING)); + try!(write!(self.body, "{}", self.headers)); + try!(self.body.write(LINE_ENDING)); if chunked { ChunkedWriter(self.body.unwrap()) @@ -184,7 +184,7 @@ impl Request { /// /// Consumes the Request. pub fn send(self) -> HttpResult { - let raw = try_io!(self.body.end()).unwrap(); + let raw = try!(self.body.end()).unwrap(); Response::new(raw) } } diff --git a/src/http.rs b/src/http.rs index 40311de7..7069ea97 100644 --- a/src/http.rs +++ b/src/http.rs @@ -301,7 +301,7 @@ fn read_until_space(stream: &mut R, buf: &mut [u8]) -> HttpResult bool { /// Read a `RequestUri` from a raw stream. pub fn read_uri(stream: &mut R) -> HttpResult { - let mut b = try_io!(stream.read_byte()); + let mut b = try!(stream.read_byte()); while b == SP { - b = try_io!(stream.read_byte()); + b = try!(stream.read_byte()); } let mut s = String::new(); @@ -371,7 +371,7 @@ pub fn read_uri(stream: &mut R) -> HttpResult { } else { s.push(b as char); loop { - match try_io!(stream.read_byte()) { + match try!(stream.read_byte()) { SP => { break; }, @@ -422,7 +422,7 @@ pub fn read_http_version(stream: &mut R) -> HttpResult { try!(expect(stream.read_byte(), b'P')); try!(expect(stream.read_byte(), b'/')); - match try_io!(stream.read_byte()) { + match try!(stream.read_byte()) { b'0' => { try!(expect(stream.read_byte(), b'.')); try!(expect(stream.read_byte(), b'9')); @@ -430,7 +430,7 @@ pub fn read_http_version(stream: &mut R) -> HttpResult { }, b'1' => { try!(expect(stream.read_byte(), b'.')); - match try_io!(stream.read_byte()) { + match try!(stream.read_byte()) { b'0' => Ok(Http10), b'1' => Ok(Http11), _ => Err(HttpVersionError) @@ -476,9 +476,9 @@ pub fn read_header(stream: &mut R) -> HttpResult { - match try_io!(stream.read_byte()) { + match try!(stream.read_byte()) { LF => return Ok(None), _ => return Err(HttpHeaderError) } @@ -495,7 +495,7 @@ pub fn read_header(stream: &mut R) -> HttpResult break, LF => return Err(HttpHeaderError), b' ' if ows => {}, @@ -508,7 +508,7 @@ pub fn read_header(stream: &mut R) -> HttpResult Ok(Some((name, value))), _ => Err(HttpHeaderError) } @@ -528,10 +528,10 @@ pub fn read_request_line(stream: &mut R) -> HttpResult { let version = try!(read_http_version(stream)); debug!("version = {}", version); - if try_io!(stream.read_byte()) != CR { + if try!(stream.read_byte()) != CR { return Err(HttpVersionError); } - if try_io!(stream.read_byte()) != LF { + if try!(stream.read_byte()) != LF { return Err(HttpVersionError); } @@ -557,7 +557,7 @@ pub type StatusLine = (HttpVersion, status::StatusCode); /// >``` pub fn read_status_line(stream: &mut R) -> HttpResult { let version = try!(read_http_version(stream)); - if try_io!(stream.read_byte()) != SP { + if try!(stream.read_byte()) != SP { return Err(HttpVersionError); } let code = try!(read_status(stream)); @@ -568,9 +568,9 @@ pub fn read_status_line(stream: &mut R) -> HttpResult { /// Read the StatusCode from a stream. pub fn read_status(stream: &mut R) -> HttpResult { let code = [ - try_io!(stream.read_byte()), - try_io!(stream.read_byte()), - try_io!(stream.read_byte()), + try!(stream.read_byte()), + try!(stream.read_byte()), + try!(stream.read_byte()), ]; let code = match str::from_utf8(code.as_slice()).and_then(from_str::) { @@ -583,8 +583,8 @@ pub fn read_status(stream: &mut R) -> HttpResult // reason is purely for humans, so just consume it till we get to CRLF loop { - match try_io!(stream.read_byte()) { - CR => match try_io!(stream.read_byte()) { + match try!(stream.read_byte()) { + CR => match try!(stream.read_byte()) { LF => break, _ => return Err(HttpStatusError) }, diff --git a/src/lib.rs b/src/lib.rs index 758d9789..89f50888 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -145,15 +145,12 @@ pub use status::{Ok, BadRequest, NotFound}; pub use server::Server; use std::fmt; +use std::error::{Error, FromError}; use std::io::IoError; use std::rt::backtrace; -macro_rules! try_io( - ($e:expr) => (match $e { Ok(v) => v, Err(e) => return Err(::HttpIoError(e)) }) -) - macro_rules! todo( ($($arg:tt)*) => (if cfg!(not(ndebug)) { format_args!(|args| log!(5, "TODO: {}", args), $($arg)*) @@ -222,6 +219,32 @@ pub enum HttpError { 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 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 //to be Send. For now, this has the compiler do a static check. fn _assert_send() { diff --git a/src/server/mod.rs b/src/server/mod.rs index 03373927..55638b11 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -55,11 +55,11 @@ impl, S: NetworkStream, A: NetworkAcceptor> Server, L: NetworkListener, { debug!("binding to {}:{}", self.ip, self.port); - let mut listener: L = try_io!(NetworkListener::::bind((self.ip, self.port))); + let mut listener: L = try!(NetworkListener::::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(); TaskBuilder::new().named("hyper acceptor").spawn(proc() { @@ -131,7 +131,7 @@ impl, S: NetworkStream> Listening { /// and does not close the rest of the acceptors. pub fn close(&mut self) -> HttpResult<()> { debug!("closing server"); - try_io!(self.acceptor.close()); + try!(self.acceptor.close()); Ok(()) } } diff --git a/src/server/request.rs b/src/server/request.rs index 214285c0..0fe76d2e 100644 --- a/src/server/request.rs +++ b/src/server/request.rs @@ -36,7 +36,7 @@ impl Request { /// Create a new Request, reading the StartLine and Headers so they are /// immediately useful. pub fn new(mut stream: S) -> HttpResult { - let remote_addr = try_io!(stream.peer_name()); + let remote_addr = try!(stream.peer_name()); debug!("remote addr = {}", remote_addr); let mut stream = BufferedReader::new(box stream as Box); let (method, uri, version) = try!(read_request_line(&mut stream));