1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +01:00

unify route not found handling

This commit is contained in:
Nikolay Kim 2017-12-11 16:26:51 -08:00
parent b1ae7f95cc
commit 007b7ce62f
3 changed files with 40 additions and 12 deletions

View File

@ -526,3 +526,27 @@ predicates match. i.e:
```rust,ignore ```rust,ignore
pred::All(vec![pred::Get(), pred::Header("content-type", "plain/text")]) 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();
}
```

View File

@ -1,7 +1,7 @@
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap; use std::collections::HashMap;
use handler::{Reply, RouteHandler}; use handler::Reply;
use router::{Router, Pattern}; use router::{Router, Pattern};
use resource::Resource; use resource::Resource;
use httprequest::HttpRequest; use httprequest::HttpRequest;
@ -27,9 +27,9 @@ impl<S: 'static> HttpApplication<S> {
pub(crate) fn run(&self, mut req: HttpRequest<S>) -> Reply { pub(crate) fn run(&self, mut req: HttpRequest<S>) -> Reply {
if let Some(h) = self.router.recognize(&mut req) { if let Some(h) = self.router.recognize(&mut req) {
h.handle(req) h.handle(req.clone(), Some(&self.default))
} else { } else {
self.default.handle(req) self.default.handle(req, None)
} }
} }
} }
@ -196,7 +196,7 @@ impl<S> Application<S> where S: 'static {
self 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<F>(&mut self, f: F) -> &mut Self pub fn default_resource<F>(&mut self, f: F) -> &mut Self
where F: FnOnce(&mut Resource<S>) + 'static where F: FnOnce(&mut Resource<S>) + 'static
{ {

View File

@ -1,12 +1,13 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use http::Method; use http::{Method, StatusCode};
use pred; use pred;
use body::Body;
use route::Route; use route::Route;
use handler::{Reply, Handler, FromRequest, RouteHandler}; use handler::{Reply, Handler, FromRequest};
use httpcodes::HTTPNotFound;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse;
/// *Resource* is an entry in route table which corresponds to requested URL. /// *Resource* is an entry in route table which corresponds to requested URL.
/// ///
@ -124,16 +125,19 @@ impl<S: 'static> Resource<S> {
self.routes.push(Route::default()); self.routes.push(Route::default());
self.routes.last_mut().unwrap().f(handler) self.routes.last_mut().unwrap().f(handler)
} }
}
impl<S: 'static> RouteHandler<S> for Resource<S> { pub(crate) fn handle(&self, mut req: HttpRequest<S>, default: Option<&Resource<S>>)
-> Reply
fn handle(&self, mut req: HttpRequest<S>) -> Reply { {
for route in &self.routes { for route in &self.routes {
if route.check(&mut req) { if route.check(&mut req) {
return route.handle(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))
}
} }
} }