1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-27 17:22:57 +01:00

use Route for Applicaiton handlers

This commit is contained in:
Nikolay Kim 2017-12-04 14:53:40 -08:00
parent f5d6179a34
commit e332c1242f
16 changed files with 61 additions and 80 deletions

View File

@ -110,7 +110,7 @@ fn main() {
.middleware(middlewares::Logger::default()) // <- register logger middleware
.resource("/ws/", |r|
r.method(Method::GET).f(|req| ws::start(req, MyWebSocket))) // <- websocket route
.route("/", fs::StaticFiles::new("examples/static/", true))) // <- serve static files
.route("/", |r| r.h(fs::StaticFiles::new("examples/static/", true)))) // <- serve static files
.serve::<_, ()>("127.0.0.1:8080").unwrap();
Arbiter::system().send(msgs::SystemExit(0));

View File

@ -66,8 +66,8 @@ fn main() {
.secure(false)
.finish()
))
// register simple handle r, handle all methods
.handler("/index.html", index)
// register simple route, handle all methods
.route("/index.html", |r| r.f(index))
// with path parameters
.resource("/user/{name}/", |r| r.route().method(Method::GET).f(with_param))
// async handler
@ -81,15 +81,15 @@ fn main() {
.header("LOCATION", "/index.html")
.body(Body::Empty)
}))
.handler("/test", |req| {
.route("/test", |r| r.f(|req| {
match *req.method() {
Method::GET => httpcodes::HTTPOk,
Method::POST => httpcodes::HTTPMethodNotAllowed,
_ => httpcodes::HTTPNotFound,
}
})
}))
// static files
.route("/static", fs::StaticFiles::new("examples/static/", true)))
.route("/static", |r| r.h(fs::StaticFiles::new("examples/static/", true))))
.serve::<_, ()>("127.0.0.1:8080").unwrap();
println!("Started http server: 127.0.0.1:8080");

View File

@ -69,7 +69,7 @@ fn main() {
.method(Method::GET)
.f(|req| ws::start(req, MyWebSocket{counter: 0})))
// register simple handler, handle all methods
.handler("/", index))
.route("/", |r| r.f(index)))
.serve::<_, ()>("127.0.0.1:8080").unwrap();
println!("Started http server: 127.0.0.1:8080");

View File

@ -67,7 +67,7 @@ fn main() {
// websocket route
.resource("/ws/", |r| r.route().method(Method::GET).f(ws_index))
// static files
.route("/", fs::StaticFiles::new("examples/static/", true)))
.route("/", |r| r.h(fs::StaticFiles::new("examples/static/", true))))
// start http server on 127.0.0.1:8080
.serve::<_, ()>("127.0.0.1:8080").unwrap();

View File

