1use std::{
2 any::Any,
3 cmp, fmt, io,
4 marker::PhantomData,
5 net,
6 sync::{Arc, Mutex},
7 time::Duration,
8};
9
10#[cfg(feature = "__tls")]
11use actix_http::TlsAcceptorConfig;
12use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
13use actix_server::{Server, ServerBuilder};
14use actix_service::{
15 map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
16};
17#[cfg(feature = "openssl")]
18use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorBuilder};
19
20use crate::{config::AppConfig, Error};
21
22struct Socket {
23 scheme: &'static str,
24 addr: net::SocketAddr,
25}
26
27struct Config {
28 host: Option<String>,
29 keep_alive: KeepAlive,
30 client_request_timeout: Duration,
31 client_disconnect_timeout: Duration,
32 #[allow(dead_code)] tls_handshake_timeout: Option<Duration>,
34}
35
36pub struct HttpServer<F, I, S, B>
68where
69 F: Fn() -> I + Send + Clone + 'static,
70 I: IntoServiceFactory<S, Request>,
71 S: ServiceFactory<Request, Config = AppConfig>,
72 S::Error: Into<Error>,
73 S::InitError: fmt::Debug,
74 S::Response: Into<Response<B>>,
75 B: MessageBody,
76{
77 pub(super) factory: F,
78 config: Arc<Mutex<Config>>,
79 backlog: u32,
80 sockets: Vec<Socket>,
81 builder: ServerBuilder,
82 #[allow(clippy::type_complexity)]
83 on_connect_fn: Option<Arc<dyn Fn(&dyn Any, &mut Extensions) + Send + Sync>>,
84 _phantom: PhantomData<(S, B)>,
85}
86
87impl<F, I, S, B> HttpServer<F, I, S, B>
88where
89 F: Fn() -> I + Send + Clone + 'static,
90 I: IntoServiceFactory<S, Request>,
91
92 S: ServiceFactory<Request, Config = AppConfig> + 'static,
93 S::Error: Into<Error> + 'static,
94 S::InitError: fmt::Debug,
95 S::Response: Into<Response<B>> + 'static,
96 <S::Service as Service<Request>>::Future: 'static,
97 S::Service: 'static,
98
99 B: MessageBody + 'static,
100{
101 pub fn new(factory: F) -> Self {
109 HttpServer {
110 factory,
111 config: Arc::new(Mutex::new(Config {
112 host: None,
113 keep_alive: KeepAlive::default(),
114 client_request_timeout: Duration::from_secs(5),
115 client_disconnect_timeout: Duration::from_secs(1),
116 tls_handshake_timeout: None,
117 })),
118 backlog: 1024,
119 sockets: Vec::new(),
120 builder: ServerBuilder::default(),
121 on_connect_fn: None,
122 _phantom: PhantomData,
123 }
124 }
125
126 pub fn workers(mut self, num: usize) -> Self {
141 self.builder = self.builder.workers(num);
142 self
143 }
144
145 pub fn keep_alive<T: Into<KeepAlive>>(self, val: T) -> Self {
149 self.config.lock().unwrap().keep_alive = val.into();
150 self
151 }
152
153 pub fn backlog(mut self, backlog: u32) -> Self {
163 self.backlog = backlog;
164 self.builder = self.builder.backlog(backlog);
165 self
166 }
167
168 pub fn max_connections(mut self, num: usize) -> Self {
175 self.builder = self.builder.max_concurrent_connections(num);
176 self
177 }
178
179 #[allow(unused_variables)]
186 pub fn max_connection_rate(self, num: usize) -> Self {
187 #[cfg(feature = "__tls")]
188 actix_tls::accept::max_concurrent_tls_connect(num);
189 self
190 }
191
192 pub fn worker_max_blocking_threads(mut self, num: usize) -> Self {
198 self.builder = self.builder.worker_max_blocking_threads(num);
199 self
200 }
201
202 pub fn client_request_timeout(self, dur: Duration) -> Self {
211 self.config.lock().unwrap().client_request_timeout = dur;
212 self
213 }
214
215 #[doc(hidden)]
216 #[deprecated(since = "4.0.0", note = "Renamed to `client_request_timeout`.")]
217 pub fn client_timeout(self, dur: Duration) -> Self {
218 self.client_request_timeout(dur)
219 }
220
221 pub fn client_disconnect_timeout(self, dur: Duration) -> Self {
230 self.config.lock().unwrap().client_disconnect_timeout = dur;
231 self
232 }
233
234 #[cfg(feature = "__tls")]
241 pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
242 self.config
243 .lock()
244 .unwrap()
245 .tls_handshake_timeout
246 .replace(dur);
247
248 self
249 }
250
251 #[doc(hidden)]
252 #[deprecated(since = "4.0.0", note = "Renamed to `client_disconnect_timeout`.")]
253 pub fn client_shutdown(self, dur: u64) -> Self {
254 self.client_disconnect_timeout(Duration::from_millis(dur))
255 }
256
257 pub fn on_connect<CB>(self, f: CB) -> HttpServer<F, I, S, B>
276 where
277 CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,
278 {
279 HttpServer {
280 factory: self.factory,
281 config: self.config,
282 backlog: self.backlog,
283 sockets: self.sockets,
284 builder: self.builder,
285 on_connect_fn: Some(Arc::new(f)),
286 _phantom: PhantomData,
287 }
288 }
289
290 pub fn server_hostname<T: AsRef<str>>(self, val: T) -> Self {
297 self.config.lock().unwrap().host = Some(val.as_ref().to_owned());
298 self
299 }
300
301 pub fn system_exit(mut self) -> Self {
305 self.builder = self.builder.system_exit();
306 self
307 }
308
309 pub fn disable_signals(mut self) -> Self {
311 self.builder = self.builder.disable_signals();
312 self
313 }
314
315 pub fn shutdown_timeout(mut self, sec: u64) -> Self {
322 self.builder = self.builder.shutdown_timeout(sec);
323 self
324 }
325
326 pub fn addrs(&self) -> Vec<net::SocketAddr> {
328 self.sockets.iter().map(|s| s.addr).collect()
329 }
330
331 pub fn addrs_with_scheme(&self) -> Vec<(net::SocketAddr, &str)> {
337 self.sockets.iter().map(|s| (s.addr, s.scheme)).collect()
338 }
339
340 pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
387 let sockets = bind_addrs(addrs, self.backlog)?;
388
389 for lst in sockets {
390 self = self.listen(lst)?;
391 }
392
393 Ok(self)
394 }
395
396 #[cfg(feature = "http2")]
401 pub fn bind_auto_h2c<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
402 let sockets = bind_addrs(addrs, self.backlog)?;
403
404 for lst in sockets {
405 self = self.listen_auto_h2c(lst)?;
406 }
407
408 Ok(self)
409 }
410
411 #[cfg(feature = "rustls-0_20")]
418 pub fn bind_rustls<A: net::ToSocketAddrs>(
419 mut self,
420 addrs: A,
421 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
422 ) -> io::Result<Self> {
423 let sockets = bind_addrs(addrs, self.backlog)?;
424 for lst in sockets {
425 self = self.listen_rustls_0_20_inner(lst, config.clone())?;
426 }
427 Ok(self)
428 }
429
430 #[cfg(feature = "rustls-0_21")]
437 pub fn bind_rustls_021<A: net::ToSocketAddrs>(
438 mut self,
439 addrs: A,
440 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
441 ) -> io::Result<Self> {
442 let sockets = bind_addrs(addrs, self.backlog)?;
443 for lst in sockets {
444 self = self.listen_rustls_0_21_inner(lst, config.clone())?;
445 }
446 Ok(self)
447 }
448
449 #[cfg(feature = "rustls-0_22")]
456 pub fn bind_rustls_0_22<A: net::ToSocketAddrs>(
457 mut self,
458 addrs: A,
459 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
460 ) -> io::Result<Self> {
461 let sockets = bind_addrs(addrs, self.backlog)?;
462 for lst in sockets {
463 self = self.listen_rustls_0_22_inner(lst, config.clone())?;
464 }
465 Ok(self)
466 }
467
468 #[cfg(feature = "rustls-0_23")]
475 pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
476 mut self,
477 addrs: A,
478 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
479 ) -> io::Result<Self> {
480 let sockets = bind_addrs(addrs, self.backlog)?;
481 for lst in sockets {
482 self = self.listen_rustls_0_23_inner(lst, config.clone())?;
483 }
484 Ok(self)
485 }
486
487 #[cfg(feature = "openssl")]
494 pub fn bind_openssl<A>(mut self, addrs: A, builder: SslAcceptorBuilder) -> io::Result<Self>
495 where
496 A: net::ToSocketAddrs,
497 {
498 let sockets = bind_addrs(addrs, self.backlog)?;
499 let acceptor = openssl_acceptor(builder)?;
500
501 for lst in sockets {
502 self = self.listen_openssl_inner(lst, acceptor.clone())?;
503 }
504
505 Ok(self)
506 }
507
508 pub fn listen(mut self, lst: net::TcpListener) -> io::Result<Self> {
513 let cfg = Arc::clone(&self.config);
514 let factory = self.factory.clone();
515 let addr = lst.local_addr().unwrap();
516
517 self.sockets.push(Socket {
518 addr,
519 scheme: "http",
520 });
521
522 let on_connect_fn = self.on_connect_fn.clone();
523
524 self.builder =
525 self.builder
526 .listen(format!("actix-web-service-{}", addr), lst, move || {
527 let cfg = cfg.lock().unwrap();
528 let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
529
530 let mut svc = HttpService::build()
531 .keep_alive(cfg.keep_alive)
532 .client_request_timeout(cfg.client_request_timeout)
533 .client_disconnect_timeout(cfg.client_disconnect_timeout)
534 .local_addr(addr);
535
536 if let Some(handler) = on_connect_fn.clone() {
537 svc =
538 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
539 };
540
541 let fac = factory()
542 .into_factory()
543 .map_err(|err| err.into().error_response());
544
545 svc.finish(map_config(fac, move |_| {
546 AppConfig::new(false, host.clone(), addr)
547 }))
548 .tcp()
549 })?;
550
551 Ok(self)
552 }
553
554 #[cfg(feature = "http2")]
556 pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result<Self> {
557 let cfg = Arc::clone(&self.config);
558 let factory = self.factory.clone();
559 let addr = lst.local_addr().unwrap();
560
561 self.sockets.push(Socket {
562 addr,
563 scheme: "http",
564 });
565
566 let on_connect_fn = self.on_connect_fn.clone();
567
568 self.builder =
569 self.builder
570 .listen(format!("actix-web-service-{}", addr), lst, move || {
571 let cfg = cfg.lock().unwrap();
572 let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
573
574 let mut svc = HttpService::build()
575 .keep_alive(cfg.keep_alive)
576 .client_request_timeout(cfg.client_request_timeout)
577 .client_disconnect_timeout(cfg.client_disconnect_timeout)
578 .local_addr(addr);
579
580 if let Some(handler) = on_connect_fn.clone() {
581 svc =
582 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
583 };
584
585 let fac = factory()
586 .into_factory()
587 .map_err(|err| err.into().error_response());
588
589 svc.finish(map_config(fac, move |_| {
590 AppConfig::new(false, host.clone(), addr)
591 }))
592 .tcp_auto_h2c()
593 })?;
594
595 Ok(self)
596 }
597
598 #[cfg(feature = "rustls-0_20")]
605 pub fn listen_rustls(
606 self,
607 lst: net::TcpListener,
608 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
609 ) -> io::Result<Self> {
610 self.listen_rustls_0_20_inner(lst, config)
611 }
612
613 #[cfg(feature = "rustls-0_21")]
620 pub fn listen_rustls_0_21(
621 self,
622 lst: net::TcpListener,
623 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
624 ) -> io::Result<Self> {
625 self.listen_rustls_0_21_inner(lst, config)
626 }
627
628 #[cfg(feature = "rustls-0_20")]
629 fn listen_rustls_0_20_inner(
630 mut self,
631 lst: net::TcpListener,
632 config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
633 ) -> io::Result<Self> {
634 let factory = self.factory.clone();
635 let cfg = Arc::clone(&self.config);
636 let addr = lst.local_addr().unwrap();
637 self.sockets.push(Socket {
638 addr,
639 scheme: "https",
640 });
641
642 let on_connect_fn = self.on_connect_fn.clone();
643
644 self.builder =
645 self.builder
646 .listen(format!("actix-web-service-{}", addr), lst, move || {
647 let c = cfg.lock().unwrap();
648 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
649
650 let svc = HttpService::build()
651 .keep_alive(c.keep_alive)
652 .client_request_timeout(c.client_request_timeout)
653 .client_disconnect_timeout(c.client_disconnect_timeout);
654
655 let svc = if let Some(handler) = on_connect_fn.clone() {
656 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
657 } else {
658 svc
659 };
660
661 let fac = factory()
662 .into_factory()
663 .map_err(|err| err.into().error_response());
664
665 let acceptor_config = match c.tls_handshake_timeout {
666 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
667 None => TlsAcceptorConfig::default(),
668 };
669
670 svc.finish(map_config(fac, move |_| {
671 AppConfig::new(true, host.clone(), addr)
672 }))
673 .rustls_with_config(config.clone(), acceptor_config)
674 })?;
675
676 Ok(self)
677 }
678
679 #[cfg(feature = "rustls-0_21")]
680 fn listen_rustls_0_21_inner(
681 mut self,
682 lst: net::TcpListener,
683 config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
684 ) -> io::Result<Self> {
685 let factory = self.factory.clone();
686 let cfg = Arc::clone(&self.config);
687 let addr = lst.local_addr().unwrap();
688 self.sockets.push(Socket {
689 addr,
690 scheme: "https",
691 });
692
693 let on_connect_fn = self.on_connect_fn.clone();
694
695 self.builder =
696 self.builder
697 .listen(format!("actix-web-service-{}", addr), lst, move || {
698 let c = cfg.lock().unwrap();
699 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
700
701 let svc = HttpService::build()
702 .keep_alive(c.keep_alive)
703 .client_request_timeout(c.client_request_timeout)
704 .client_disconnect_timeout(c.client_disconnect_timeout);
705
706 let svc = if let Some(handler) = on_connect_fn.clone() {
707 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
708 } else {
709 svc
710 };
711
712 let fac = factory()
713 .into_factory()
714 .map_err(|err| err.into().error_response());
715
716 let acceptor_config = match c.tls_handshake_timeout {
717 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
718 None => TlsAcceptorConfig::default(),
719 };
720
721 svc.finish(map_config(fac, move |_| {
722 AppConfig::new(true, host.clone(), addr)
723 }))
724 .rustls_021_with_config(config.clone(), acceptor_config)
725 })?;
726
727 Ok(self)
728 }
729
730 #[cfg(feature = "rustls-0_22")]
737 pub fn listen_rustls_0_22(
738 self,
739 lst: net::TcpListener,
740 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
741 ) -> io::Result<Self> {
742 self.listen_rustls_0_22_inner(lst, config)
743 }
744
745 #[cfg(feature = "rustls-0_22")]
746 fn listen_rustls_0_22_inner(
747 mut self,
748 lst: net::TcpListener,
749 config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
750 ) -> io::Result<Self> {
751 let factory = self.factory.clone();
752 let cfg = Arc::clone(&self.config);
753 let addr = lst.local_addr().unwrap();
754 self.sockets.push(Socket {
755 addr,
756 scheme: "https",
757 });
758
759 let on_connect_fn = self.on_connect_fn.clone();
760
761 self.builder =
762 self.builder
763 .listen(format!("actix-web-service-{}", addr), lst, move || {
764 let c = cfg.lock().unwrap();
765 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
766
767 let svc = HttpService::build()
768 .keep_alive(c.keep_alive)
769 .client_request_timeout(c.client_request_timeout)
770 .client_disconnect_timeout(c.client_disconnect_timeout);
771
772 let svc = if let Some(handler) = on_connect_fn.clone() {
773 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
774 } else {
775 svc
776 };
777
778 let fac = factory()
779 .into_factory()
780 .map_err(|err| err.into().error_response());
781
782 let acceptor_config = match c.tls_handshake_timeout {
783 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
784 None => TlsAcceptorConfig::default(),
785 };
786
787 svc.finish(map_config(fac, move |_| {
788 AppConfig::new(true, host.clone(), addr)
789 }))
790 .rustls_0_22_with_config(config.clone(), acceptor_config)
791 })?;
792
793 Ok(self)
794 }
795
796 #[cfg(feature = "rustls-0_23")]
803 pub fn listen_rustls_0_23(
804 self,
805 lst: net::TcpListener,
806 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
807 ) -> io::Result<Self> {
808 self.listen_rustls_0_23_inner(lst, config)
809 }
810
811 #[cfg(feature = "rustls-0_23")]
812 fn listen_rustls_0_23_inner(
813 mut self,
814 lst: net::TcpListener,
815 config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
816 ) -> io::Result<Self> {
817 let factory = self.factory.clone();
818 let cfg = Arc::clone(&self.config);
819 let addr = lst.local_addr().unwrap();
820 self.sockets.push(Socket {
821 addr,
822 scheme: "https",
823 });
824
825 let on_connect_fn = self.on_connect_fn.clone();
826
827 self.builder =
828 self.builder
829 .listen(format!("actix-web-service-{}", addr), lst, move || {
830 let c = cfg.lock().unwrap();
831 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
832
833 let svc = HttpService::build()
834 .keep_alive(c.keep_alive)
835 .client_request_timeout(c.client_request_timeout)
836 .client_disconnect_timeout(c.client_disconnect_timeout);
837
838 let svc = if let Some(handler) = on_connect_fn.clone() {
839 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
840 } else {
841 svc
842 };
843
844 let fac = factory()
845 .into_factory()
846 .map_err(|err| err.into().error_response());
847
848 let acceptor_config = match c.tls_handshake_timeout {
849 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
850 None => TlsAcceptorConfig::default(),
851 };
852
853 svc.finish(map_config(fac, move |_| {
854 AppConfig::new(true, host.clone(), addr)
855 }))
856 .rustls_0_23_with_config(config.clone(), acceptor_config)
857 })?;
858
859 Ok(self)
860 }
861
862 #[cfg(feature = "openssl")]
868 pub fn listen_openssl(
869 self,
870 lst: net::TcpListener,
871 builder: SslAcceptorBuilder,
872 ) -> io::Result<Self> {
873 self.listen_openssl_inner(lst, openssl_acceptor(builder)?)
874 }
875
876 #[cfg(feature = "openssl")]
877 fn listen_openssl_inner(
878 mut self,
879 lst: net::TcpListener,
880 acceptor: SslAcceptor,
881 ) -> io::Result<Self> {
882 let factory = self.factory.clone();
883 let cfg = Arc::clone(&self.config);
884 let addr = lst.local_addr().unwrap();
885 self.sockets.push(Socket {
886 addr,
887 scheme: "https",
888 });
889
890 let on_connect_fn = self.on_connect_fn.clone();
891
892 self.builder =
893 self.builder
894 .listen(format!("actix-web-service-{}", addr), lst, move || {
895 let c = cfg.lock().unwrap();
896 let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
897
898 let svc = HttpService::build()
899 .keep_alive(c.keep_alive)
900 .client_request_timeout(c.client_request_timeout)
901 .client_disconnect_timeout(c.client_disconnect_timeout)
902 .local_addr(addr);
903
904 let svc = if let Some(handler) = on_connect_fn.clone() {
905 svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
906 } else {
907 svc
908 };
909
910 let fac = factory()
911 .into_factory()
912 .map_err(|err| err.into().error_response());
913
914 #[allow(clippy::significant_drop_in_scrutinee)]
916 let acceptor_config = match c.tls_handshake_timeout {
917 Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
918 None => TlsAcceptorConfig::default(),
919 };
920
921 svc.finish(map_config(fac, move |_| {
922 AppConfig::new(true, host.clone(), addr)
923 }))
924 .openssl_with_config(acceptor.clone(), acceptor_config)
925 })?;
926
927 Ok(self)
928 }
929
930 #[cfg(unix)]
932 pub fn bind_uds<A>(mut self, uds_path: A) -> io::Result<Self>
933 where
934 A: AsRef<std::path::Path>,
935 {
936 use actix_http::Protocol;
937 use actix_rt::net::UnixStream;
938 use actix_service::{fn_service, ServiceFactoryExt as _};
939
940 let cfg = Arc::clone(&self.config);
941 let factory = self.factory.clone();
942 let socket_addr =
943 net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
944
945 self.sockets.push(Socket {
946 scheme: "http",
947 addr: socket_addr,
948 });
949
950 self.builder = self.builder.bind_uds(
951 format!("actix-web-service-{:?}", uds_path.as_ref()),
952 uds_path,
953 move || {
954 let c = cfg.lock().unwrap();
955 let config = AppConfig::new(
956 false,
957 c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
958 socket_addr,
959 );
960
961 let fac = factory()
962 .into_factory()
963 .map_err(|err| err.into().error_response());
964
965 fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then(
966 HttpService::build()
967 .keep_alive(c.keep_alive)
968 .client_request_timeout(c.client_request_timeout)
969 .client_disconnect_timeout(c.client_disconnect_timeout)
970 .finish(map_config(fac, move |_| config.clone())),
971 )
972 },
973 )?;
974
975 Ok(self)
976 }
977
978 #[cfg(unix)]
980 pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
981 use actix_http::Protocol;
982 use actix_rt::net::UnixStream;
983 use actix_service::{fn_service, ServiceFactoryExt as _};
984
985 let cfg = Arc::clone(&self.config);
986 let factory = self.factory.clone();
987 let socket_addr =
988 net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
989 self.sockets.push(Socket {
990 scheme: "http",
991 addr: socket_addr,
992 });
993
994 let addr = lst.local_addr()?;
995 let name = format!("actix-web-service-{:?}", addr);
996 let on_connect_fn = self.on_connect_fn.clone();
997
998 self.builder = self.builder.listen_uds(name, lst, move || {
999 let c = cfg.lock().unwrap();
1000 let config = AppConfig::new(
1001 false,
1002 c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1003 socket_addr,
1004 );
1005
1006 fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1007 let mut svc = HttpService::build()
1008 .keep_alive(c.keep_alive)
1009 .client_request_timeout(c.client_request_timeout)
1010 .client_disconnect_timeout(c.client_disconnect_timeout);
1011
1012 if let Some(handler) = on_connect_fn.clone() {
1013 svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1014 }
1015
1016 let fac = factory()
1017 .into_factory()
1018 .map_err(|err| err.into().error_response());
1019
1020 svc.finish(map_config(fac, move |_| config.clone()))
1021 })
1022 })?;
1023 Ok(self)
1024 }
1025}
1026
1027impl<F, I, S, B> HttpServer<F, I, S, B>
1028where
1029 F: Fn() -> I + Send + Clone + 'static,
1030 I: IntoServiceFactory<S, Request>,
1031 S: ServiceFactory<Request, Config = AppConfig>,
1032 S::Error: Into<Error>,
1033 S::InitError: fmt::Debug,
1034 S::Response: Into<Response<B>>,
1035 S::Service: 'static,
1036 B: MessageBody,
1037{
1038 pub fn run(self) -> Server {
1051 self.builder.run()
1052 }
1053}
1054
1055fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
1057 let mut err = None;
1058 let mut success = false;
1059 let mut sockets = Vec::new();
1060
1061 for addr in addrs.to_socket_addrs()? {
1062 match create_tcp_listener(addr, backlog) {
1063 Ok(lst) => {
1064 success = true;
1065 sockets.push(lst);
1066 }
1067 Err(error) => err = Some(error),
1068 }
1069 }
1070
1071 if success {
1072 Ok(sockets)
1073 } else if let Some(err) = err.take() {
1074 Err(err)
1075 } else {
1076 Err(io::Error::new(
1077 io::ErrorKind::Other,
1078 "Can not bind to address.",
1079 ))
1080 }
1081}
1082
1083fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
1085 use socket2::{Domain, Protocol, Socket, Type};
1086 let domain = Domain::for_address(addr);
1087 let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
1088 #[cfg(not(windows))]
1089 {
1090 socket.set_reuse_address(true)?;
1091 }
1092 socket.bind(&addr.into())?;
1093 let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
1095 socket.listen(backlog)?;
1096 Ok(net::TcpListener::from(socket))
1097}
1098
1099#[cfg(feature = "openssl")]
1101fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
1102 builder.set_alpn_select_callback(|_, protocols| {
1103 const H2: &[u8] = b"\x02h2";
1104 const H11: &[u8] = b"\x08http/1.1";
1105
1106 if protocols.windows(3).any(|window| window == H2) {
1107 Ok(b"h2")
1108 } else if protocols.windows(9).any(|window| window == H11) {
1109 Ok(b"http/1.1")
1110 } else {
1111 Err(AlpnError::NOACK)
1112 }
1113 });
1114
1115 builder.set_alpn_protos(b"\x08http/1.1\x02h2")?;
1116
1117 Ok(builder.build())
1118}