1 | use std::error::Error as StdError; |
2 | use std::fmt; |
3 | |
4 | use tokio::io::{AsyncRead, AsyncWrite}; |
5 | |
6 | use super::{HttpService, Service}; |
7 | use crate::body::HttpBody; |
8 | use crate::common::{task, Future, Poll}; |
9 | |
10 | // The same "trait alias" as tower::MakeConnection, but inlined to reduce |
11 | // dependencies. |
12 | pub trait MakeConnection<Target>: self::sealed::Sealed<(Target,)> { |
13 | type Connection: AsyncRead + AsyncWrite; |
14 | type Error; |
15 | type Future: Future<Output = Result<Self::Connection, Self::Error>>; |
16 | |
17 | fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>; |
18 | fn make_connection(&mut self, target: Target) -> Self::Future; |
19 | } |
20 | |
21 | impl<S, Target> self::sealed::Sealed<(Target,)> for S where S: Service<Target> {} |
22 | |
23 | impl<S, Target> MakeConnection<Target> for S |
24 | where |
25 | S: Service<Target>, |
26 | S::Response: AsyncRead + AsyncWrite, |
27 | { |
28 | type Connection = S::Response; |
29 | type Error = S::Error; |
30 | type Future = S::Future; |
31 | |
32 | fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> { |
33 | Service::poll_ready(self, cx) |
34 | } |
35 | |
36 | fn make_connection(&mut self, target: Target) -> Self::Future { |
37 | Service::call(self, req:target) |
38 | } |
39 | } |
40 | |
41 | // Just a sort-of "trait alias" of `MakeService`, not to be implemented |
42 | // by anyone, only used as bounds. |
43 | pub trait MakeServiceRef<Target, ReqBody>: self::sealed::Sealed<(Target, ReqBody)> { |
44 | type ResBody: HttpBody; |
45 | type Error: Into<Box<dyn StdError + Send + Sync>>; |
46 | type Service: HttpService<ReqBody, ResBody = Self::ResBody, Error = Self::Error>; |
47 | type MakeError: Into<Box<dyn StdError + Send + Sync>>; |
48 | type Future: Future<Output = Result<Self::Service, Self::MakeError>>; |
49 | |
50 | // Acting like a #[non_exhaustive] for associated types of this trait. |
51 | // |
52 | // Basically, no one outside of hyper should be able to set this type |
53 | // or declare bounds on it, so it should prevent people from creating |
54 | // trait objects or otherwise writing code that requires using *all* |
55 | // of the associated types. |
56 | // |
57 | // Why? So we can add new associated types to this alias in the future, |
58 | // if necessary. |
59 | type __DontNameMe: self::sealed::CantImpl; |
60 | |
61 | fn poll_ready_ref(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>>; |
62 | |
63 | fn make_service_ref(&mut self, target: &Target) -> Self::Future; |
64 | } |
65 | |
66 | impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target, IB> for T |
67 | where |
68 | T: for<'a> Service<&'a Target, Error = ME, Response = S, Future = F>, |
69 | E: Into<Box<dyn StdError + Send + Sync>>, |
70 | ME: Into<Box<dyn StdError + Send + Sync>>, |
71 | S: HttpService<IB, ResBody = OB, Error = E>, |
72 | F: Future<Output = Result<S, ME>>, |
73 | IB: HttpBody, |
74 | OB: HttpBody, |
75 | { |
76 | type Error = E; |
77 | type Service = S; |
78 | type ResBody = OB; |
79 | type MakeError = ME; |
80 | type Future = F; |
81 | |
82 | type __DontNameMe = self::sealed::CantName; |
83 | |
84 | fn poll_ready_ref(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>> { |
85 | self.poll_ready(cx) |
86 | } |
87 | |
88 | fn make_service_ref(&mut self, target: &Target) -> Self::Future { |
89 | self.call(req:target) |
90 | } |
91 | } |
92 | |
93 | impl<T, Target, S, B1, B2> self::sealed::Sealed<(Target, B1)> for T |
94 | where |
95 | T: for<'a> Service<&'a Target, Response = S>, |
96 | S: HttpService<B1, ResBody = B2>, |
97 | B1: HttpBody, |
98 | B2: HttpBody, |
99 | { |
100 | } |
101 | |
102 | /// Create a `MakeService` from a function. |
103 | /// |
104 | /// # Example |
105 | /// |
106 | /// ``` |
107 | /// # #[cfg (feature = "runtime" )] |
108 | /// # async fn run() { |
109 | /// use std::convert::Infallible; |
110 | /// use hyper::{Body, Request, Response, Server}; |
111 | /// use hyper::server::conn::AddrStream; |
112 | /// use hyper::service::{make_service_fn, service_fn}; |
113 | /// |
114 | /// let addr = ([127, 0, 0, 1], 3000).into(); |
115 | /// |
116 | /// let make_svc = make_service_fn(|socket: &AddrStream| { |
117 | /// let remote_addr = socket.remote_addr(); |
118 | /// async move { |
119 | /// Ok::<_, Infallible>(service_fn(move |_: Request<Body>| async move { |
120 | /// Ok::<_, Infallible>( |
121 | /// Response::new(Body::from(format!("Hello, {}!" , remote_addr))) |
122 | /// ) |
123 | /// })) |
124 | /// } |
125 | /// }); |
126 | /// |
127 | /// // Then bind and serve... |
128 | /// let server = Server::bind(&addr) |
129 | /// .serve(make_svc); |
130 | /// |
131 | /// // Finally, spawn `server` onto an Executor... |
132 | /// if let Err(e) = server.await { |
133 | /// eprintln!("server error: {}" , e); |
134 | /// } |
135 | /// # } |
136 | /// # fn main() {} |
137 | /// ``` |
138 | pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F> |
139 | where |
140 | F: FnMut(&Target) -> Ret, |
141 | Ret: Future, |
142 | { |
143 | MakeServiceFn { f } |
144 | } |
145 | |
146 | /// `MakeService` returned from [`make_service_fn`] |
147 | #[derive (Clone, Copy)] |
148 | pub struct MakeServiceFn<F> { |
149 | f: F, |
150 | } |
151 | |
152 | impl<'t, F, Ret, Target, Svc, MkErr> Service<&'t Target> for MakeServiceFn<F> |
153 | where |
154 | F: FnMut(&Target) -> Ret, |
155 | Ret: Future<Output = Result<Svc, MkErr>>, |
156 | MkErr: Into<Box<dyn StdError + Send + Sync>>, |
157 | { |
158 | type Error = MkErr; |
159 | type Response = Svc; |
160 | type Future = Ret; |
161 | |
162 | fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> { |
163 | Poll::Ready(Ok(())) |
164 | } |
165 | |
166 | fn call(&mut self, target: &'t Target) -> Self::Future { |
167 | (self.f)(target) |
168 | } |
169 | } |
170 | |
171 | impl<F> fmt::Debug for MakeServiceFn<F> { |
172 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
173 | f.debug_struct(name:"MakeServiceFn" ).finish() |
174 | } |
175 | } |
176 | |
177 | mod sealed { |
178 | pub trait Sealed<X> {} |
179 | |
180 | #[allow (unreachable_pub)] // This is intentional. |
181 | pub trait CantImpl {} |
182 | |
183 | #[allow (missing_debug_implementations)] |
184 | pub enum CantName {} |
185 | |
186 | impl CantImpl for CantName {} |
187 | } |
188 | |