diff --git a/README.md b/README.md
index d4b5324a..c259654e 100644
--- a/README.md
+++ b/README.md
@@ -19,8 +19,7 @@ fn hello(name: &str, age: u8) -> String {
}
fn main() {
- let mut rocket = Rocket::new("localhost", 8000);
- rocket.mount_and_launch("/hello", routes![hello]);
+ Rocket::new("localhost", 8000).mount_and_launch("/hello", routes![hello]);
}
```
diff --git a/examples/errors/src/main.rs b/examples/errors/src/main.rs
index a55d7793..5c668e61 100644
--- a/examples/errors/src/main.rs
+++ b/examples/errors/src/main.rs
@@ -11,13 +11,12 @@ fn hello(name: &str, age: i8) -> String {
#[error(code = "404")]
fn not_found() -> &'static str {
- "Sorry, I couldn't find what you're looking for."
+ "
Sorry pal.
Go to '/hello/<name>/<age>' instead.
"
}
fn main() {
let mut rocket = Rocket::new("localhost", 8000);
rocket.mount("/", routes![hello]);
rocket.catch(errors![not_found]);
- // rocket.catch_and_launch(errors![not_found]);
rocket.launch();
}
diff --git a/lib/src/catcher.rs b/lib/src/catcher.rs
index d4252bac..95e0151b 100644
--- a/lib/src/catcher.rs
+++ b/lib/src/catcher.rs
@@ -8,15 +8,25 @@ use term_painter::Color::*;
pub struct Catcher {
pub code: u16,
pub handler: Handler,
+ is_default: bool
}
impl Catcher {
pub fn new(code: u16, handler: Handler) -> Catcher {
+ Catcher::new_with_default(code, handler, false)
+ }
+
+ fn new_with_default(code: u16, handler: Handler, default: bool) -> Catcher {
Catcher {
code: code,
handler: handler,
+ is_default: default
}
}
+
+ pub fn is_default(&self) -> bool {
+ self.is_default
+ }
}
impl<'a> From<&'a StaticCatchInfo> for Catcher {
@@ -27,6 +37,52 @@ impl<'a> From<&'a StaticCatchInfo> for Catcher {
impl fmt::Display for Catcher {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{} {}", Blue.paint(&self.code), Blue.paint("catcher."))
+ write!(f, "{}", Blue.paint(&self.code))
}
}
+
+pub mod defaults {
+ use request::Request;
+ use response::Response;
+ use super::Catcher;
+ use std::collections::HashMap;
+
+ pub fn get() -> HashMap {
+ let mut map = HashMap::new();
+ map.insert(404, Catcher::new_with_default(404, not_found, true));
+ map.insert(500, Catcher::new_with_default(500, internal_error, true));
+ map
+ }
+
+ pub fn not_found(_request: Request) -> Response {
+ // FIXME: Need a way to pass in the status code.
+ Response::new("\
+ \
+ \
+ 404: Not Found\
+ \
+ \
+ 404: Not Found
\
+ The page you were looking for could not be found.
\
+
\
+ Rocket\
+ \
+ ")
+ }
+
+ pub fn internal_error(_request: Request) -> Response {
+ // FIXME: Need a way to pass in the status code.
+ Response::new("\
+ \
+ \
+ 404: Not Found\
+ \
+ \
+ 500: Internal Server Error
\
+ The server encountered a problem processing your request.
\
+
\
+ Rocket\
+ ")
+ }
+}
+
diff --git a/lib/src/response/with_status.rs b/lib/src/response/with_status.rs
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/src/rocket.rs b/lib/src/rocket.rs
index 86a91564..5f5bb9c3 100644
--- a/lib/src/rocket.rs
+++ b/lib/src/rocket.rs
@@ -1,8 +1,10 @@
use super::*;
use response::{HyperResponse, HyperFresh};
use request::HyperRequest;
+use catcher;
use std::io::Read;
+use std::collections::HashMap;
use term_painter::Color::*;
use term_painter::ToStyle;
@@ -14,37 +16,45 @@ pub struct Rocket {
address: &'static str,
port: isize,
router: Router,
- catchers: Vec,
+ catchers: HashMap,
}
impl HyperHandler for Rocket {
fn handle<'a, 'k>(&'a self, mut req: HyperRequest<'a, 'k>,
res: HyperResponse<'a, HyperFresh>) {
- println!("{} {:?} {:?}", White.paint("Incoming:"),
- Green.paint(&req.method), Blue.paint(&req.uri));
+ println!("{:?} {:?}", Green.paint(&req.method), Blue.paint(&req.uri));
let mut buf = vec![];
req.read_to_end(&mut buf); // FIXME: Simple DOS attack here.
if let HyperRequestUri::AbsolutePath(uri_string) = req.uri {
if let Some(method) = Method::from_hyp(req.method) {
-
let uri_str = uri_string.as_str();
let route = self.router.route(method, uri_str);
- let mut response = route.map_or(Response::not_found(), |route| {
+
+ if route.is_some() {
+ let route = route.unwrap();
let params = route.get_params(uri_str);
let request = Request::new(params, uri_str, &buf);
- (route.handler)(request)
- });
- println!("{}", Green.paint("\t=> Dispatched request."));
- return response.respond(res);
+ println!("{}", Green.paint("\t=> Dispatching request."));
+ // FIXME: Responder should be able to say it didn't work.
+ return (route.handler)(request).respond(res);
+ } else {
+ // FIXME: Try next highest ranking route, not just 404.
+ let request = Request::new(vec![], uri_str, &buf);
+ let handler_404 = self.catchers.get(&404).unwrap().handler;
+
+ let msg = "\t=> Dispatch failed. Returning 404.";
+ println!("{}", Red.paint(msg));
+ return handler_404(request).respond(res);
+ }
}
println!("{}", Yellow.paint("\t=> Debug: Method::from_hyp failed!"));
}
- println!("{}", Red.paint("\t=> Dispatch failed. Returning 404."));
- Response::not_found().respond(res);
+ println!("{}", Red.paint("\t=> Internal failure. Bad method or path."));
+ Response::server_error().respond(res);
}
}
@@ -54,7 +64,7 @@ impl Rocket {
address: address,
port: port,
router: Router::new(),
- catchers: Vec::new(),
+ catchers: catcher::defaults::get(),
}
}
@@ -73,9 +83,16 @@ impl Rocket {
pub fn catch(&mut self, catchers: Vec) -> &mut Self {
println!("👾 {}:", Magenta.paint("Catchers"));
- for catcher in catchers {
- println!("\t* {}", catcher);
- self.catchers.push(catcher);
+ for c in catchers {
+ if self.catchers.contains_key(&c.code) &&
+ !self.catchers.get(&c.code).unwrap().is_default() {
+ let msg = format!("warning: overrides {} catcher!", c.code);
+ println!("\t* {} ({})", c, Yellow.paint(msg.as_str()));
+ } else {
+ println!("\t* {}", c);
+ }
+
+ self.catchers.insert(c.code, c);
}
self