1use std::{fmt, marker::PhantomData, net, rc::Rc, time::Duration};
2
3use actix_codec::Framed;
4use actix_service::{IntoServiceFactory, Service, ServiceFactory};
5
6use crate::{
7 body::{BoxBody, MessageBody},
8 h1::{self, ExpectHandler, H1Service, UpgradeHandler},
9 service::HttpService,
10 ConnectCallback, Extensions, KeepAlive, Request, Response, ServiceConfig,
11};
12
13pub struct HttpServiceBuilder<T, S, X = ExpectHandler, U = UpgradeHandler> {
17 keep_alive: KeepAlive,
18 client_request_timeout: Duration,
19 client_disconnect_timeout: Duration,
20 secure: bool,
21 local_addr: Option<net::SocketAddr>,
22 expect: X,
23 upgrade: Option<U>,
24 on_connect_ext: Option<Rc<ConnectCallback<T>>>,
25 _phantom: PhantomData<S>,
26}
27
28impl<T, S> Default for HttpServiceBuilder<T, S, ExpectHandler, UpgradeHandler>
29where
30 S: ServiceFactory<Request, Config = ()>,
31 S::Error: Into<Response<BoxBody>> + 'static,
32 S::InitError: fmt::Debug,
33 <S::Service as Service<Request>>::Future: 'static,
34{
35 fn default() -> Self {
36 HttpServiceBuilder {
37 keep_alive: KeepAlive::default(),
39 client_request_timeout: Duration::from_secs(5),
40 client_disconnect_timeout: Duration::ZERO,
41 secure: false,
42 local_addr: None,
43
44 expect: ExpectHandler,
46 upgrade: None,
47 on_connect_ext: None,
48 _phantom: PhantomData,
49 }
50 }
51}
52
53impl<T, S, X, U> HttpServiceBuilder<T, S, X, U>
54where
55 S: ServiceFactory<Request, Config = ()>,
56 S::Error: Into<Response<BoxBody>> + 'static,
57 S::InitError: fmt::Debug,
58 <S::Service as Service<Request>>::Future: 'static,
59 X: ServiceFactory<Request, Config = (), Response = Request>,
60 X::Error: Into<Response<BoxBody>>,
61 X::InitError: fmt::Debug,
62 U: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), Response = ()>,
63 U::Error: fmt::Display,
64 U::InitError: fmt::Debug,
65{
66 pub fn keep_alive<W: Into<KeepAlive>>(mut self, val: W) -> Self {
72 self.keep_alive = val.into();
73 self
74 }
75
76 pub fn secure(mut self) -> Self {
78 self.secure = true;
79 self
80 }
81
82 pub fn local_addr(mut self, addr: net::SocketAddr) -> Self {
84 self.local_addr = Some(addr);
85 self
86 }
87
88 pub fn client_request_timeout(mut self, dur: Duration) -> Self {
98 self.client_request_timeout = dur;
99 self
100 }
101
102 #[doc(hidden)]
103 #[deprecated(since = "3.0.0", note = "Renamed to `client_request_timeout`.")]
104 pub fn client_timeout(self, dur: Duration) -> Self {
105 self.client_request_timeout(dur)
106 }
107
108 pub fn client_disconnect_timeout(mut self, dur: Duration) -> Self {
117 self.client_disconnect_timeout = dur;
118 self
119 }
120
121 #[doc(hidden)]
122 #[deprecated(since = "3.0.0", note = "Renamed to `client_disconnect_timeout`.")]
123 pub fn client_disconnect(self, dur: Duration) -> Self {
124 self.client_disconnect_timeout(dur)
125 }
126
127 pub fn expect<F, X1>(self, expect: F) -> HttpServiceBuilder<T, S, X1, U>
133 where
134 F: IntoServiceFactory<X1, Request>,
135 X1: ServiceFactory<Request, Config = (), Response = Request>,
136 X1::Error: Into<Response<BoxBody>>,
137 X1::InitError: fmt::Debug,
138 {
139 HttpServiceBuilder {
140 keep_alive: self.keep_alive,
141 client_request_timeout: self.client_request_timeout,
142 client_disconnect_timeout: self.client_disconnect_timeout,
143 secure: self.secure,
144 local_addr: self.local_addr,
145 expect: expect.into_factory(),
146 upgrade: self.upgrade,
147 on_connect_ext: self.on_connect_ext,
148 _phantom: PhantomData,
149 }
150 }
151
152 pub fn upgrade<F, U1>(self, upgrade: F) -> HttpServiceBuilder<T, S, X, U1>
157 where
158 F: IntoServiceFactory<U1, (Request, Framed<T, h1::Codec>)>,
159 U1: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), Response = ()>,
160 U1::Error: fmt::Display,
161 U1::InitError: fmt::Debug,
162 {
163 HttpServiceBuilder {
164 keep_alive: self.keep_alive,
165 client_request_timeout: self.client_request_timeout,
166 client_disconnect_timeout: self.client_disconnect_timeout,
167 secure: self.secure,
168 local_addr: self.local_addr,
169 expect: self.expect,
170 upgrade: Some(upgrade.into_factory()),
171 on_connect_ext: self.on_connect_ext,
172 _phantom: PhantomData,
173 }
174 }
175
176 pub fn on_connect_ext<F>(mut self, f: F) -> Self
182 where
183 F: Fn(&T, &mut Extensions) + 'static,
184 {
185 self.on_connect_ext = Some(Rc::new(f));
186 self
187 }
188
189 pub fn h1<F, B>(self, service: F) -> H1Service<T, S, B, X, U>
191 where
192 B: MessageBody,
193 F: IntoServiceFactory<S, Request>,
194 S::Error: Into<Response<BoxBody>>,
195 S::InitError: fmt::Debug,
196 S::Response: Into<Response<B>>,
197 {
198 let cfg = ServiceConfig::new(
199 self.keep_alive,
200 self.client_request_timeout,
201 self.client_disconnect_timeout,
202 self.secure,
203 self.local_addr,
204 );
205
206 H1Service::with_config(cfg, service.into_factory())
207 .expect(self.expect)
208 .upgrade(self.upgrade)
209 .on_connect_ext(self.on_connect_ext)
210 }
211
212 #[cfg(feature = "http2")]
214 pub fn h2<F, B>(self, service: F) -> crate::h2::H2Service<T, S, B>
215 where
216 F: IntoServiceFactory<S, Request>,
217 S::Error: Into<Response<BoxBody>> + 'static,
218 S::InitError: fmt::Debug,
219 S::Response: Into<Response<B>> + 'static,
220
221 B: MessageBody + 'static,
222 {
223 let cfg = ServiceConfig::new(
224 self.keep_alive,
225 self.client_request_timeout,
226 self.client_disconnect_timeout,
227 self.secure,
228 self.local_addr,
229 );
230
231 crate::h2::H2Service::with_config(cfg, service.into_factory())
232 .on_connect_ext(self.on_connect_ext)
233 }
234
235 pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B, X, U>
237 where
238 F: IntoServiceFactory<S, Request>,
239 S::Error: Into<Response<BoxBody>> + 'static,
240 S::InitError: fmt::Debug,
241 S::Response: Into<Response<B>> + 'static,
242
243 B: MessageBody + 'static,
244 {
245 let cfg = ServiceConfig::new(
246 self.keep_alive,
247 self.client_request_timeout,
248 self.client_disconnect_timeout,
249 self.secure,
250 self.local_addr,
251 );
252
253 HttpService::with_config(cfg, service.into_factory())
254 .expect(self.expect)
255 .upgrade(self.upgrade)
256 .on_connect_ext(self.on_connect_ext)
257 }
258}