Skip to content

Commit 33ce81a

Browse files
committed
add HttpServer::new_async
1 parent a3806cd commit 33ce81a

File tree

1 file changed

+96
-52
lines changed

1 file changed

+96
-52
lines changed

src/server.rs

+96-52
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,29 @@ use std::{
22
any::Any,
33
cmp,
44
error::Error as StdError,
5-
fmt, io,
5+
fmt,
6+
future::Future,
7+
io,
68
marker::PhantomData,
79
net,
810
sync::{Arc, Mutex},
911
};
1012

11-
use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
13+
use actix_http::{
14+
body::AnyBody, body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response,
15+
};
1216
use actix_server::{Server, ServerBuilder};
1317
use actix_service::{
14-
map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
18+
fn_factory_with_config, map_config, IntoServiceFactory, Service, ServiceFactory,
19+
ServiceFactoryExt as _,
1520
};
1621

1722
#[cfg(feature = "openssl")]
1823
use actix_tls::accept::openssl::{AlpnError, SslAcceptor, SslAcceptorBuilder};
1924
#[cfg(feature = "rustls")]
2025
use actix_tls::accept::rustls::ServerConfig as RustlsServerConfig;
2126

22-
use crate::{config::AppConfig, Error};
27+
use crate::{config::AppConfig, Error, HttpResponse};
2328

