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