1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-12-02 19:12:24 +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 .middleware(middlewares::Logger::default()) // <- register logger middleware
.resource("/ws/", |r| .resource("/ws/", |r|
r.method(Method::GET).f(|req| ws::start(req, MyWebSocket))) // <- websocket route 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(); .serve::<_, ()>("127.0.0.1:8080").unwrap();
Arbiter::system().send(msgs::SystemExit(0)); Arbiter::system().send(msgs::SystemExit(0));

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -57,7 +57,7 @@ mod httpresponse;
mod payload; mod payload;
mod resource; mod resource;
mod recognizer; mod recognizer;
mod route; mod handler;
mod pipeline; mod pipeline;
mod server; mod server;
mod channel; mod channel;
@ -83,7 +83,7 @@ pub use application::Application;
pub use httprequest::{HttpRequest, UrlEncoded}; pub use httprequest::{HttpRequest, UrlEncoded};
pub use httpresponse::HttpResponse; pub use httpresponse::HttpResponse;
pub use payload::{Payload, PayloadItem}; pub use payload::{Payload, PayloadItem};
pub use route::{Reply, Json, FromRequest}; pub use handler::{Reply, Json, FromRequest};
pub use resource::{Route, Resource}; pub use resource::{Route, Resource};
pub use recognizer::Params; pub use recognizer::Params;
pub use server::HttpServer; 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 body::{Body, BodyStream};
use context::{Frame, IoContext}; use context::{Frame, IoContext};
use error::{Error, UnexpectedTaskFrame}; use error::{Error, UnexpectedTaskFrame};
use route::{Reply, ReplyItem}; use handler::{Reply, ReplyItem};
use h1writer::{Writer, WriterState}; use h1writer::{Writer, WriterState};
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;

View File

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

View File

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