1use std::{
2 any::Any,
3 cmp, fmt,
4 future::Future,
5 io,
6 marker::PhantomData,
7 net,
8 sync::{Arc, Mutex},
9 time::Duration,
10};
11
12#[cfg(feature = "__tls")]
13use actix_http::TlsAcceptorConfig;
14use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
15use actix_server::{Server, ServerBuilder};
16use actix_service::{
17 map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
18};
19#[cfg(feature = "openssl")]
20use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorBuilder};
21
22use crate::{config::AppConfig, Error};
23
24struct Socket {
25 scheme: &'static str,
26 addr: net::SocketAddr,
27}
28
29struct Config {
30 host: Option<String>,
31 keep_alive: KeepAlive,
32 client_request_timeout: Duration,
33 client_disconnect_timeout: Duration,
34 h1_allow_half_closed: bool,
35 #[allow(dead_code)] tls_handshake_timeout: Option<Duration>,
37}
38
39#[must_use]
71pub struct HttpServer<F, I, S, B>
72where
73 F: Fn() -> I + Send + Clone + 'static,
74 I: IntoServiceFactory<S, Request>,
75 S: ServiceFactory<Request, Config = AppConfig>,
76 S::Error: Into<Error>,
77 S::InitError: fmt::Debug,
78 S::Response: Into<Response<B>>,
79 B: MessageBody,
80{
81 pub(super) factory: F,
82 config: Arc<Mutex<Config>>,
83 backlog: u32,
84 sockets: Vec<Socket>,
85 builder: ServerBuilder,
86 #[allow(clippy::type_complexity)]
87 on_connect_fn: Option<Arc<dyn Fn(&dyn Any, &mut Extensions) + Send + Sync>>,
88 _phantom: PhantomData<(S, B)>,
89}
90
91impl<F, I, S, B> HttpServer<F, I, S, B>
92where
93 F: Fn() -> I + Send + Clone + 'static,
94 I: IntoServiceFactory<S, Request>,
95
96 S: ServiceFactory<Request, Config = AppConfig> + 'static,
97 S::Error: Into<Error> + 'static,
98 S::InitError: fmt::Debug,
99 S::Response: Into<Response<B>> + 'static,
100 <S::Service as Service<Request>>::Future: 'static,
101 S::Service: 'static,
102
103 B: MessageBody + 'static,
104{
105 pub fn new(factory: F) -> Self {
113 HttpServer {
114 factory,
115 config: Arc::new(Mutex::new(Config {
116 host: None,
117 keep_alive: KeepAlive::default(),
118 client_request_timeout: Duration::from_secs(5),
119 client_disconnect_timeout: Duration::from_secs(1),
120 h1_allow_half_closed: true,
121 tls_handshake_timeout: None,
122 })),
123 backlog: 1024,
124 sockets: Vec::new(),
125 builder: ServerBuilder::default(),
126 on_connect_fn: None,
127 _phantom: PhantomData,
128 }
129 }
130
131 pub fn workers(mut self, num: usize) -> Self {
146 self.builder = self.builder.workers(num);
147 self
148 }
149
150 pub fn keep_alive<T: Into<KeepAlive>>(self, val: T) -> Self {
154 self.config.lock().unwrap().keep_alive = val.into();
155 self
156 }
157
158 pub fn backlog(mut self, backlog: u32) -> Self {
168 self.backlog = backlog;
169 self.builder = self.builder.backlog(backlog);
170 self
171 }
172
173 pub fn max_connections(mut self, num: usize) -> Self {
180 self.builder = self.builder.max_concurrent_connections(num);
181 self
182 }
183
184 #[allow(unused_variables)]
191 pub fn max_connection_rate(self, num: usize) -> Self {
192 #[cfg(feature = "__tls")]
193 actix_tls::accept::max_concurrent_tls_connect(num);
194 self
195 }
196
197 pub fn worker_max_blocking_threads(mut self, num: usize) -> Self {
203 self.builder = self.builder.worker_max_blocking_threads(num);
204 self
205 }
206
207 pub fn client_request_timeout(self, dur: Duration) -> Self {
216 self.config.lock().unwrap().client_request_timeout = dur;
217 self
218 }
219
220 #[doc(hidden)]
221 #[deprecated(since = "4.0.0", note = "Renamed to `client_request_timeout`.")]
222 pub fn client_timeout(self, dur: Duration) -> Self {
223 self.client_request_timeout(dur)
224 }
225
226 pub fn client_disconnect_timeout(self, dur: Duration) -> Self {
235 self.config.lock().unwrap().client_disconnect_timeout = dur;
236 self
237 }
238
239 #[cfg(feature = "__tls")]
246 pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
247 self.config
248 .lock()
249 .unwrap()
250 .tls_handshake_timeout
251 .replace(dur);
252
253 self
254 }
255
256 #[doc(hidden)]
257 #[deprecated(since = "4.0.0", note = "Renamed to `client_disconnect_timeout`.")]
258 pub fn client_shutdown(self, dur: u64) -> Self {
259 self.client_disconnect_timeout(Duration::from_millis(dur))
260 }
261
262 pub fn h1_allow_half_closed(self, allow: bool) -> Self {
270 self.config.lock().unwrap().h1_allow_half_closed = allow;
271 self
272 }
273
274 pub fn on_connect<CB>(mut self, f: CB) -> HttpServer<F, I, S, B>
293 where
294 CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,
295 {
296 self.on_connect_fn = Some(Arc::new(f));
297 self
298 }
299
300 pub fn server_hostname<T: AsRef<str>>(self, val: T) -> Self {
307 self.config.lock().unwrap().host = Some(val.as_ref().to_owned());
308 self
309 }
310
311 pub fn system_exit(mut self) -> Self {
315 self.builder = self.builder.system_exit();
316 self
317 }
318
319 pub fn disable_signals(mut self) -> Self {
321 self.builder = self.builder.disable_signals();
322 self
323 }
324
325 pub fn shutdown_signal<Fut>(mut self, shutdown_signal: Fut) -> Self
349 where
350 Fut: Future<Output = ()> + Send + 'static,
351 {
352 self.builder = self.builder.shutdown_signal(shutdown_signal);
353 self
354 }
355
356 pub fn shutdown_timeout(mut self, sec: u64) -> Self {
363 self.builder = self.builder.shutdown_timeout(sec);
364 self
365 }
366
367 pub fn addrs(&self) -> Vec<net::SocketAddr> {
369 self.sockets.iter().map(|s| s.addr).collect()
370 }
371
372 pub fn addrs_with_scheme(&self) -> Vec<(net::SocketAddr, &str)> {
378 self.sockets.iter().map(|s| (s.addr, s.scheme)).collect()
379 }
380
381 pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
428 let sockets = bind_addrs(addrs, self.backlog)?;
429
430 for lst in sockets {
431 self = self.listen(lst)?;
432 }
433
434 Ok(self)
435 }
436
437 #[cfg(feature = "http2")]
442 pub fn bind_auto_h2c<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
443 let sockets = bind_addrs(addrs, self.backlog)?;
444
445 for lst in sockets {
446 self = self.listen_auto_h2c(lst)?;
447 }
448
449 Ok(self)
450 }
451
452 #[cfg(feature = "rustls-0_20")]
459 pub fn bind_rustls<A: net::ToSocketAddrs>(
460 mut self,
461 addrs: A,
462 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
463 ) -> io::Result<Self> {
464 let sockets = bind_addrs(addrs, self.backlog)?;
465 for lst in sockets {
466 self = self.listen_rustls_0_20_inner(lst, config.clone())?;
467 }
468 Ok(self)
469 }
470
471 #[cfg(feature = "rustls-0_21")]
478 pub fn bind_rustls_021<A: net::ToSocketAddrs>(
479 mut self,
480 addrs: A,
481 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
482 ) -> io::Result<Self> {
483 let sockets = bind_addrs(addrs, self.backlog)?;
484 for lst in sockets {
485 self = self.listen_rustls_0_21_inner(lst, config.clone())?;
486 }
487 Ok(self)
488 }
489
490 #[cfg(feature = "rustls-0_22")]
497 pub fn bind_rustls_0_22<A: net::ToSocketAddrs>(
498 mut self,
499 addrs: A,
500 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
501 ) -> io::Result<Self> {
502 let sockets = bind_addrs(addrs, self.backlog)?;
503 for lst in sockets {
504 self = self.listen_rustls_0_22_inner(lst, config.clone())?;
505 }
506 Ok(self)
507 }
508
509 #[cfg(feature = "rustls-0_23")]
516 pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
517 mut self,
518 addrs: A,
519 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
520 ) -> io::Result<Self> {
521 let sockets = bind_addrs(addrs, self.backlog)?;
522 for lst in sockets {
523 self = self.listen_rustls_0_23_inner(lst, config.clone())?;
524 }
525 Ok(self)
526 }
527
528 #[cfg(feature = "openssl")]
535 pub fn bind_openssl<A>(mut self, addrs: A, builder: SslAcceptorBuilder) -> io::Result<Self>
536 where
537 A: net::ToSocketAddrs,
538 {
539 let sockets = bind_addrs(addrs, self.backlog)?;
540 let acceptor = openssl_acceptor(builder)?;
541
542 for lst in sockets {
543 self = self.listen_openssl_inner(lst, acceptor.clone())?;
544 }
545
546 Ok(self)
547 }
548
549 pub fn listen(mut self, lst: net::TcpListener) -> io::Result<Self> {
554 let cfg = Arc::clone(&self.config);
555 let factory = self.factory.clone();
556 let addr = lst.local_addr().unwrap();
557
558 self.sockets.push(Socket {
559 addr,
560 scheme: "http",
561 });
562
563 let on_connect_fn = self.on_connect_fn.clone();
564
565 self.builder =
566 self.builder
567 .listen(format!("actix-web-service-{}", addr), lst, move || {
568 let cfg = cfg.lock().unwrap();
569 let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
570
571 let mut svc = HttpService::build()
572 .keep_alive(cfg.keep_alive)
573 .client_request_timeout(cfg.client_request_timeout)
574 .client_disconnect_timeout(cfg.client_disconnect_timeout)
575 .h1_allow_half_closed(cfg.h1_allow_half_closed)
576 .local_addr(addr);
577
578 if let Some(handler) = on_connect_fn.clone() {
579 svc =
580 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
581 };
582
583 let fac = factory()
584 .into_factory()
585 .map_err(|err| err.into().error_response());
586
587 svc.finish(map_config(fac, move |_| {
588 AppConfig::new(false, host.clone(), addr)
589 }))
590 .tcp()
591 })?;
592
593 Ok(self)
594 }
595
596 #[cfg(feature = "http2")]
598 pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result<Self> {
599 let cfg = Arc::clone(&self.config);
600 let factory = self.factory.clone();
601 let addr = lst.local_addr().unwrap();
602
603 self.sockets.push(Socket {
604 addr,
605 scheme: "http",
606 });
607
608 let on_connect_fn = self.on_connect_fn.clone();
609
610 self.builder =
611 self.builder
612 .listen(format!("actix-web-service-{}", addr), lst, move || {
613 let cfg = cfg.lock().unwrap();
614 let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
615
616 let mut svc = HttpService::build()
617 .keep_alive(cfg.keep_alive)
618 .client_request_timeout(cfg.client_request_timeout)
619 .client_disconnect_timeout(cfg.client_disconnect_timeout)
620 .h1_allow_half_closed(cfg.h1_allow_half_closed)
621 .local_addr(addr);
622
623 if let Some(handler) = on_connect_fn.clone() {
624 svc =
625 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
626 };
627
628 let fac = factory()
629 .into_factory()
630 .map_err(|err| err.into().error_response());
631
632 svc.finish(map_config(fac, move |_| {
633 AppConfig::new(false, host.clone(), addr)
634 }))
635 .tcp_auto_h2c()
636 })?;
637
638 Ok(self)
639 }
640
641 #[cfg(feature = "rustls-0_20")]
648 pub fn listen_rustls(
649 self,
650 lst: net::TcpListener,
651 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
652 ) -> io::Result<Self> {
653 self.listen_rustls_0_20_inner(lst, config)
654 }
655
656 #[cfg(feature = "rustls-0_21")]
663 pub fn listen_rustls_0_21(
664 self,
665 lst: net::TcpListener,
666 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
667 ) -> io::Result<Self> {
668 self.listen_rustls_0_21_inner(lst, config)
669 }
670
671 #[cfg(feature = "rustls-0_20")]
672 fn listen_rustls_0_20_inner(
673 mut self,
674 lst: net::TcpListener,
675 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
676 ) -> io::Result<Self> {
677 let factory = self.factory.clone();
678 let cfg = Arc::clone(&self.config);
679 let addr = lst.local_addr().unwrap();
680 self.sockets.push(Socket {
681 addr,
682 scheme: "https",
683 });
684
685 let on_connect_fn = self.on_connect_fn.clone();
686
687 self.builder =
688 self.builder
689 .listen(format!("actix-web-service-{}", addr), lst, move || {
690 let c = cfg.lock().unwrap();
691 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
692
693 let svc = HttpService::build()
694 .keep_alive(c.keep_alive)
695 .client_request_timeout(c.client_request_timeout)
696 .h1_allow_half_closed(c.h1_allow_half_closed)
697 .client_disconnect_timeout(c.client_disconnect_timeout);
698
699 let svc = if let Some(handler) = on_connect_fn.clone() {
700 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
701 } else {
702 svc
703 };
704
705 let fac = factory()
706 .into_factory()
707 .map_err(|err| err.into().error_response());
708
709 let acceptor_config = match c.tls_handshake_timeout {
710 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
711 None => TlsAcceptorConfig::default(),
712 };
713
714 svc.finish(map_config(fac, move |_| {
715 AppConfig::new(true, host.clone(), addr)
716 }))
717 .rustls_with_config(config.clone(), acceptor_config)
718 })?;
719
720 Ok(self)
721 }
722
723 #[cfg(feature = "rustls-0_21")]
724 fn listen_rustls_0_21_inner(
725 mut self,
726 lst: net::TcpListener,
727 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
728 ) -> io::Result<Self> {
729 let factory = self.factory.clone();
730 let cfg = Arc::clone(&self.config);
731 let addr = lst.local_addr().unwrap();
732 self.sockets.push(Socket {
733 addr,
734 scheme: "https",
735 });
736
737 let on_connect_fn = self.on_connect_fn.clone();
738
739 self.builder =
740 self.builder
741 .listen(format!("actix-web-service-{}", addr), lst, move || {
742 let c = cfg.lock().unwrap();
743 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
744
745 let svc = HttpService::build()
746 .keep_alive(c.keep_alive)
747 .client_request_timeout(c.client_request_timeout)
748 .h1_allow_half_closed(c.h1_allow_half_closed)
749 .client_disconnect_timeout(c.client_disconnect_timeout);
750
751 let svc = if let Some(handler) = on_connect_fn.clone() {
752 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
753 } else {
754 svc
755 };
756
757 let fac = factory()
758 .into_factory()
759 .map_err(|err| err.into().error_response());
760
761 let acceptor_config = match c.tls_handshake_timeout {
762 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
763 None => TlsAcceptorConfig::default(),
764 };
765
766 svc.finish(map_config(fac, move |_| {
767 AppConfig::new(true, host.clone(), addr)
768 }))
769 .rustls_021_with_config(config.clone(), acceptor_config)
770 })?;
771
772 Ok(self)
773 }
774
775 #[cfg(feature = "rustls-0_22")]
782 pub fn listen_rustls_0_22(
783 self,
784 lst: net::TcpListener,
785 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
786 ) -> io::Result<Self> {
787 self.listen_rustls_0_22_inner(lst, config)
788 }
789
790 #[cfg(feature = "rustls-0_22")]
791 fn listen_rustls_0_22_inner(
792 mut self,
793 lst: net::TcpListener,
794 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
795 ) -> io::Result<Self> {
796 let factory = self.factory.clone();
797 let cfg = Arc::clone(&self.config);
798 let addr = lst.local_addr().unwrap();
799 self.sockets.push(Socket {
800 addr,
801 scheme: "https",
802 });
803
804 let on_connect_fn = self.on_connect_fn.clone();
805
806 self.builder =
807 self.builder
808 .listen(format!("actix-web-service-{}", addr), lst, move || {
809 let c = cfg.lock().unwrap();
810 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
811
812 let svc = HttpService::build()
813 .keep_alive(c.keep_alive)
814 .client_request_timeout(c.client_request_timeout)
815 .h1_allow_half_closed(c.h1_allow_half_closed)
816 .client_disconnect_timeout(c.client_disconnect_timeout);
817
818 let svc = if let Some(handler) = on_connect_fn.clone() {
819 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
820 } else {
821 svc
822 };
823
824 let fac = factory()
825 .into_factory()
826 .map_err(|err| err.into().error_response());
827
828 let acceptor_config = match c.tls_handshake_timeout {
829 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
830 None => TlsAcceptorConfig::default(),
831 };
832
833 svc.finish(map_config(fac, move |_| {
834 AppConfig::new(true, host.clone(), addr)
835 }))
836 .rustls_0_22_with_config(config.clone(), acceptor_config)
837 })?;
838
839 Ok(self)
840 }
841
842 #[cfg(feature = "rustls-0_23")]
849 pub fn listen_rustls_0_23(
850 self,
851 lst: net::TcpListener,
852 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
853 ) -> io::Result<Self> {
854 self.listen_rustls_0_23_inner(lst, config)
855 }
856
857 #[cfg(feature = "rustls-0_23")]
858 fn listen_rustls_0_23_inner(
859 mut self,
860 lst: net::TcpListener,
861 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
862 ) -> io::Result<Self> {
863 let factory = self.factory.clone();
864 let cfg = Arc::clone(&self.config);
865 let addr = lst.local_addr().unwrap();
866 self.sockets.push(Socket {
867 addr,
868 scheme: "https",
869 });
870
871 let on_connect_fn = self.on_connect_fn.clone();
872
873 self.builder =
874 self.builder
875 .listen(format!("actix-web-service-{}", addr), lst, move || {
876 let c = cfg.lock().unwrap();
877 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
878
879 let svc = HttpService::build()
880 .keep_alive(c.keep_alive)
881 .client_request_timeout(c.client_request_timeout)
882 .h1_allow_half_closed(c.h1_allow_half_closed)
883 .client_disconnect_timeout(c.client_disconnect_timeout);
884
885 let svc = if let Some(handler) = on_connect_fn.clone() {
886 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
887 } else {
888 svc
889 };
890
891 let fac = factory()
892 .into_factory()
893 .map_err(|err| err.into().error_response());
894
895 let acceptor_config = match c.tls_handshake_timeout {
896 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
897 None => TlsAcceptorConfig::default(),
898 };
899
900 svc.finish(map_config(fac, move |_| {
901 AppConfig::new(true, host.clone(), addr)
902 }))
903 .rustls_0_23_with_config(config.clone(), acceptor_config)
904 })?;
905
906 Ok(self)
907 }
908
909 #[cfg(feature = "openssl")]
915 pub fn listen_openssl(
916 self,
917 lst: net::TcpListener,
918 builder: SslAcceptorBuilder,
919 ) -> io::Result<Self> {
920 self.listen_openssl_inner(lst, openssl_acceptor(builder)?)
921 }
922
923 #[cfg(feature = "openssl")]
924 fn listen_openssl_inner(
925 mut self,
926 lst: net::TcpListener,
927 acceptor: SslAcceptor,
928 ) -> io::Result<Self> {
929 let factory = self.factory.clone();
930 let cfg = Arc::clone(&self.config);
931 let addr = lst.local_addr().unwrap();
932
933 self.sockets.push(Socket {
934 addr,
935 scheme: "https",
936 });
937
938 let on_connect_fn = self.on_connect_fn.clone();
939
940 self.builder =
941 self.builder
942 .listen(format!("actix-web-service-{}", addr), lst, move || {
943 let c = cfg.lock().unwrap();
944 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
945
946 let svc = HttpService::build()
947 .keep_alive(c.keep_alive)
948 .client_request_timeout(c.client_request_timeout)
949 .client_disconnect_timeout(c.client_disconnect_timeout)
950 .h1_allow_half_closed(c.h1_allow_half_closed)
951 .local_addr(addr);
952
953 let svc = if let Some(handler) = on_connect_fn.clone() {
954 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
955 } else {
956 svc
957 };
958
959 let fac = factory()
960 .into_factory()
961 .map_err(|err| err.into().error_response());
962
963 #[allow(clippy::significant_drop_in_scrutinee)]
965 let acceptor_config = match c.tls_handshake_timeout {
966 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
967 None => TlsAcceptorConfig::default(),
968 };
969
970 svc.finish(map_config(fac, move |_| {
971 AppConfig::new(true, host.clone(), addr)
972 }))
973 .openssl_with_config(acceptor.clone(), acceptor_config)
974 })?;
975
976 Ok(self)
977 }
978
979 #[cfg(unix)]
981 pub fn bind_uds<A>(mut self, uds_path: A) -> io::Result<Self>
982 where
983 A: AsRef<std::path::Path>,
984 {
985 use actix_http::Protocol;
986 use actix_rt::net::UnixStream;
987 use actix_service::{fn_service, ServiceFactoryExt as _};
988
989 let cfg = Arc::clone(&self.config);
990 let factory = self.factory.clone();
991 let socket_addr =
992 net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
993
994 self.sockets.push(Socket {
995 scheme: "http",
996 addr: socket_addr,
997 });
998
999 self.builder = self.builder.bind_uds(
1000 format!("actix-web-service-{:?}", uds_path.as_ref()),
1001 uds_path,
1002 move || {
1003 let c = cfg.lock().unwrap();
1004 let config = AppConfig::new(
1005 false,
1006 c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1007 socket_addr,
1008 );
1009
1010 let fac = factory()
1011 .into_factory()
1012 .map_err(|err| err.into().error_response());
1013
1014 fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then(
1015 HttpService::build()
1016 .keep_alive(c.keep_alive)
1017 .client_request_timeout(c.client_request_timeout)
1018 .client_disconnect_timeout(c.client_disconnect_timeout)
1019 .h1_allow_half_closed(c.h1_allow_half_closed)
1020 .finish(map_config(fac, move |_| config.clone())),
1021 )
1022 },
1023 )?;
1024
1025 Ok(self)
1026 }
1027
1028 #[cfg(unix)]
1030 pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
1031 use actix_http::Protocol;
1032 use actix_rt::net::UnixStream;
1033 use actix_service::{fn_service, ServiceFactoryExt as _};
1034
1035 let cfg = Arc::clone(&self.config);
1036 let factory = self.factory.clone();
1037 let socket_addr =
1038 net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1039
1040 self.sockets.push(Socket {
1041 scheme: "http",
1042 addr: socket_addr,
1043 });
1044
1045 let addr = lst.local_addr()?;
1046 let name = format!("actix-web-service-{:?}", addr);
1047 let on_connect_fn = self.on_connect_fn.clone();
1048
1049 self.builder = self.builder.listen_uds(name, lst, move || {
1050 let c = cfg.lock().unwrap();
1051 let config = AppConfig::new(
1052 false,
1053 c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1054 socket_addr,
1055 );
1056
1057 fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1058 let mut svc = HttpService::build()
1059 .keep_alive(c.keep_alive)
1060 .client_request_timeout(c.client_request_timeout)
1061 .h1_allow_half_closed(c.h1_allow_half_closed)
1062 .client_disconnect_timeout(c.client_disconnect_timeout);
1063
1064 if let Some(handler) = on_connect_fn.clone() {
1065 svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1066 }
1067
1068 let fac = factory()
1069 .into_factory()
1070 .map_err(|err| err.into().error_response());
1071
1072 svc.finish(map_config(fac, move |_| config.clone()))
1073 })
1074 })?;
1075 Ok(self)
1076 }
1077}
1078
1079impl<F, I, S, B> HttpServer<F, I, S, B>
1080where
1081 F: Fn() -> I + Send + Clone + 'static,
1082 I: IntoServiceFactory<S, Request>,
1083 S: ServiceFactory<Request, Config = AppConfig>,
1084 S::Error: Into<Error>,
1085 S::InitError: fmt::Debug,
1086 S::Response: Into<Response<B>>,
1087 S::Service: 'static,
1088 B: MessageBody,
1089{
1090 pub fn run(self) -> Server {
1103 self.builder.run()
1104 }
1105}
1106
1107fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
1109 let mut err = None;
1110 let mut success = false;
1111 let mut sockets = Vec::new();
1112
1113 for addr in addrs.to_socket_addrs()? {
1114 match create_tcp_listener(addr, backlog) {
1115 Ok(lst) => {
1116 success = true;
1117 sockets.push(lst);
1118 }
1119 Err(error) => err = Some(error),
1120 }
1121 }
1122
1123 if success {
1124 Ok(sockets)
1125 } else if let Some(err) = err.take() {
1126 Err(err)
1127 } else {
1128 Err(io::Error::other("Could not bind to address"))
1129 }
1130}
1131
1132fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
1134 use socket2::{Domain, Protocol, Socket, Type};
1135 let domain = Domain::for_address(addr);
1136 let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
1137 #[cfg(not(windows))]
1138 {
1139 socket.set_reuse_address(true)?;
1140 }
1141 socket.bind(&addr.into())?;
1142 let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
1144 socket.listen(backlog)?;
1145 Ok(net::TcpListener::from(socket))
1146}
1147
1148#[cfg(feature = "openssl")]
1150fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
1151 builder.set_alpn_select_callback(|_, protocols| {
1152 const H2: &[u8] = b"\x02h2";
1153 const H11: &[u8] = b"\x08http/1.1";
1154
1155 if protocols.windows(3).any(|window| window == H2) {
1156 Ok(b"h2")
1157 } else if protocols.windows(9).any(|window| window == H11) {
1158 Ok(b"http/1.1")
1159 } else {
1160 Err(AlpnError::NOACK)
1161 }
1162 });
1163
1164 builder.set_alpn_protos(b"\x08http/1.1\x02h2")?;
1165
1166 Ok(builder.build())
1167}