2429
struct Socket {
2530
scheme: &'static str,
@@ -50,17 +55,8 @@ struct Config {
5055
/// .await
5156
/// }
5257
/// ```
53-
pub struct HttpServer<F, I, S, B>
54-
where
55-
F: Fn() -> I + Send + Clone + 'static,
56-
I: IntoServiceFactory<S, Request>,
57-
S: ServiceFactory<Request, Config = AppConfig>,
58-
S::Error: Into<Error>,
59-
S::InitError: fmt::Debug,
60-
S::Response: Into<Response<B>>,
61-
B: MessageBody,
62-
{
63-
pub(super) factory: F,
58+
pub struct HttpServer<S = (), B = ()> {
59+
pub(super) factory: S,
6460
config: Arc<Mutex<Config>>,
6561
backlog: u32,
6662
sockets: Vec<Socket>,
@@ -69,14 +65,85 @@ where
6965
_phantom: PhantomData<(S, B)>,
7066
}
7167

72-
impl<F, I, S, B> HttpServer<F, I, S, B>
73-
where
74-
F: Fn() -> I + Send + Clone + 'static,
75-
I: IntoServiceFactory<S, Request>,
68+
impl HttpServer {
69+
/// Create new HTTP server with application factory
70+
pub fn new<F, I, SF, B>(
71+
factory_fn: F,
72+
) -> HttpServer<
73+
impl ServiceFactory<
74+
Request,
75+
Config = AppConfig,
76+
Error = HttpResponse,
77+
InitError = SF::InitError,
78+
Response = SF::Response,
79+
> + Send
80+
+ Clone,
81+
B,
82+
>
83+
where
84+
F: FnOnce() -> I + Send + Clone + 'static,
85+
I: IntoServiceFactory<SF, Request>,
86+
SF: ServiceFactory<Request, Config = AppConfig>,
87+
SF::Error: Into<Error> + 'static,
88+
SF::InitError: fmt::Debug + 'static,
89+
SF::Response: Into<Response<B>> + 'static,
90+
<SF::Service as Service<Request>>::Future: 'static,
91+
SF::Service: 'static,
92+
// S::Service: 'static,
93+
B: MessageBody + 'static,
94+
B::Error: Into<Box<dyn StdError>>,
95+
{
96+
let factory = fn_factory_with_config(move |cfg| {
97+
let factory_fn = factory_fn.clone();
98+
async move { factory_fn().into_factory().new_service(cfg).await }
99+
})
100+
.map_err(|err| err.into().error_response());
101+
102+
HttpServer::new2(factory)
103+
}
76104

77-
S: ServiceFactory<Request, Config = AppConfig> + 'static,
105+
pub fn new_async<F, Fut, SF, B>(
106+
factory_fn: F,
107+
) -> HttpServer<
108+
impl ServiceFactory<
109+
Request,
110+
Config = AppConfig,
111+
Error = HttpResponse,
112+
InitError = SF::InitError,
113+
Response = SF::Response,
114+
> + Send
115+
+ Clone,
116+
B,
117+
>
118+
where
119+
F: FnOnce() -> Fut + Send + Clone + 'static,
120+
Fut: Future,
121+
Fut::Output: IntoServiceFactory<SF, Request>,
122+
SF: ServiceFactory<Request, Config = AppConfig>,
123+
SF::Error: Into<Error> + 'static,
124+
SF::InitError: fmt::Debug + 'static,
125+
SF::Response: Into<Response<B>> + 'static,
126+
<SF::Service as Service<Request>>::Future: 'static,
127+
SF::Service: 'static,
128+
// S::Service: 'static,
129+
B: MessageBody + 'static,
130+
B::Error: Into<Box<dyn StdError>>,
131+
{
132+
let factory = fn_factory_with_config(move |cfg| {
133+
let factory_fn = factory_fn.clone();
134+
async move { factory_fn().await.into_factory().new_service(cfg).await }
135+
})
136+
.map_err(|err| err.into().error_response());
137+
138+
HttpServer::new2(factory)
139+
}
140+
}
141+
142+
impl<S, B> HttpServer<S, B>
143+
where
144+
S: ServiceFactory<Request, Config = AppConfig> + Send + Clone + 'static,
78145
// S::Future: 'static,
79-
S::Error: Into<Error> + 'static,
146+
S::Error: Into<Response<AnyBody>> + 'static,
80147
S::InitError: fmt::Debug,
81148
S::Response: Into<Response<B>> + 'static,
82149
<S::Service as Service<Request>>::Future: 'static,
@@ -85,8 +152,7 @@ where
85152
B: MessageBody + 'static,
86153
B::Error: Into<Box<dyn StdError>>,
87154
{
88-
/// Create new HTTP server with application factory
89-
pub fn new(factory: F) -> Self {
155+
fn new2(factory: S) -> Self {
90156
HttpServer {
91157
factory,
92158
config: Arc::new(Mutex::new(Config {
@@ -113,7 +179,7 @@ where
113179
/// - `actix_web::rt::net::TcpStream` when no encryption is used.
114180
///
115181
/// See `on_connect` example for additional details.
116-
pub fn on_connect<CB>(self, f: CB) -> HttpServer<F, I, S, B>
182+
pub fn on_connect<CB>(self, f: CB) -> Self
117183
where
118184
CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,
119185
{
@@ -304,11 +370,7 @@ where
304370
})
305371
};
306372

307-
let fac = factory()
308-
.into_factory()
309-
.map_err(|err| err.into().error_response());
310-
311-
svc.finish(map_config(fac, move |_| {
373+
svc.finish(map_config(factory.clone(), move |_| {
312374
AppConfig::new(false, host.clone(), addr)
313375
}))
314376
.tcp()
@@ -364,11 +426,7 @@ where
364426
svc
365427
};
366428

367-
let fac = factory()
368-
.into_factory()
369-
.map_err(|err| err.into().error_response());
370-
371-
svc.finish(map_config(fac, move |_| {
429+
svc.finish(map_config(factory.clone(), move |_| {
372430
AppConfig::new(true, host.clone(), addr)
373431
}))
374432
.openssl(acceptor.clone())
@@ -422,11 +480,7 @@ where
422480
svc
423481
};
424482

425-
let fac = factory()
426-
.into_factory()
427-
.map_err(|err| err.into().error_response());
428-
429-
svc.finish(map_config(fac, move |_| {
483+
svc.finish(map_config(factory.clone(), move |_| {
430484
AppConfig::new(true, host.clone(), addr)
431485
}))
432486
.rustls(config.clone())
@@ -548,11 +602,7 @@ where
548602
.on_connect_ext(move |io: &_, ext: _| (&*handler)(io as &dyn Any, ext));
549603
}
550604

551-
let fac = factory()
552-
.into_factory()
553-
.map_err(|err| err.into().error_response());
554-
555-
svc.finish(map_config(fac, move |_| config.clone()))
605+
svc.finish(map_config(factory.clone(), move |_| config.clone()))
556606
})
557607
})?;
558608
Ok(self)
@@ -589,16 +639,12 @@ where
589639
socket_addr,
590640
);
591641

592-
let fac = factory()
593-
.into_factory()
594-
.map_err(|err| err.into().error_response());
595-
596642
fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then(
597643
HttpService::build()
598644
.keep_alive(c.keep_alive)
599645
.client_timeout(c.client_timeout)
600646
.client_disconnect(c.client_shutdown)
601-
.finish(map_config(fac, move |_| config.clone())),
647+
.finish(map_config(factory.clone(), move |_| config.clone())),
602648
)
603649
},
604650
)?;
@@ -607,10 +653,8 @@ where
607653
}
608654
}
609655

610-
impl<F, I, S, B> HttpServer<F, I, S, B>
656+
impl<S, B> HttpServer<S, B>
611657
where
612-
F: Fn() -> I + Send + Clone + 'static,
613-
I: IntoServiceFactory<S, Request>,
614658
S: ServiceFactory<Request, Config = AppConfig>,
615659
S::Error: Into<Error>,
616660
S::InitError: fmt::Debug,

0 commit comments

Comments
 (0)