diff --git a/guide/src/qs_5.md b/guide/src/qs_5.md index 33b107099..1b9a707ea 100644 --- a/guide/src/qs_5.md +++ b/guide/src/qs_5.md @@ -526,3 +526,27 @@ predicates match. i.e: ```rust,ignore pred::All(vec![pred::Get(), pred::Header("content-type", "plain/text")]) ``` + +## Changing the default Not Found response + +If path pattern can not be found in routing table or resource can not find matching +route default resource is used. Default response is *NOT FOUND* response. +To override *NOT FOUND* resource use `Application::default_resource()` method. +This method accepts *configuration function* same as normal resource registration +with `Application::resource()` method. + +``rust +# extern crate actix_web; +# extern crate http; +use actix_web::*; +use actix_web::httpcodes::*; + +fn main() { + Application::new() + .default_resource(|r| + r.method(Method::GET).f(|req| HTTPNotFound); + r.route().p(pred::Not(pred::Get()).f(|req| HTTPMethodNotAllowed); + }) + .finish(); +} +``` diff --git a/src/application.rs b/src/application.rs index b094292b3..9da145f03 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use std::collections::HashMap; -use handler::{Reply, RouteHandler}; +use handler::Reply; use router::{Router, Pattern}; use resource::Resource; use httprequest::HttpRequest; @@ -27,9 +27,9 @@ impl HttpApplication { pub(crate) fn run(&self, mut req: HttpRequest) -> Reply { if let Some(h) = self.router.recognize(&mut req) { - h.handle(req) + h.handle(req.clone(), Some(&self.default)) } else { - self.default.handle(req) + self.default.handle(req, None) } } } @@ -196,7 +196,7 @@ impl Application where S: 'static { self } - /// Default resource is used if no match route could be found. + /// Default resource is used if no matched route could be found. pub fn default_resource(&mut self, f: F) -> &mut Self where F: FnOnce(&mut Resource) + 'static { diff --git a/src/resource.rs b/src/resource.rs index 0053b84ed..523a30966 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -1,12 +1,13 @@ use std::marker::PhantomData; -use http::Method; +use http::{Method, StatusCode}; use pred; +use body::Body; use route::Route; -use handler::{Reply, Handler, FromRequest, RouteHandler}; -use httpcodes::HTTPNotFound; +use handler::{Reply, Handler, FromRequest}; use httprequest::HttpRequest; +use httpresponse::HttpResponse; /// *Resource* is an entry in route table which corresponds to requested URL. /// @@ -124,16 +125,19 @@ impl Resource { self.routes.push(Route::default()); self.routes.last_mut().unwrap().f(handler) } -} -impl RouteHandler for Resource { - - fn handle(&self, mut req: HttpRequest) -> Reply { + pub(crate) fn handle(&self, mut req: HttpRequest, default: Option<&Resource>) + -> Reply + { for route in &self.routes { if route.check(&mut req) { return route.handle(req) } } - Reply::response(HTTPNotFound) + if let Some(resource) = default { + resource.handle(req, None) + } else { + Reply::response(HttpResponse::new(StatusCode::NOT_FOUND, Body::Empty)) + } } }