1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-01-13 04:05:25 +01:00
actix-web/src/handler.rs

292 lines
7.2 KiB
Rust
Raw Normal View History

2019-05-12 08:34:51 -07:00
use std::convert::Infallible;
2019-11-20 23:33:22 +06:00
use std::future::Future;
2018-04-13 16:02:01 -07:00
use std::marker::PhantomData;
2019-11-20 23:33:22 +06:00
use std::pin::Pin;
use std::task::{Context, Poll};
2017-10-06 21:48:14 -07:00
2019-05-22 11:49:27 -07:00
use actix_http::{Error, Response};
2019-11-20 23:33:22 +06:00
use actix_service::{Service, ServiceFactory};
use futures::future::{ok, Ready};
use futures::ready;
use pin_project::pin_project;
2018-05-01 17:30:06 -07:00
use crate::extract::FromRequest;
2019-03-01 22:51:32 -08:00
use crate::request::HttpRequest;
use crate::responder::Responder;
2019-04-07 14:43:07 -07:00
use crate::service::{ServiceRequest, ServiceResponse};
2017-11-03 13:35:34 -07:00
2019-03-01 22:51:32 -08:00
/// Async handler converter factory
2019-11-21 21:34:04 +06:00
pub trait Factory<T, R, O>: Clone + 'static
2019-03-01 22:51:32 -08:00
where
R: Future<Output = O>,
2019-11-20 23:33:22 +06:00
O: Responder,
2019-03-01 22:51:32 -08:00
{
fn call(&self, param: T) -> R;
}
2018-05-01 17:19:15 -07:00
2019-11-21 21:34:04 +06:00
impl<F, R, O> Factory<(), R, O> for F
2019-03-01 22:51:32 -08:00
where
F: Fn() -> R + Clone + 'static,
R: Future<Output = O>,
2019-11-20 23:33:22 +06:00
O: Responder,
2019-03-01 22:51:32 -08:00
{
fn call(&self, _: ()) -> R {
(self)()
2017-11-28 19:49:17 -08:00
}
2019-03-01 22:51:32 -08:00
}
2017-12-09 13:25:06 -08:00
2019-03-01 22:51:32 -08:00
#[doc(hidden)]
2019-11-21 21:34:04 +06:00
pub struct Handler<F, T, R, O>
2019-03-01 22:51:32 -08:00
where
2019-11-21 21:34:04 +06:00
F: Factory<T, R, O>,
R: Future<Output = O>,
2019-11-20 23:33:22 +06:00
O: Responder,
2019-03-01 22:51:32 -08:00
{
hnd: F,
_t: PhantomData<(T, R, O)>,
2019-03-01 22:51:32 -08:00
}
2018-05-01 17:19:15 -07:00
2019-11-21 21:34:04 +06:00
impl<F, T, R, O> Handler<F, T, R, O>
2019-03-01 22:51:32 -08:00
where
2019-11-21 21:34:04 +06:00
F: Factory<T, R, O>,
R: Future<Output = O>,
2019-11-20 23:33:22 +06:00
O: Responder,
2019-03-01 22:51:32 -08:00
{
pub fn new(hnd: F) -> Self {
2019-11-21 21:34:04 +06:00
Handler {
2019-03-01 22:51:32 -08:00
hnd,
_t: PhantomData,
2017-12-09 13:25:06 -08:00
}
}
2017-11-28 19:49:17 -08:00
}
2019-11-21 21:34:04 +06:00
impl<F, T, R, O> Clone for Handler<F, T, R, O>
2019-03-01 22:51:32 -08:00
where
2019-11-21 21:34:04 +06:00
F: Factory<T, R, O>,
R: Future<Output = O>,
2019-11-20 23:33:22 +06:00
O: Responder,
2019-03-01 22:51:32 -08:00
{
fn clone(&self) -> Self {
2019-11-21 21:34:04 +06:00
Handler {
2019-03-01 22:51:32 -08:00
hnd: self.hnd.clone(),
_t: PhantomData,
}
}
}
2019-11-21 21:34:04 +06:00
impl<F, T, R, O> Service for Handler<F, T, R, O>
2019-03-01 22:51:32 -08:00
where
2019-11-21 21:34:04 +06:00
F: Factory<T, R, O>,
R: Future<Output = O>,
2019-11-20 23:33:22 +06:00
O: Responder,
2019-03-01 22:51:32 -08:00
{
type Request = (T, HttpRequest);
2019-03-01 22:51:32 -08:00
type Response = ServiceResponse;
2019-05-12 08:34:51 -07:00
type Error = Infallible;
2019-11-21 21:34:04 +06:00
type Future = HandlerServiceResponse<R, O>;
2017-12-01 21:29:22 -08:00
2019-11-20 23:33:22 +06:00
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
2019-03-01 22:51:32 -08:00
fn call(&mut self, (param, req): (T, HttpRequest)) -> Self::Future {
2019-11-21 21:34:04 +06:00
HandlerServiceResponse {
2019-11-20 23:33:22 +06:00
fut: self.hnd.call(param),
fut2: None,
2019-03-01 22:51:32 -08:00
req: Some(req),
}
}
}
2019-03-01 22:51:32 -08:00
#[doc(hidden)]
2019-11-20 23:33:22 +06:00
#[pin_project]
2019-11-21 21:34:04 +06:00
pub struct HandlerServiceResponse<T, R>
where
T: Future<Output = R>,
2019-11-20 23:33:22 +06:00
R: Responder,
{
2019-11-20 23:33:22 +06:00
#[pin]
2019-03-01 22:51:32 -08:00
fut: T,
2019-11-20 23:33:22 +06:00
#[pin]
fut2: Option<R::Future>,
2019-03-01 22:51:32 -08:00
req: Option<HttpRequest>,
2018-05-01 17:19:15 -07:00
}
2019-11-21 21:34:04 +06:00
impl<T, R> Future for HandlerServiceResponse<T, R>
2018-08-23 09:48:01 -07:00
where
T: Future<Output = R>,
2019-11-20 23:33:22 +06:00
R: Responder,
2018-05-01 17:19:15 -07:00
{
2019-11-20 23:33:22 +06:00
type Output = Result<ServiceResponse, Infallible>;
2019-03-01 22:51:32 -08:00
2019-11-20 23:33:22 +06:00
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let this = self.as_mut().project();
if let Some(fut) = this.fut2.as_pin_mut() {
return match fut.poll(cx) {
Poll::Ready(Ok(res)) => {
Poll::Ready(Ok(ServiceResponse::new(this.req.take().unwrap(), res)))
}
Poll::Pending => Poll::Pending,
Poll::Ready(Err(e)) => {
let res: Response = e.into().into();
2019-11-20 23:33:22 +06:00
Poll::Ready(Ok(ServiceResponse::new(this.req.take().unwrap(), res)))
}
};
}
2019-11-20 23:33:22 +06:00
match this.fut.poll(cx) {
Poll::Ready(res) => {
2019-11-20 23:33:22 +06:00
let fut = res.respond_to(this.req.as_ref().unwrap());
self.as_mut().project().fut2.set(Some(fut));
self.poll(cx)
}
2019-11-20 23:33:22 +06:00
Poll::Pending => Poll::Pending,
}
}
}
2019-03-01 22:51:32 -08:00
/// Extract arguments from request
pub struct Extract<T: FromRequest, S> {
service: S,
_t: PhantomData<T>,
}
impl<T: FromRequest, S> Extract<T, S> {
pub fn new(service: S) -> Self {
2019-03-03 00:57:48 -08:00
Extract {
service,
2019-03-03 00:57:48 -08:00
_t: PhantomData,
}
}
2019-03-01 22:51:32 -08:00
}
2019-11-20 23:33:22 +06:00
impl<T: FromRequest, S> ServiceFactory for Extract<T, S>
where
2019-05-12 08:34:51 -07:00
S: Service<
Request = (T, HttpRequest),
Response = ServiceResponse,
Error = Infallible,
> + Clone,
{
2019-05-12 08:34:51 -07:00
type Config = ();
type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = (Error, ServiceRequest);
2019-03-01 22:51:32 -08:00
type InitError = ();
type Service = ExtractService<T, S>;
2019-11-20 23:33:22 +06:00
type Future = Ready<Result<Self::Service, ()>>;
2018-07-15 15:12:21 +06:00
2019-03-01 22:51:32 -08:00
fn new_service(&self, _: &()) -> Self::Future {
2019-03-03 00:57:48 -08:00
ok(ExtractService {
_t: PhantomData,
service: self.service.clone(),
2019-03-03 00:57:48 -08:00
})
2019-03-01 22:51:32 -08:00
}
2017-11-29 13:26:55 -08:00
}
pub struct ExtractService<T: FromRequest, S> {
service: S,
_t: PhantomData<T>,
2017-11-29 13:26:55 -08:00
}
impl<T: FromRequest, S> Service for ExtractService<T, S>
where
2019-05-12 08:34:51 -07:00
S: Service<
Request = (T, HttpRequest),
Response = ServiceResponse,
Error = Infallible,
> + Clone,
{
type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = (Error, ServiceRequest);
type Future = ExtractResponse<T, S>;
2019-03-01 22:51:32 -08:00
2019-11-20 23:33:22 +06:00
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
2017-11-29 13:26:55 -08:00
}
fn call(&mut self, req: ServiceRequest) -> Self::Future {
let (req, mut payload) = req.into_parts();
2019-11-20 23:33:22 +06:00
let fut = T::from_request(&req, &mut payload);
2019-04-07 14:43:07 -07:00
2019-03-01 22:51:32 -08:00
ExtractResponse {
2019-04-07 14:43:07 -07:00
fut,
2019-05-22 11:49:27 -07:00
req,
fut_s: None,
service: self.service.clone(),
}
2017-11-29 13:26:55 -08:00
}
}
2019-11-20 23:33:22 +06:00
#[pin_project]
pub struct ExtractResponse<T: FromRequest, S: Service> {
2019-05-22 11:49:27 -07:00
req: HttpRequest,
service: S,
2019-11-20 23:33:22 +06:00
#[pin]
fut: T::Future,
#[pin]
fut_s: Option<S::Future>,
2017-11-29 13:26:55 -08:00
}
impl<T: FromRequest, S> Future for ExtractResponse<T, S>
where
2019-05-12 08:34:51 -07:00
S: Service<
Request = (T, HttpRequest),
Response = ServiceResponse,
Error = Infallible,
>,
{
2019-11-20 23:33:22 +06:00
type Output = Result<ServiceResponse, (Error, ServiceRequest)>;
2017-11-29 13:26:55 -08:00
2019-11-20 23:33:22 +06:00
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let this = self.as_mut().project();
2019-11-20 23:33:22 +06:00
if let Some(fut) = this.fut_s.as_pin_mut() {
return fut.poll(cx).map_err(|_| panic!());
}
2019-03-01 22:51:32 -08:00
2019-11-20 23:33:22 +06:00
match ready!(this.fut.poll(cx)) {
Err(e) => {
let req = ServiceRequest::new(this.req.clone());
Poll::Ready(Err((e.into(), req)))
}
Ok(item) => {
let fut = Some(this.service.call((item, this.req.clone())));
self.as_mut().project().fut_s.set(fut);
self.poll(cx)
}
}
2018-03-29 15:41:13 -07:00
}
}
2019-03-01 22:51:32 -08:00
/// FromRequest trait impl for tuples
macro_rules! factory_tuple ({ $(($n:tt, $T:ident)),+} => {
2019-11-21 21:34:04 +06:00
impl<Func, $($T,)+ Res, O> Factory<($($T,)+), Res, O> for Func
2019-03-01 22:51:32 -08:00
where Func: Fn($($T,)+) -> Res + Clone + 'static,
Res: Future<Output = O>,
2019-11-20 23:33:22 +06:00
O: Responder,
2019-03-01 22:51:32 -08:00
{
fn call(&self, param: ($($T,)+)) -> Res {
(self)($(param.$n,)+)
}
2018-03-29 15:41:13 -07:00
}
2019-03-01 22:51:32 -08:00
});
#[rustfmt::skip]
mod m {
use super::*;
factory_tuple!((0, A));
factory_tuple!((0, A), (1, B));
factory_tuple!((0, A), (1, B), (2, C));
factory_tuple!((0, A), (1, B), (2, C), (3, D));
factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E));
factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
2018-03-29 15:41:13 -07:00
}