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 #[allow(dead_code)] tls_handshake_timeout: Option<Duration>,
36}
37
38#[must_use]
70pub struct HttpServer<F, I, S, B>
71where
72 F: Fn() -> I + Send + Clone + 'static,
73 I: IntoServiceFactory<S, Request>,
74 S: ServiceFactory<Request, Config = AppConfig>,
75 S::Error: Into<Error>,
76 S::InitError: fmt::Debug,
77 S::Response: Into<Response<B>>,
78 B: MessageBody,
79{
80 pub(super) factory: F,
81 config: Arc<Mutex<Config>>,
82 backlog: u32,
83 sockets: Vec<Socket>,
84 builder: ServerBuilder,
85 #[allow(clippy::type_complexity)]
86 on_connect_fn: Option<Arc<dyn Fn(&dyn Any, &mut Extensions) + Send + Sync>>,
87 _phantom: PhantomData<(S, B)>,
88}
89
90impl<F, I, S, B> HttpServer<F, I, S, B>
91where
92 F: Fn() -> I + Send + Clone + 'static,
93 I: IntoServiceFactory<S, Request>,
94
95 S: ServiceFactory<Request, Config = AppConfig> + 'static,
96 S::Error: Into<Error> + 'static,
97 S::InitError: fmt::Debug,
98 S::Response: Into<Response<B>> + 'static,
99 <S::Service as Service<Request>>::Future: 'static,
100 S::Service: 'static,
101
102 B: MessageBody + 'static,
103{
104 pub fn new(factory: F) -> Self {
112 HttpServer {
113 factory,
114 config: Arc::new(Mutex::new(Config {
115 host: None,
116 keep_alive: KeepAlive::default(),
117 client_request_timeout: Duration::from_secs(5),
118 client_disconnect_timeout: Duration::from_secs(1),
119 tls_handshake_timeout: None,
120 })),
121 backlog: 1024,
122 sockets: Vec::new(),
123 builder: ServerBuilder::default(),
124 on_connect_fn: None,
125 _phantom: PhantomData,
126 }
127 }
128
129 pub fn workers(mut self, num: usize) -> Self {
144 self.builder = self.builder.workers(num);
145 self
146 }
147
148 pub fn keep_alive<T: Into<KeepAlive>>(self, val: T) -> Self {
152 self.config.lock().unwrap().keep_alive = val.into();
153 self
154 }
155
156 pub fn backlog(mut self, backlog: u32) -> Self {
166 self.backlog = backlog;
167 self.builder = self.builder.backlog(backlog);
168 self
169 }
170
171 pub fn max_connections(mut self, num: usize) -> Self {
178 self.builder = self.builder.max_concurrent_connections(num);
179 self
180 }
181
182 #[allow(unused_variables)]
189 pub fn max_connection_rate(self, num: usize) -> Self {
190 #[cfg(feature = "__tls")]
191 actix_tls::accept::max_concurrent_tls_connect(num);
192 self
193 }
194
195 pub fn worker_max_blocking_threads(mut self, num: usize) -> Self {
201 self.builder = self.builder.worker_max_blocking_threads(num);
202 self
203 }
204
205 pub fn client_request_timeout(self, dur: Duration) -> Self {
214 self.config.lock().unwrap().client_request_timeout = dur;
215 self
216 }
217
218 #[doc(hidden)]
219 #[deprecated(since = "4.0.0", note = "Renamed to `client_request_timeout`.")]
220 pub fn client_timeout(self, dur: Duration) -> Self {
221 self.client_request_timeout(dur)
222 }
223
224 pub fn client_disconnect_timeout(self, dur: Duration) -> Self {
233 self.config.lock().unwrap().client_disconnect_timeout = dur;
234 self
235 }
236
237 #[cfg(feature = "__tls")]
244 pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
245 self.config
246 .lock()
247 .unwrap()
248 .tls_handshake_timeout
249 .replace(dur);
250
251 self
252 }
253
254 #[doc(hidden)]
255 #[deprecated(since = "4.0.0", note = "Renamed to `client_disconnect_timeout`.")]
256 pub fn client_shutdown(self, dur: u64) -> Self {
257 self.client_disconnect_timeout(Duration::from_millis(dur))
258 }
259
260 pub fn on_connect<CB>(mut self, f: CB) -> HttpServer<F, I, S, B>
279 where
280 CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,
281 {
282 self.on_connect_fn = Some(Arc::new(f));
283 self
284 }
285
286 pub fn server_hostname<T: AsRef<str>>(self, val: T) -> Self {
293 self.config.lock().unwrap().host = Some(val.as_ref().to_owned());
294 self
295 }
296
297 pub fn system_exit(mut self) -> Self {
301 self.builder = self.builder.system_exit();
302 self
303 }
304
305 pub fn disable_signals(mut self) -> Self {
307 self.builder = self.builder.disable_signals();
308 self
309 }
310
311 pub fn shutdown_signal<Fut>(mut self, shutdown_signal: Fut) -> Self
335 where
336 Fut: Future<Output = ()> + Send + 'static,
337 {
338 self.builder = self.builder.shutdown_signal(shutdown_signal);
339 self
340 }
341
342 pub fn shutdown_timeout(mut self, sec: u64) -> Self {
349 self.builder = self.builder.shutdown_timeout(sec);
350 self
351 }
352
353 pub fn addrs(&self) -> Vec<net::SocketAddr> {
355 self.sockets.iter().map(|s| s.addr).collect()
356 }
357
358 pub fn addrs_with_scheme(&self) -> Vec<(net::SocketAddr, &str)> {
364 self.sockets.iter().map(|s| (s.addr, s.scheme)).collect()
365 }
366
367 pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
414 let sockets = bind_addrs(addrs, self.backlog)?;
415
416 for lst in sockets {
417 self = self.listen(lst)?;
418 }
419
420 Ok(self)
421 }
422
423 #[cfg(feature = "http2")]
428 pub fn bind_auto_h2c<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
429 let sockets = bind_addrs(addrs, self.backlog)?;
430
431 for lst in sockets {
432 self = self.listen_auto_h2c(lst)?;
433 }
434
435 Ok(self)
436 }
437
438 #[cfg(feature = "rustls-0_20")]
445 pub fn bind_rustls<A: net::ToSocketAddrs>(
446 mut self,
447 addrs: A,
448 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
449 ) -> io::Result<Self> {
450 let sockets = bind_addrs(addrs, self.backlog)?;
451 for lst in sockets {
452 self = self.listen_rustls_0_20_inner(lst, config.clone())?;
453 }
454 Ok(self)
455 }
456
457 #[cfg(feature = "rustls-0_21")]
464 pub fn bind_rustls_021<A: net::ToSocketAddrs>(
465 mut self,
466 addrs: A,
467 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
468 ) -> io::Result<Self> {
469 let sockets = bind_addrs(addrs, self.backlog)?;
470 for lst in sockets {
471 self = self.listen_rustls_0_21_inner(lst, config.clone())?;
472 }
473 Ok(self)
474 }
475
476 #[cfg(feature = "rustls-0_22")]
483 pub fn bind_rustls_0_22<A: net::ToSocketAddrs>(
484 mut self,
485 addrs: A,
486 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
487 ) -> io::Result<Self> {
488 let sockets = bind_addrs(addrs, self.backlog)?;
489 for lst in sockets {
490 self = self.listen_rustls_0_22_inner(lst, config.clone())?;
491 }
492 Ok(self)
493 }
494
495 #[cfg(feature = "rustls-0_23")]
502 pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
503 mut self,
504 addrs: A,
505 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
506 ) -> io::Result<Self> {
507 let sockets = bind_addrs(addrs, self.backlog)?;
508 for lst in sockets {
509 self = self.listen_rustls_0_23_inner(lst, config.clone())?;
510 }
511 Ok(self)
512 }
513
514 #[cfg(feature = "openssl")]
521 pub fn bind_openssl<A>(mut self, addrs: A, builder: SslAcceptorBuilder) -> io::Result<Self>
522 where
523 A: net::ToSocketAddrs,
524 {
525 let sockets = bind_addrs(addrs, self.backlog)?;
526 let acceptor = openssl_acceptor(builder)?;
527
528 for lst in sockets {
529 self = self.listen_openssl_inner(lst, acceptor.clone())?;
530 }
531
532 Ok(self)
533 }
534
535 pub fn listen(mut self, lst: net::TcpListener) -> io::Result<Self> {
540 let cfg = Arc::clone(&self.config);
541 let factory = self.factory.clone();
542 let addr = lst.local_addr().unwrap();
543
544 self.sockets.push(Socket {
545 addr,
546 scheme: "http",
547 });
548
549 let on_connect_fn = self.on_connect_fn.clone();
550
551 self.builder =
552 self.builder
553 .listen(format!("actix-web-service-{}", addr), lst, move || {
554 let cfg = cfg.lock().unwrap();
555 let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
556
557 let mut svc = HttpService::build()
558 .keep_alive(cfg.keep_alive)
559 .client_request_timeout(cfg.client_request_timeout)
560 .client_disconnect_timeout(cfg.client_disconnect_timeout)
561 .local_addr(addr);
562
563 if let Some(handler) = on_connect_fn.clone() {
564 svc =
565 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
566 };
567
568 let fac = factory()
569 .into_factory()
570 .map_err(|err| err.into().error_response());
571
572 svc.finish(map_config(fac, move |_| {
573 AppConfig::new(false, host.clone(), addr)
574 }))
575 .tcp()
576 })?;
577
578 Ok(self)
579 }
580
581 #[cfg(feature = "http2")]
583 pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result<Self> {
584 let cfg = Arc::clone(&self.config);
585 let factory = self.factory.clone();
586 let addr = lst.local_addr().unwrap();
587
588 self.sockets.push(Socket {
589 addr,
590 scheme: "http",
591 });
592
593 let on_connect_fn = self.on_connect_fn.clone();
594
595 self.builder =
596 self.builder
597 .listen(format!("actix-web-service-{}", addr), lst, move || {
598 let cfg = cfg.lock().unwrap();
599 let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
600
601 let mut svc = HttpService::build()
602 .keep_alive(cfg.keep_alive)
603 .client_request_timeout(cfg.client_request_timeout)
604 .client_disconnect_timeout(cfg.client_disconnect_timeout)
605 .local_addr(addr);
606
607 if let Some(handler) = on_connect_fn.clone() {
608 svc =
609 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
610 };
611
612 let fac = factory()
613 .into_factory()
614 .map_err(|err| err.into().error_response());
615
616 svc.finish(map_config(fac, move |_| {
617 AppConfig::new(false, host.clone(), addr)
618 }))
619 .tcp_auto_h2c()
620 })?;
621
622 Ok(self)
623 }
624
625 #[cfg(feature = "rustls-0_20")]
632 pub fn listen_rustls(
633 self,
634 lst: net::TcpListener,
635 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
636 ) -> io::Result<Self> {
637 self.listen_rustls_0_20_inner(lst, config)
638 }
639
640 #[cfg(feature = "rustls-0_21")]
647 pub fn listen_rustls_0_21(
648 self,
649 lst: net::TcpListener,
650 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
651 ) -> io::Result<Self> {
652 self.listen_rustls_0_21_inner(lst, config)
653 }
654
655 #[cfg(feature = "rustls-0_20")]
656 fn listen_rustls_0_20_inner(
657 mut self,
658 lst: net::TcpListener,
659 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
660 ) -> io::Result<Self> {
661 let factory = self.factory.clone();
662 let cfg = Arc::clone(&self.config);
663 let addr = lst.local_addr().unwrap();
664 self.sockets.push(Socket {
665 addr,
666 scheme: "https",
667 });
668
669 let on_connect_fn = self.on_connect_fn.clone();
670
671 self.builder =
672 self.builder
673 .listen(format!("actix-web-service-{}", addr), lst, move || {
674 let c = cfg.lock().unwrap();
675 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
676
677 let svc = HttpService::build()
678 .keep_alive(c.keep_alive)
679 .client_request_timeout(c.client_request_timeout)
680 .client_disconnect_timeout(c.client_disconnect_timeout);
681
682 let svc = if let Some(handler) = on_connect_fn.clone() {
683 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
684 } else {
685 svc
686 };
687
688 let fac = factory()
689 .into_factory()
690 .map_err(|err| err.into().error_response());
691
692 let acceptor_config = match c.tls_handshake_timeout {
693 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
694 None => TlsAcceptorConfig::default(),
695 };
696
697 svc.finish(map_config(fac, move |_| {
698 AppConfig::new(true, host.clone(), addr)
699 }))
700 .rustls_with_config(config.clone(), acceptor_config)
701 })?;
702
703 Ok(self)
704 }
705
706 #[cfg(feature = "rustls-0_21")]
707 fn listen_rustls_0_21_inner(
708 mut self,
709 lst: net::TcpListener,
710 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
711 ) -> io::Result<Self> {
712 let factory = self.factory.clone();
713 let cfg = Arc::clone(&self.config);
714 let addr = lst.local_addr().unwrap();
715 self.sockets.push(Socket {
716 addr,
717 scheme: "https",
718 });
719
720 let on_connect_fn = self.on_connect_fn.clone();
721
722 self.builder =
723 self.builder
724 .listen(format!("actix-web-service-{}", addr), lst, move || {
725 let c = cfg.lock().unwrap();
726 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
727
728 let svc = HttpService::build()
729 .keep_alive(c.keep_alive)
730 .client_request_timeout(c.client_request_timeout)
731 .client_disconnect_timeout(c.client_disconnect_timeout);
732
733 let svc = if let Some(handler) = on_connect_fn.clone() {
734 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
735 } else {
736 svc
737 };
738
739 let fac = factory()
740 .into_factory()
741 .map_err(|err| err.into().error_response());
742
743 let acceptor_config = match c.tls_handshake_timeout {
744 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
745 None => TlsAcceptorConfig::default(),
746 };
747
748 svc.finish(map_config(fac, move |_| {
749 AppConfig::new(true, host.clone(), addr)
750 }))
751 .rustls_021_with_config(config.clone(), acceptor_config)
752 })?;
753
754 Ok(self)
755 }
756
757 #[cfg(feature = "rustls-0_22")]
764 pub fn listen_rustls_0_22(
765 self,
766 lst: net::TcpListener,
767 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
768 ) -> io::Result<Self> {
769 self.listen_rustls_0_22_inner(lst, config)
770 }
771
772 #[cfg(feature = "rustls-0_22")]
773 fn listen_rustls_0_22_inner(
774 mut self,
775 lst: net::TcpListener,
776 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
777 ) -> io::Result<Self> {
778 let factory = self.factory.clone();
779 let cfg = Arc::clone(&self.config);
780 let addr = lst.local_addr().unwrap();
781 self.sockets.push(Socket {
782 addr,
783 scheme: "https",
784 });
785
786 let on_connect_fn = self.on_connect_fn.clone();
787
788 self.builder =
789 self.builder
790 .listen(format!("actix-web-service-{}", addr), lst, move || {
791 let c = cfg.lock().unwrap();
792 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
793
794 let svc = HttpService::build()
795 .keep_alive(c.keep_alive)
796 .client_request_timeout(c.client_request_timeout)
797 .client_disconnect_timeout(c.client_disconnect_timeout);
798
799 let svc = if let Some(handler) = on_connect_fn.clone() {
800 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
801 } else {
802 svc
803 };
804
805 let fac = factory()
806 .into_factory()
807 .map_err(|err| err.into().error_response());
808
809 let acceptor_config = match c.tls_handshake_timeout {
810 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
811 None => TlsAcceptorConfig::default(),
812 };
813
814 svc.finish(map_config(fac, move |_| {
815 AppConfig::new(true, host.clone(), addr)
816 }))
817 .rustls_0_22_with_config(config.clone(), acceptor_config)
818 })?;
819
820 Ok(self)
821 }
822
823 #[cfg(feature = "rustls-0_23")]
830 pub fn listen_rustls_0_23(
831 self,
832 lst: net::TcpListener,
833 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
834 ) -> io::Result<Self> {
835 self.listen_rustls_0_23_inner(lst, config)
836 }
837
838 #[cfg(feature = "rustls-0_23")]
839 fn listen_rustls_0_23_inner(
840 mut self,
841 lst: net::TcpListener,
842 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
843 ) -> io::Result<Self> {
844 let factory = self.factory.clone();
845 let cfg = Arc::clone(&self.config);
846 let addr = lst.local_addr().unwrap();
847 self.sockets.push(Socket {
848 addr,
849 scheme: "https",
850 });
851
852 let on_connect_fn = self.on_connect_fn.clone();
853
854 self.builder =
855 self.builder
856 .listen(format!("actix-web-service-{}", addr), lst, move || {
857 let c = cfg.lock().unwrap();
858 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
859
860 let svc = HttpService::build()
861 .keep_alive(c.keep_alive)
862 .client_request_timeout(c.client_request_timeout)
863 .client_disconnect_timeout(c.client_disconnect_timeout);
864
865 let svc = if let Some(handler) = on_connect_fn.clone() {
866 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
867 } else {
868 svc
869 };
870
871 let fac = factory()
872 .into_factory()
873 .map_err(|err| err.into().error_response());
874
875 let acceptor_config = match c.tls_handshake_timeout {
876 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
877 None => TlsAcceptorConfig::default(),
878 };
879
880 svc.finish(map_config(fac, move |_| {
881 AppConfig::new(true, host.clone(), addr)
882 }))
883 .rustls_0_23_with_config(config.clone(), acceptor_config)
884 })?;
885
886 Ok(self)
887 }
888
889 #[cfg(feature = "openssl")]
895 pub fn listen_openssl(
896 self,
897 lst: net::TcpListener,
898 builder: SslAcceptorBuilder,
899 ) -> io::Result<Self> {
900 self.listen_openssl_inner(lst, openssl_acceptor(builder)?)
901 }
902
903 #[cfg(feature = "openssl")]
904 fn listen_openssl_inner(
905 mut self,
906 lst: net::TcpListener,
907 acceptor: SslAcceptor,
908 ) -> io::Result<Self> {
909 let factory = self.factory.clone();
910 let cfg = Arc::clone(&self.config);
911 let addr = lst.local_addr().unwrap();
912
913 self.sockets.push(Socket {
914 addr,
915 scheme: "https",
916 });
917
918 let on_connect_fn = self.on_connect_fn.clone();
919
920 self.builder =
921 self.builder
922 .listen(format!("actix-web-service-{}", addr), lst, move || {
923 let c = cfg.lock().unwrap();
924 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
925
926 let svc = HttpService::build()
927 .keep_alive(c.keep_alive)
928 .client_request_timeout(c.client_request_timeout)
929 .client_disconnect_timeout(c.client_disconnect_timeout)
930 .local_addr(addr);
931
932 let svc = if let Some(handler) = on_connect_fn.clone() {
933 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
934 } else {
935 svc
936 };
937
938 let fac = factory()
939 .into_factory()
940 .map_err(|err| err.into().error_response());
941
942 #[allow(clippy::significant_drop_in_scrutinee)]
944 let acceptor_config = match c.tls_handshake_timeout {
945 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
946 None => TlsAcceptorConfig::default(),
947 };
948
949 svc.finish(map_config(fac, move |_| {
950 AppConfig::new(true, host.clone(), addr)
951 }))
952 .openssl_with_config(acceptor.clone(), acceptor_config)
953 })?;
954
955 Ok(self)
956 }
957
958 #[cfg(unix)]
960 pub fn bind_uds<A>(mut self, uds_path: A) -> io::Result<Self>
961 where
962 A: AsRef<std::path::Path>,
963 {
964 use actix_http::Protocol;
965 use actix_rt::net::UnixStream;
966 use actix_service::{fn_service, ServiceFactoryExt as _};
967
968 let cfg = Arc::clone(&self.config);
969 let factory = self.factory.clone();
970 let socket_addr =
971 net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
972
973 self.sockets.push(Socket {
974 scheme: "http",
975 addr: socket_addr,
976 });
977
978 self.builder = self.builder.bind_uds(
979 format!("actix-web-service-{:?}", uds_path.as_ref()),
980 uds_path,
981 move || {
982 let c = cfg.lock().unwrap();
983 let config = AppConfig::new(
984 false,
985 c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
986 socket_addr,
987 );
988
989 let fac = factory()
990 .into_factory()
991 .map_err(|err| err.into().error_response());
992
993 fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then(
994 HttpService::build()
995 .keep_alive(c.keep_alive)
996 .client_request_timeout(c.client_request_timeout)
997 .client_disconnect_timeout(c.client_disconnect_timeout)
998 .finish(map_config(fac, move |_| config.clone())),
999 )
1000 },
1001 )?;
1002
1003 Ok(self)
1004 }
1005
1006 #[cfg(unix)]
1008 pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
1009 use actix_http::Protocol;
1010 use actix_rt::net::UnixStream;
1011 use actix_service::{fn_service, ServiceFactoryExt as _};
1012
1013 let cfg = Arc::clone(&self.config);
1014 let factory = self.factory.clone();
1015 let socket_addr =
1016 net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1017
1018 self.sockets.push(Socket {
1019 scheme: "http",
1020 addr: socket_addr,
1021 });
1022
1023 let addr = lst.local_addr()?;
1024 let name = format!("actix-web-service-{:?}", addr);
1025 let on_connect_fn = self.on_connect_fn.clone();
1026
1027 self.builder = self.builder.listen_uds(name, lst, move || {
1028 let c = cfg.lock().unwrap();
1029 let config = AppConfig::new(
1030 false,
1031 c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1032 socket_addr,
1033 );
1034
1035 fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1036 let mut svc = HttpService::build()
1037 .keep_alive(c.keep_alive)
1038 .client_request_timeout(c.client_request_timeout)
1039 .client_disconnect_timeout(c.client_disconnect_timeout);
1040
1041 if let Some(handler) = on_connect_fn.clone() {
1042 svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1043 }
1044
1045 let fac = factory()
1046 .into_factory()
1047 .map_err(|err| err.into().error_response());
1048
1049 svc.finish(map_config(fac, move |_| config.clone()))
1050 })
1051 })?;
1052 Ok(self)
1053 }
1054}
1055
1056impl<F, I, S, B> HttpServer<F, I, S, B>
1057where
1058 F: Fn() -> I + Send + Clone + 'static,
1059 I: IntoServiceFactory<S, Request>,
1060 S: ServiceFactory<Request, Config = AppConfig>,
1061 S::Error: Into<Error>,
1062 S::InitError: fmt::Debug,
1063 S::Response: Into<Response<B>>,
1064 S::Service: 'static,
1065 B: MessageBody,
1066{
1067 pub fn run(self) -> Server {
1080 self.builder.run()
1081 }
1082}
1083
1084fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
1086 let mut err = None;
1087 let mut success = false;
1088 let mut sockets = Vec::new();
1089
1090 for addr in addrs.to_socket_addrs()? {
1091 match create_tcp_listener(addr, backlog) {
1092 Ok(lst) => {
1093 success = true;
1094 sockets.push(lst);
1095 }
1096 Err(error) => err = Some(error),
1097 }
1098 }
1099
1100 if success {
1101 Ok(sockets)
1102 } else if let Some(err) = err.take() {
1103 Err(err)
1104 } else {
1105 Err(io::Error::other("Could not bind to address"))
1106 }
1107}
1108
1109fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
1111 use socket2::{Domain, Protocol, Socket, Type};
1112 let domain = Domain::for_address(addr);
1113 let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
1114 #[cfg(not(windows))]
1115 {
1116 socket.set_reuse_address(true)?;
1117 }
1118 socket.bind(&addr.into())?;
1119 let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
1121 socket.listen(backlog)?;
1122 Ok(net::TcpListener::from(socket))
1123}
1124
1125#[cfg(feature = "openssl")]
1127fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
1128 builder.set_alpn_select_callback(|_, protocols| {
1129 const H2: &[u8] = b"\x02h2";
1130 const H11: &[u8] = b"\x08http/1.1";
1131
1132 if protocols.windows(3).any(|window| window == H2) {
1133 Ok(b"h2")
1134 } else if protocols.windows(9).any(|window| window == H11) {
1135 Ok(b"http/1.1")
1136 } else {
1137 Err(AlpnError::NOACK)
1138 }
1139 });
1140
1141 builder.set_alpn_protos(b"\x08http/1.1\x02h2")?;
1142
1143 Ok(builder.build())
1144}