@ -32,7 +32,7 @@ extern crate actix_web;
fn main() {
actix_web::Application::default("/")
.route("/static", actix_web::fs::StaticFiles::new(".", true))
.route("/static", |r| r.h(actix_web::fs::StaticFiles::new(".", true)))
.finish();
}
```

View File

@ -18,7 +18,7 @@ fn index(req: HttpRequest) -> HttpResponse {
fn main() {
Application::default("/")
.handler("/prefix", index)
.route("/prefix", |r| r.f(index))
.finish();
}
```
@ -37,7 +37,7 @@ fn index(req: HttpRequest) -> HttpResponse {
fn main() {
Application::default("/app")
.handler("/prefix", index)
.route("/prefix", |r| r.f(index))
.finish();
}
```

View File

@ -1,13 +1,10 @@
use std::rc::Rc;
use std::collections::HashMap;
use futures::Future;
use error::Error;
use route::{RouteHandler, Reply, Handler, FromRequest, WrapHandler, AsyncHandler};
use resource::Resource;
use handler::{Reply, RouteHandler};
use resource::{Route, Resource};
use recognizer::{RouteRecognizer, check_pattern};
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use channel::HttpHandler;
use pipeline::Pipeline;
use middlewares::Middleware;
@ -18,7 +15,7 @@ pub struct Application<S> {
state: Rc<S>,
prefix: String,
default: Resource<S>,
handlers: HashMap<String, Box<RouteHandler<S>>>,
routes: Vec<(String, Route<S>)>,
router: RouteRecognizer<Resource<S>>,
middlewares: Rc<Vec<Box<Middleware>>>,
}
@ -34,10 +31,10 @@ impl<S: 'static> Application<S> {
}
h.handle(req)
} else {
for (prefix, handler) in &self.handlers {
if req.path().starts_with(prefix) {
req.set_prefix(prefix.len());
return handler.handle(req)
for route in &self.routes {
if req.path().starts_with(&route.0) && route.1.check(&mut req) {
req.set_prefix(route.0.len());
return route.1.handle(req)
}
}
self.default.handle(req)
@ -66,7 +63,7 @@ impl Application<()> {
state: (),
prefix: prefix.into(),
default: Resource::default_not_found(),
handlers: HashMap::new(),
routes: Vec::new(),
resources: HashMap::new(),
middlewares: Vec::new(),
})
@ -85,7 +82,7 @@ impl<S> Application<S> where S: 'static {
state: state,
prefix: prefix.into(),
default: Resource::default_not_found(),
handlers: HashMap::new(),
routes: Vec::new(),
resources: HashMap::new(),
middlewares: Vec::new(),
})
@ -97,7 +94,7 @@ struct ApplicationBuilderParts<S> {
state: S,
prefix: String,
default: Resource<S>,
handlers: HashMap<String, Box<RouteHandler<S>>>,
routes: Vec<(String, Route<S>)>,
resources: HashMap<String, Resource<S>>,
middlewares: Vec<Box<Middleware>>,
}
@ -168,8 +165,10 @@ impl<S> ApplicationBuilder<S> where S: 'static {
self
}
/// This method register handler for specified path prefix.
/// Any path that starts with this prefix matches handler.
/// This method register route for specified path prefix.
/// Route maches based on path prefix, variable path patterns are not available
/// in this case. If you need variable path patterns consider using *resource()*
/// method.
///
/// ```rust
/// extern crate actix_web;
@ -177,49 +176,31 @@ impl<S> ApplicationBuilder<S> where S: 'static {
///
/// fn main() {
/// let app = Application::default("/")
/// .handler("/test", |req| {
/// match *req.method() {
/// Method::GET => httpcodes::HTTPOk,
/// Method::POST => httpcodes::HTTPMethodNotAllowed,
/// _ => httpcodes::HTTPNotFound,
/// }
/// })
/// .route("/test", |r| r.f(
/// |req| {
/// match *req.method() {
/// Method::GET => httpcodes::HTTPOk,
/// Method::POST => httpcodes::HTTPMethodNotAllowed,
/// _ => httpcodes::HTTPNotFound,
/// }
/// }
/// ))
/// .finish();
/// }
/// ```
pub fn handler<P, F, R>(&mut self, path: P, handler: F) -> &mut Self
pub fn route<F, P: Into<String>>(&mut self, path: P, f: F) -> &mut Self
where P: Into<String>,
F: Fn(HttpRequest<S>) -> R + 'static,
R: FromRequest + 'static
F: FnOnce(&mut Route<S>) + 'static
{
self.parts.as_mut().expect("Use after finish")
.handlers.insert(path.into(), Box::new(WrapHandler::new(handler)));
{
let parts = self.parts.as_mut().expect("Use after finish");
parts.routes.push((path.into(), Route::default()));
f(&mut parts.routes.last_mut().unwrap().1);
}
self
}
/// This method register handler for specified path prefix.
/// Any path that starts with this prefix matches handler.
pub fn route<P, H>(&mut self, path: P, handler: H) -> &mut Self
where P: Into<String>, H: Handler<S>
{
self.parts.as_mut().expect("Use after finish")
.handlers.insert(path.into(), Box::new(WrapHandler::new(handler)));
self
}
/// This method register async handler for specified path prefix.
/// Any path that starts with this prefix matches handler.
pub fn async<P, F, R>(&mut self, path: P, handler: F) -> &mut Self
where F: Fn(HttpRequest<S>) -> R + 'static,
R: Future<Item=HttpResponse, Error=Error> + 'static,
P: Into<String>,
{
self.parts.as_mut().expect("Use after finish")
.handlers.insert(path.into(), Box::new(AsyncHandler::new(handler)));
self
}
/// Construct application
/// Register a middleware
pub fn middleware<T>(&mut self, mw: T) -> &mut Self
where T: Middleware + 'static
{
@ -232,27 +213,27 @@ impl<S> ApplicationBuilder<S> where S: 'static {
pub fn finish(&mut self) -> Application<S> {
let parts = self.parts.take().expect("Use after finish");
let mut handlers = HashMap::new();
let prefix = if parts.prefix.ends_with('/') {
parts.prefix
} else {
parts.prefix + "/"
};
let mut routes = Vec::new();
let mut resources = Vec::new();
for (path, handler) in parts.resources {
routes.push((path, handler))
resources.push((path, handler))
}
for (path, handler) in parts.handlers {
handlers.insert(prefix.clone() + path.trim_left_matches('/'), handler);
let mut routes = Vec::new();
for (path, route) in parts.routes {
routes.push((prefix.clone() + path.trim_left_matches('/'), route));
}
Application {
state: Rc::new(parts.state),
prefix: prefix.clone(),
default: parts.default,
handlers: handlers,
router: RouteRecognizer::new(prefix, routes),
routes: routes,
router: RouteRecognizer::new(prefix, resources),
middlewares: Rc::new(parts.middlewares),
}
}

View File

@ -9,7 +9,7 @@
//! ```
// dev specific
pub use route::Handler;
pub use handler::Handler;
pub use pipeline::Pipeline;
pub use channel::{HttpChannel, HttpHandler};
pub use recognizer::{FromParam, RouteRecognizer};

View File

@ -9,7 +9,7 @@ use std::path::{Path, PathBuf};
use std::ops::{Deref, DerefMut};
use mime_guess::get_mime_type;
use route::{Handler, FromRequest};
use handler::{Handler, FromRequest};
use recognizer::FromParam;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
@ -198,7 +198,7 @@ impl FromRequest for FilesystemElement {
///
/// fn main() {
/// let app = actix_web::Application::default("/")
/// .route("/static", actix_web::fs::StaticFiles::new(".", true))
/// .route("/static", |r| r.h(actix_web::fs::StaticFiles::new(".", true)))
/// .finish();
/// }
/// ```

View File

@ -3,7 +3,7 @@
use http::{StatusCode, Error as HttpError};
use body::Body;
use route::{Reply, Handler, RouteHandler, FromRequest};
use handler::{Reply, Handler, RouteHandler, FromRequest};
use httprequest::HttpRequest;
use httpresponse::{HttpResponse, HttpResponseBuilder};

View File

@ -11,7 +11,7 @@ use serde::Serialize;
use Cookie;
use body::Body;
use error::Error;
use route::FromRequest;
use handler::FromRequest;
use encoding::ContentEncoding;
use httprequest::HttpRequest;

View File

@ -57,7 +57,7 @@ mod httpresponse;
mod payload;
mod resource;
mod recognizer;
mod route;
mod handler;
mod pipeline;
mod server;
mod channel;
@ -83,7 +83,7 @@ pub use application::Application;
pub use httprequest::{HttpRequest, UrlEncoded};
pub use httpresponse::HttpResponse;
pub use payload::{Payload, PayloadItem};
pub use route::{Reply, Json, FromRequest};
pub use handler::{Reply, Json, FromRequest};
pub use resource::{Route, Resource};
pub use recognizer::Params;
pub use server::HttpServer;

View File

@ -8,7 +8,7 @@ use futures::task::{Task as FutureTask, current as current_task};
use body::{Body, BodyStream};
use context::{Frame, IoContext};
use error::{Error, UnexpectedTaskFrame};
use route::{Reply, ReplyItem};
use handler::{Reply, ReplyItem};
use h1writer::{Writer, WriterState};
use httprequest::HttpRequest;
use httpresponse::HttpResponse;

View File

@ -5,7 +5,7 @@ use futures::Future;
use error::Error;
use pred::{self, Predicate};
use route::{Reply, Handler, FromRequest, RouteHandler, AsyncHandler, WrapHandler};
use handler::{Reply, Handler, FromRequest, RouteHandler, AsyncHandler, WrapHandler};
use httpcodes::HTTPNotFound;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
@ -31,7 +31,7 @@ impl<S: 'static> Default for Route<S> {
impl<S: 'static> Route<S> {
fn check(&self, req: &mut HttpRequest<S>) -> bool {
pub(crate) fn check(&self, req: &mut HttpRequest<S>) -> bool {
for pred in &self.preds {
if !pred.check(req) {
return false
@ -40,7 +40,7 @@ impl<S: 'static> Route<S> {
true
}
fn handle(&self, req: HttpRequest<S>) -> Reply {
pub(crate) fn handle(&self, req: HttpRequest<S>) -> Reply {
self.handler.handle(req)
}

View File

@ -56,7 +56,7 @@ use actix::{Actor, AsyncContext, ResponseType, StreamHandler};
use body::Body;
use context::HttpContext;
use route::Reply;
use handler::Reply;
use payload::Payload;
use error::{Error, WsHandshakeError};
use httprequest::HttpRequest;