mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-28 01:52:57 +01:00
refactor RouteHandler trait
This commit is contained in:
parent
6f833798c7
commit
16ceb741b8
@ -82,8 +82,15 @@ fn main() {
|
|||||||
.header("LOCATION", "/index.html")
|
.header("LOCATION", "/index.html")
|
||||||
.body(Body::Empty)
|
.body(Body::Empty)
|
||||||
}))
|
}))
|
||||||
|
.handler("/test", |req| {
|
||||||
|
match *req.method() {
|
||||||
|
Method::GET => httpcodes::HTTPOk,
|
||||||
|
Method::POST => httpcodes::HTTPMethodNotAllowed,
|
||||||
|
_ => httpcodes::HTTPNotFound,
|
||||||
|
}
|
||||||
|
})
|
||||||
// static files
|
// static files
|
||||||
.route_handler("/static", StaticFiles::new("examples/static/", true)))
|
.route("/static", 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");
|
||||||
|
@ -66,7 +66,8 @@ fn main() {
|
|||||||
.middleware(middlewares::Logger::default())
|
.middleware(middlewares::Logger::default())
|
||||||
// websocket route
|
// websocket route
|
||||||
.resource("/ws/", |r| r.get(ws_index))
|
.resource("/ws/", |r| r.get(ws_index))
|
||||||
.route_handler("/", StaticFiles::new("examples/static/", true)))
|
// static files
|
||||||
|
.route("/", 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();
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use std::rc::Rc;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use task::Task;
|
use task::Task;
|
||||||
use route::{RouteHandler, FnHandler, Reply};
|
use route::{RouteHandler, WrapHandler, Reply, Handler};
|
||||||
use resource::Resource;
|
use resource::Resource;
|
||||||
use recognizer::{RouteRecognizer, check_pattern};
|
use recognizer::{RouteRecognizer, check_pattern};
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
@ -126,10 +126,7 @@ impl<S> ApplicationBuilder<S> where S: 'static {
|
|||||||
/// store userid and friend in the exposed Params object:
|
/// store userid and friend in the exposed Params object:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// extern crate actix;
|
|
||||||
/// extern crate actix_web;
|
/// extern crate actix_web;
|
||||||
///
|
|
||||||
/// use actix::*;
|
|
||||||
/// use actix_web::*;
|
/// use actix_web::*;
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
@ -158,7 +155,7 @@ impl<S> ApplicationBuilder<S> where S: 'static {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default resource is used if no matches route could be found.
|
/// Default resource is used if no match 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
|
||||||
{
|
{
|
||||||
@ -178,7 +175,7 @@ impl<S> ApplicationBuilder<S> where S: 'static {
|
|||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let app = Application::default("/")
|
/// let app = Application::default("/")
|
||||||
/// .handler("/test", |req| {
|
/// .inline("/test", |req| {
|
||||||
/// match *req.method() {
|
/// match *req.method() {
|
||||||
/// Method::GET => httpcodes::HTTPOk,
|
/// Method::GET => httpcodes::HTTPOk,
|
||||||
/// Method::POST => httpcodes::HTTPMethodNotAllowed,
|
/// Method::POST => httpcodes::HTTPMethodNotAllowed,
|
||||||
@ -189,28 +186,22 @@ impl<S> ApplicationBuilder<S> where S: 'static {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn handler<P, F, R>(&mut self, path: P, handler: F) -> &mut Self
|
pub fn handler<P, F, R>(&mut self, path: P, handler: F) -> &mut Self
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where P: Into<String>,
|
||||||
R: Into<Reply> + 'static,
|
F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
P: Into<String>,
|
R: Into<Reply> + 'static
|
||||||
{
|
{
|
||||||
self.parts.as_mut().expect("Use after finish")
|
self.parts.as_mut().expect("Use after finish")
|
||||||
.handlers.insert(path.into(), Box::new(FnHandler::new(handler)));
|
.handlers.insert(path.into(), Box::new(WrapHandler::new(handler)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add path handler
|
/// This method register handler for specified path prefix.
|
||||||
pub fn route_handler<H, P>(&mut self, path: P, h: H) -> &mut Self
|
/// Any path that starts with this prefix matches handler.
|
||||||
where H: RouteHandler<S> + 'static, P: Into<String>
|
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")
|
||||||
// add resource
|
.handlers.insert(path.into(), Box::new(WrapHandler::new(handler)));
|
||||||
let parts = self.parts.as_mut().expect("Use after finish");
|
|
||||||
let path = path.into();
|
|
||||||
if parts.handlers.contains_key(&path) {
|
|
||||||
panic!("Handler already registered: {:?}", path);
|
|
||||||
}
|
|
||||||
parts.handlers.insert(path, Box::new(h));
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
// dev specific
|
// dev specific
|
||||||
pub use task::Task;
|
pub use task::Task;
|
||||||
|
pub use route::Handler;
|
||||||
pub use pipeline::Pipeline;
|
pub use pipeline::Pipeline;
|
||||||
pub use recognizer::RouteRecognizer;
|
pub use recognizer::RouteRecognizer;
|
||||||
pub use channel::HttpChannel;
|
pub use channel::HttpChannel;
|
||||||
|
@ -82,7 +82,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::{Frame, RouteHandler, Reply};
|
pub use route::{Frame, Reply};
|
||||||
pub use resource::Resource;
|
pub use resource::Resource;
|
||||||
pub use recognizer::Params;
|
pub use recognizer::Params;
|
||||||
pub use server::HttpServer;
|
pub use server::HttpServer;
|
||||||
|
@ -6,7 +6,7 @@ use futures::Stream;
|
|||||||
|
|
||||||
use task::Task;
|
use task::Task;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use route::{Reply, RouteHandler, Frame, FnHandler, StreamHandler};
|
use route::{Reply, RouteHandler, Frame, WrapHandler, Handler, StreamHandler};
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
use httpcodes::{HTTPNotFound, HTTPMethodNotAllowed};
|
use httpcodes::{HTTPNotFound, HTTPMethodNotAllowed};
|
||||||
|
|
||||||
@ -17,13 +17,12 @@ use httpcodes::{HTTPNotFound, HTTPMethodNotAllowed};
|
|||||||
/// Resource in turn has at least one route.
|
/// Resource in turn has at least one route.
|
||||||
/// Route corresponds to handling HTTP method by calling route handler.
|
/// Route corresponds to handling HTTP method by calling route handler.
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust
|
||||||
///
|
/// extern crate actix_web;
|
||||||
/// struct MyRoute;
|
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let router = RoutingMap::default()
|
/// let app = actix_web::Application::default("/")
|
||||||
/// .resource("/", |r| r.post::<MyRoute>())
|
/// .resource("/", |r| r.get(|_| actix_web::HttpResponse::Ok()))
|
||||||
/// .finish();
|
/// .finish();
|
||||||
/// }
|
/// }
|
||||||
pub struct Resource<S=()> {
|
pub struct Resource<S=()> {
|
||||||
@ -63,7 +62,7 @@ impl<S> Resource<S> where S: 'static {
|
|||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Into<Reply> + 'static,
|
R: Into<Reply> + 'static,
|
||||||
{
|
{
|
||||||
self.routes.insert(method, Box::new(FnHandler::new(handler)));
|
self.routes.insert(method, Box::new(WrapHandler::new(handler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register async handler for specified method.
|
/// Register async handler for specified method.
|
||||||
@ -74,51 +73,42 @@ impl<S> Resource<S> where S: 'static {
|
|||||||
self.routes.insert(method, Box::new(StreamHandler::new(handler)));
|
self.routes.insert(method, Box::new(StreamHandler::new(handler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register handler for specified method.
|
|
||||||
pub fn route_handler<H>(&mut self, method: Method, handler: H)
|
|
||||||
where H: RouteHandler<S>
|
|
||||||
{
|
|
||||||
self.routes.insert(method, Box::new(handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Default handler is used if no matched route found.
|
/// Default handler is used if no matched route found.
|
||||||
/// By default `HTTPMethodNotAllowed` is used.
|
/// By default `HTTPMethodNotAllowed` is used.
|
||||||
pub fn default_handler<H>(&mut self, handler: H)
|
pub fn default_handler<H>(&mut self, handler: H) where H: Handler<S>
|
||||||
where H: RouteHandler<S>
|
|
||||||
{
|
{
|
||||||
self.default = Box::new(handler);
|
self.default = Box::new(WrapHandler::new(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler for `GET` method.
|
/// Handler for `GET` method.
|
||||||
pub fn get<F, R>(&mut self, handler: F)
|
pub fn get<F, R>(&mut self, handler: F)
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Into<Reply> + 'static, {
|
R: Into<Reply> + 'static, {
|
||||||
self.routes.insert(Method::GET, Box::new(FnHandler::new(handler)));
|
self.routes.insert(Method::GET, Box::new(WrapHandler::new(handler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler for `POST` method.
|
/// Handler for `POST` method.
|
||||||
pub fn post<F, R>(&mut self, handler: F)
|
pub fn post<F, R>(&mut self, handler: F)
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Into<Reply> + 'static, {
|
R: Into<Reply> + 'static, {
|
||||||
self.routes.insert(Method::POST, Box::new(FnHandler::new(handler)));
|
self.routes.insert(Method::POST, Box::new(WrapHandler::new(handler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler for `PUT` method.
|
/// Handler for `PUT` method.
|
||||||
pub fn put<F, R>(&mut self, handler: F)
|
pub fn put<F, R>(&mut self, handler: F)
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Into<Reply> + 'static, {
|
R: Into<Reply> + 'static, {
|
||||||
self.routes.insert(Method::PUT, Box::new(FnHandler::new(handler)));
|
self.routes.insert(Method::PUT, Box::new(WrapHandler::new(handler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler for `DELETE` method.
|
/// Handler for `DELETE` method.
|
||||||
pub fn delete<F, R>(&mut self, handler: F)
|
pub fn delete<F, R>(&mut self, handler: F)
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Into<Reply> + 'static, {
|
R: Into<Reply> + 'static, {
|
||||||
self.routes.insert(Method::DELETE, Box::new(FnHandler::new(handler)));
|
self.routes.insert(Method::DELETE, Box::new(WrapHandler::new(handler)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<S: 'static> RouteHandler<S> for Resource<S> {
|
impl<S: 'static> RouteHandler<S> for Resource<S> {
|
||||||
|
|
||||||
fn handle(&self, req: HttpRequest<S>, task: &mut Task) {
|
fn handle(&self, req: HttpRequest<S>, task: &mut Task) {
|
||||||
|
197
src/route.rs
197
src/route.rs
@ -4,15 +4,14 @@ use std::marker::PhantomData;
|
|||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
|
|
||||||
use actix::Actor;
|
use actix::Actor;
|
||||||
// use http::{header, Version};
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
|
|
||||||
use task::{Task, DrainFut, IoContext};
|
|
||||||
use body::Binary;
|
use body::Binary;
|
||||||
use error::{Error}; //, ExpectError, Result};
|
use error::Error;
|
||||||
use context::HttpContext;
|
use context::HttpContext;
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
use httpresponse::HttpResponse;
|
use httpresponse::HttpResponse;
|
||||||
|
use task::{Task, DrainFut, IoContext};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -28,118 +27,32 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait defines object that could be regestered as resource route
|
/// Trait defines object that could be regestered as route handler
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub trait RouteHandler<S>: 'static {
|
pub trait Handler<S>: 'static {
|
||||||
|
type Result: Into<Reply>;
|
||||||
|
|
||||||
/// Handle request
|
/// Handle request
|
||||||
fn handle(&self, req: HttpRequest<S>, task: &mut Task);
|
fn handle(&self, req: HttpRequest<S>) -> Self::Result;
|
||||||
|
|
||||||
/// Set route prefix
|
/// Set route prefix
|
||||||
fn set_prefix(&mut self, prefix: String) {}
|
fn set_prefix(&mut self, prefix: String) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Handler<S> for Fn()
|
||||||
/// Actors with ability to handle http requests.
|
impl<F, R, S> Handler<S> for F
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub trait RouteState {
|
|
||||||
/// Shared state. State is shared with all routes within same application
|
|
||||||
/// and could be accessed with `HttpRequest::state()` method.
|
|
||||||
type State;
|
|
||||||
|
|
||||||
/// Handle `EXPECT` header. By default respones with `HTTP/1.1 100 Continue`
|
|
||||||
fn expect(req: &mut HttpRequest<Self::State>, ctx: &mut Self::Context) -> Result<()>
|
|
||||||
where Self: Actor<Context=HttpContext<Self>>
|
|
||||||
{
|
|
||||||
// handle expect header only for HTTP/1.1
|
|
||||||
if req.version() == Version::HTTP_11 {
|
|
||||||
if let Some(expect) = req.headers().get(header::EXPECT) {
|
|
||||||
if let Ok(expect) = expect.to_str() {
|
|
||||||
if expect.to_lowercase() == "100-continue" {
|
|
||||||
ctx.write("HTTP/1.1 100 Continue\r\n\r\n");
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ExpectError::UnknownExpect.into())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(ExpectError::Encoding.into())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle incoming request with http actor.
|
|
||||||
fn handle(req: HttpRequest<Self::State>) -> Result<Reply>
|
|
||||||
where Self: Default, Self: Actor<Context=HttpContext<Self>>
|
|
||||||
{
|
|
||||||
Ok(HttpContext::new(req, Self::default()).into())
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/// Fn() route handler
|
|
||||||
pub(crate)
|
|
||||||
struct FnHandler<S, R, F>
|
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Into<Reply>,
|
R: Into<Reply> + 'static
|
||||||
S: 'static,
|
|
||||||
{
|
{
|
||||||
f: Box<F>,
|
type Result = R;
|
||||||
s: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, R, F> FnHandler<S, R, F>
|
fn handle(&self, req: HttpRequest<S>) -> R {
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
(self)(req)
|
||||||
R: Into<Reply> + 'static,
|
|
||||||
S: 'static,
|
|
||||||
{
|
|
||||||
pub fn new(f: F) -> Self {
|
|
||||||
FnHandler{f: Box::new(f), s: PhantomData}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, R, F> RouteHandler<S> for FnHandler<S, R, F>
|
/// Represents response process.
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
pub struct Reply(ReplyItem);
|
||||||
R: Into<Reply> + 'static,
|
|
||||||
S: 'static,
|
|
||||||
{
|
|
||||||
fn handle(&self, req: HttpRequest<S>, task: &mut Task) {
|
|
||||||
(self.f)(req).into().into(task)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Async route handler
|
|
||||||
pub(crate)
|
|
||||||
struct StreamHandler<S, R, F>
|
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
|
||||||
R: Stream<Item=Frame, Error=Error> + 'static,
|
|
||||||
S: 'static,
|
|
||||||
{
|
|
||||||
f: Box<F>,
|
|
||||||
s: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, R, F> StreamHandler<S, R, F>
|
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
|
||||||
R: Stream<Item=Frame, Error=Error> + 'static,
|
|
||||||
S: 'static,
|
|
||||||
{
|
|
||||||
pub fn new(f: F) -> Self {
|
|
||||||
StreamHandler{f: Box::new(f), s: PhantomData}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, R, F> RouteHandler<S> for StreamHandler<S, R, F>
|
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
|
||||||
R: Stream<Item=Frame, Error=Error> + 'static,
|
|
||||||
S: 'static,
|
|
||||||
{
|
|
||||||
fn handle(&self, req: HttpRequest<S>, task: &mut Task) {
|
|
||||||
task.stream((self.f)(req))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ReplyItem {
|
enum ReplyItem {
|
||||||
Message(HttpResponse),
|
Message(HttpResponse),
|
||||||
@ -147,11 +60,8 @@ enum ReplyItem {
|
|||||||
Stream(Box<Stream<Item=Frame, Error=Error>>),
|
Stream(Box<Stream<Item=Frame, Error=Error>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents response process.
|
impl Reply {
|
||||||
pub struct Reply(ReplyItem);
|
|
||||||
|
|
||||||
impl Reply
|
|
||||||
{
|
|
||||||
/// Create actor response
|
/// Create actor response
|
||||||
pub fn actor<A, S>(ctx: HttpContext<A, S>) -> Reply
|
pub fn actor<A, S>(ctx: HttpContext<A, S>) -> Reply
|
||||||
where A: Actor<Context=HttpContext<A, S>>, S: 'static
|
where A: Actor<Context=HttpContext<A, S>>, S: 'static
|
||||||
@ -209,3 +119,78 @@ impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> From<HttpContext<A, S>> fo
|
|||||||
Reply(ReplyItem::Actor(Box::new(item)))
|
Reply(ReplyItem::Actor(Box::new(item)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait defines object that could be regestered as resource route
|
||||||
|
pub(crate) trait RouteHandler<S>: 'static {
|
||||||
|
/// Handle request
|
||||||
|
fn handle(&self, req: HttpRequest<S>, task: &mut Task);
|
||||||
|
|
||||||
|
/// Set route prefix
|
||||||
|
fn set_prefix(&mut self, _prefix: String) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Route handler wrapper for Handler
|
||||||
|
pub(crate)
|
||||||
|
struct WrapHandler<S, H, R>
|
||||||
|
where H: Handler<S, Result=R>,
|
||||||
|
R: Into<Reply>,
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
|
h: H,
|
||||||
|
s: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, H, R> WrapHandler<S, H, R>
|
||||||
|
where H: Handler<S, Result=R>,
|
||||||
|
R: Into<Reply>,
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
|
pub fn new(h: H) -> Self {
|
||||||
|
WrapHandler{h: h, s: PhantomData}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, H, R> RouteHandler<S> for WrapHandler<S, H, R>
|
||||||
|
where H: Handler<S, Result=R>,
|
||||||
|
R: Into<Reply> + 'static,
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
|
fn handle(&self, req: HttpRequest<S>, task: &mut Task) {
|
||||||
|
self.h.handle(req).into().into(task)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_prefix(&mut self, prefix: String) {
|
||||||
|
self.h.set_prefix(prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Async route handler
|
||||||
|
pub(crate)
|
||||||
|
struct StreamHandler<S, R, F>
|
||||||
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
|
R: Stream<Item=Frame, Error=Error> + 'static,
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
|
f: Box<F>,
|
||||||
|
s: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, R, F> StreamHandler<S, R, F>
|
||||||
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
|
R: Stream<Item=Frame, Error=Error> + 'static,
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
|
pub fn new(f: F) -> Self {
|
||||||
|
StreamHandler{f: Box::new(f), s: PhantomData}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, R, F> RouteHandler<S> for StreamHandler<S, R, F>
|
||||||
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
|
R: Stream<Item=Frame, Error=Error> + 'static,
|
||||||
|
S: 'static,
|
||||||
|
{
|
||||||
|
fn handle(&self, req: HttpRequest<S>, task: &mut Task) {
|
||||||
|
task.stream((self.f)(req))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,9 +7,8 @@ use std::fmt::Write;
|
|||||||
use std::fs::{File, DirEntry};
|
use std::fs::{File, DirEntry};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use task::Task;
|
|
||||||
use route::RouteHandler;
|
|
||||||
use mime_guess::get_mime_type;
|
use mime_guess::get_mime_type;
|
||||||
|
use route::Handler;
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
use httpresponse::HttpResponse;
|
use httpresponse::HttpResponse;
|
||||||
use httpcodes::{HTTPOk, HTTPNotFound, HTTPForbidden};
|
use httpcodes::{HTTPOk, HTTPNotFound, HTTPForbidden};
|
||||||
@ -24,7 +23,7 @@ use httpcodes::{HTTPOk, HTTPNotFound, HTTPForbidden};
|
|||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let app = Application::default("/")
|
/// let app = Application::default("/")
|
||||||
/// .route_handler("/static", StaticFiles::new(".", true))
|
/// .handler("/static", StaticFiles::new(".", true))
|
||||||
/// .finish();
|
/// .finish();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
@ -128,7 +127,8 @@ impl StaticFiles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static> RouteHandler<S> for StaticFiles {
|
impl<S> Handler<S> for StaticFiles {
|
||||||
|
type Result = Result<HttpResponse, io::Error>;
|
||||||
|
|
||||||
fn set_prefix(&mut self, prefix: String) {
|
fn set_prefix(&mut self, prefix: String) {
|
||||||
if prefix != "/" {
|
if prefix != "/" {
|
||||||
@ -136,9 +136,9 @@ impl<S: 'static> RouteHandler<S> for StaticFiles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle(&self, req: HttpRequest<S>, task: &mut Task) {
|
fn handle(&self, req: HttpRequest<S>) -> Self::Result {
|
||||||
if !self.accessible {
|
if !self.accessible {
|
||||||
task.reply(HTTPNotFound)
|
Ok(HTTPNotFound.into())
|
||||||
} else {
|
} else {
|
||||||
let mut hidden = false;
|
let mut hidden = false;
|
||||||
let filepath = req.path()[self.prefix.len()..]
|
let filepath = req.path()[self.prefix.len()..]
|
||||||
@ -152,7 +152,7 @@ impl<S: 'static> RouteHandler<S> for StaticFiles {
|
|||||||
|
|
||||||
// hidden file
|
// hidden file
|
||||||
if hidden {
|
if hidden {
|
||||||
task.reply(HTTPNotFound)
|
return Ok(HTTPNotFound.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// full filepath
|
// full filepath
|
||||||
@ -160,19 +160,19 @@ impl<S: 'static> RouteHandler<S> for StaticFiles {
|
|||||||
let filename = match self.directory.join(&filepath[idx..]).canonicalize() {
|
let filename = match self.directory.join(&filepath[idx..]).canonicalize() {
|
||||||
Ok(fname) => fname,
|
Ok(fname) => fname,
|
||||||
Err(err) => return match err.kind() {
|
Err(err) => return match err.kind() {
|
||||||
io::ErrorKind::NotFound => task.reply(HTTPNotFound),
|
io::ErrorKind::NotFound => Ok(HTTPNotFound.into()),
|
||||||
io::ErrorKind::PermissionDenied => task.reply(HTTPForbidden),
|
io::ErrorKind::PermissionDenied => Ok(HTTPForbidden.into()),
|
||||||
_ => task.error(err),
|
_ => Err(err),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if filename.is_dir() {
|
if filename.is_dir() {
|
||||||
match self.index(&filepath[idx..], &filename) {
|
match self.index(&filepath[idx..], &filename) {
|
||||||
Ok(resp) => task.reply(resp),
|
Ok(resp) => Ok(resp),
|
||||||
Err(err) => match err.kind() {
|
Err(err) => match err.kind() {
|
||||||
io::ErrorKind::NotFound => task.reply(HTTPNotFound),
|
io::ErrorKind::NotFound => Ok(HTTPNotFound.into()),
|
||||||
io::ErrorKind::PermissionDenied => task.reply(HTTPForbidden),
|
io::ErrorKind::PermissionDenied => Ok(HTTPForbidden.into()),
|
||||||
_ => task.error(err),
|
_ => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -185,9 +185,9 @@ impl<S: 'static> RouteHandler<S> for StaticFiles {
|
|||||||
Ok(mut file) => {
|
Ok(mut file) => {
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
let _ = file.read_to_end(&mut data);
|
let _ = file.read_to_end(&mut data);
|
||||||
task.reply(resp.body(data).unwrap())
|
Ok(resp.body(data).unwrap())
|
||||||
},
|
},
|
||||||
Err(err) => task.error(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user