1 use std::future::Future;
2 use std::marker::PhantomData;
3 use std::pin::Pin;
4 use std::task::{Context, Poll};
5 
6 use actix_service::{Service, ServiceFactory};
7 use actix_utils::future::{ready, Ready};
8 use futures_core::ready;
9 use pin_project::pin_project;
10 
11 use crate::{
12     service::{ServiceRequest, ServiceResponse},
13     Error, FromRequest, HttpRequest, HttpResponse, Responder,
14 };
15 
16 /// A request handler is an async function that accepts zero or more parameters that can be
17 /// extracted from a request (i.e., [`impl FromRequest`](crate::FromRequest)) and returns a type
18 /// that can be converted into an [`HttpResponse`] (that is, it impls the [`Responder`] trait).
19 ///
20 /// If you got the error `the trait Handler<_, _, _> is not implemented`, then your function is not
21 /// a valid handler. See [Request Handlers](https://actix.rs/docs/handlers/) for more information.
22 pub trait Handler<T, R>: Clone + 'static
23 where
24     R: Future,
25     R::Output: Responder,
26 {
call(&self, param: T) -> R27     fn call(&self, param: T) -> R;
28 }
29 
30 #[doc(hidden)]
31 /// Extract arguments from request, run factory function and make response.
32 pub struct HandlerService<F, T, R>
33 where
34     F: Handler<T, R>,
35     T: FromRequest,
36     R: Future,
37     R::Output: Responder,
38 {
39     hnd: F,
40     _phantom: PhantomData<(T, R)>,
41 }
42 
43 impl<F, T, R> HandlerService<F, T, R>
44 where
45     F: Handler<T, R>,
46     T: FromRequest,
47     R: Future,
48     R::Output: Responder,
49 {
new(hnd: F) -> Self50     pub fn new(hnd: F) -> Self {
51         Self {
52             hnd,
53             _phantom: PhantomData,
54         }
55     }
56 }
57 
58 impl<F, T, R> Clone for HandlerService<F, T, R>
59 where
60     F: Handler<T, R>,
61     T: FromRequest,
62     R: Future,
63     R::Output: Responder,
64 {
clone(&self) -> Self65     fn clone(&self) -> Self {
66         Self {
67             hnd: self.hnd.clone(),
68             _phantom: PhantomData,
69         }
70     }
71 }
72 
73 impl<F, T, R> ServiceFactory<ServiceRequest> for HandlerService<F, T, R>
74 where
75     F: Handler<T, R>,
76     T: FromRequest,
77     R: Future,
78     R::Output: Responder,
79 {
80     type Response = ServiceResponse;
81     type Error = Error;
82     type Config = ();
83     type Service = Self;
84     type InitError = ();
85     type Future = Ready<Result<Self::Service, ()>>;
86 
new_service(&self, _: ()) -> Self::Future87     fn new_service(&self, _: ()) -> Self::Future {
88         ready(Ok(self.clone()))
89     }
90 }
91 
92 /// HandlerService is both it's ServiceFactory and Service Type.
93 impl<F, T, R> Service<ServiceRequest> for HandlerService<F, T, R>
94 where
95     F: Handler<T, R>,
96     T: FromRequest,
97     R: Future,
98     R::Output: Responder,
99 {
100     type Response = ServiceResponse;
101     type Error = Error;
102     type Future = HandlerServiceFuture<F, T, R>;
103 
104     actix_service::always_ready!();
105 
call(&self, req: ServiceRequest) -> Self::Future106     fn call(&self, req: ServiceRequest) -> Self::Future {
107         let (req, mut payload) = req.into_parts();
108         let fut = T::from_request(&req, &mut payload);
109         HandlerServiceFuture::Extract(fut, Some(req), self.hnd.clone())
110     }
111 }
112 
113 #[doc(hidden)]
114 #[pin_project(project = HandlerProj)]
115 pub enum HandlerServiceFuture<F, T, R>
116 where
117     F: Handler<T, R>,
118     T: FromRequest,
119     R: Future,
120     R::Output: Responder,
121 {
122     Extract(#[pin] T::Future, Option<HttpRequest>, F),
123     Handle(#[pin] R, Option<HttpRequest>),
124 }
125 
126 impl<F, T, R> Future for HandlerServiceFuture<F, T, R>
127 where
128     F: Handler<T, R>,
129     T: FromRequest,
130     R: Future,
131     R::Output: Responder,
132 {
133     // Error type in this future is a placeholder type.
134     // all instances of error must be converted to ServiceResponse and return in Ok.
135     type Output = Result<ServiceResponse, Error>;
136 
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>137     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
138         loop {
139             match self.as_mut().project() {
140                 HandlerProj::Extract(fut, req, handle) => {
141                     match ready!(fut.poll(cx)) {
142                         Ok(item) => {
143                             let fut = handle.call(item);
144                             let state = HandlerServiceFuture::Handle(fut, req.take());
145                             self.as_mut().set(state);
146                         }
147                         Err(err) => {
148                             let req = req.take().unwrap();
149                             let res = HttpResponse::from_error(err.into());
150                             return Poll::Ready(Ok(ServiceResponse::new(req, res)));
151                         }
152                     };
153                 }
154                 HandlerProj::Handle(fut, req) => {
155                     let res = ready!(fut.poll(cx));
156                     let req = req.take().unwrap();
157                     let res = res.respond_to(&req);
158                     return Poll::Ready(Ok(ServiceResponse::new(req, res)));
159                 }
160             }
161         }
162     }
163 }
164 
165 /// FromRequest trait impl for tuples
166 macro_rules! factory_tuple ({ $($param:ident)* } => {
167     impl<Func, $($param,)* Res> Handler<($($param,)*), Res> for Func
168     where Func: Fn($($param),*) -> Res + Clone + 'static,
169           Res: Future,
170           Res::Output: Responder,
171     {
172         #[allow(non_snake_case)]
173         fn call(&self, ($($param,)*): ($($param,)*)) -> Res {
174             (self)($($param,)*)
175         }
176     }
177 });
178 
179 factory_tuple! {}
180 factory_tuple! { A }
181 factory_tuple! { A B }
182 factory_tuple! { A B C }
183 factory_tuple! { A B C D }
184 factory_tuple! { A B C D E }
185 factory_tuple! { A B C D E F }
186 factory_tuple! { A B C D E F G }
187 factory_tuple! { A B C D E F G H }
188 factory_tuple! { A B C D E F G H I }
189 factory_tuple! { A B C D E F G H I J }
190 factory_tuple! { A B C D E F G H I J K }
191 factory_tuple! { A B C D E F G H I J K L }
192