Skip to main content

actix_web/
server.rs

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::{GracefulShutdownSignal, 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    tcp_nodelay: Option<bool>,
33    client_request_timeout: Duration,
34    client_disconnect_timeout: Duration,
35    h1_allow_half_closed: bool,
36    h1_write_buffer_size: Option<usize>,
37    h2_initial_window_size: Option<u32>,
38    h2_initial_connection_window_size: Option<u32>,
39    #[allow(dead_code)] // only dead when no TLS features are enabled
40    tls_handshake_timeout: Option<Duration>,
41}
42
43/// An HTTP Server.
44///
45/// Create new HTTP server with application factory.
46///
47/// # Automatic HTTP Version Selection
48///
49/// There are two ways to select the HTTP version of an incoming connection:
50///
51/// - One is to rely on the ALPN information that is provided when using a TLS (HTTPS); both
52///   versions are supported automatically when using either of the `.bind_rustls()` or
53///   `.bind_openssl()` methods.
54/// - The other is to read the first few bytes of the TCP stream. This is the only viable approach
55///   for supporting H2C, which allows the HTTP/2 protocol to work over plaintext connections. Use
56///   the `.bind_auto_h2c()` method to enable this behavior.
57///
58/// # Examples
59///
60/// ```no_run
61/// use actix_web::{web, App, HttpResponse, HttpServer};
62///
63/// #[actix_web::main]
64/// async fn main() -> std::io::Result<()> {
65///     HttpServer::new(|| {
66///         App::new()
67///             .service(web::resource("/").to(|| async { "hello world" }))
68///     })
69///     .bind(("127.0.0.1", 8080))?
70///     .run()
71///     .await
72/// }
73/// ```
74#[must_use]
75pub struct HttpServer<F, I, S, B>
76where
77    F: Fn() -> I + Send + Clone + 'static,
78    I: IntoServiceFactory<S, Request>,
79    S: ServiceFactory<Request, Config = AppConfig>,
80    S::Error: Into<Error>,
81    S::InitError: fmt::Debug,
82    S::Response: Into<Response<B>>,
83    B: MessageBody,
84{
85    pub(super) factory: F,
86    config: Arc<Mutex<Config>>,
87    backlog: u32,
88    sockets: Vec<Socket>,
89    builder: ServerBuilder,
90    graceful_shutdown_signal: GracefulShutdownSignal,
91    #[allow(clippy::type_complexity)]
92    on_connect_fn: Option<Arc<dyn Fn(&dyn Any, &mut Extensions) + Send + Sync>>,
93    _phantom: PhantomData<(S, B)>,
94}
95
96impl<F, I, S, B> HttpServer<F, I, S, B>
97where
98    F: Fn() -> I + Send + Clone + 'static,
99    I: IntoServiceFactory<S, Request>,
100
101    S: ServiceFactory<Request, Config = AppConfig> + 'static,
102    S::Error: Into<Error> + 'static,
103    S::InitError: fmt::Debug,
104    S::Response: Into<Response<B>> + 'static,
105    <S::Service as Service<Request>>::Future: 'static,
106    S::Service: 'static,
107
108    B: MessageBody + 'static,
109{
110    /// Create new HTTP server with application factory
111    ///
112    /// # Worker Count
113    ///
114    /// The `factory` will be instantiated multiple times in most configurations. See
115    /// [`bind()`](Self::bind()) docs for more on how worker count and bind address resolution
116    /// causes multiple server factory instantiations.
117    pub fn new(factory: F) -> Self {
118        let builder = ServerBuilder::default();
119        let graceful_shutdown_signal = builder.graceful_shutdown_signal();
120
121        HttpServer {
122            factory,
123            config: Arc::new(Mutex::new(Config {
124                host: None,
125                keep_alive: KeepAlive::default(),
126                tcp_nodelay: None,
127                client_request_timeout: Duration::from_secs(5),
128                client_disconnect_timeout: Duration::from_secs(1),
129                h1_allow_half_closed: true,
130                h1_write_buffer_size: None,
131                h2_initial_window_size: None,
132                h2_initial_connection_window_size: None,
133                tls_handshake_timeout: None,
134            })),
135            backlog: 1024,
136            sockets: Vec::new(),
137            builder,
138            graceful_shutdown_signal,
139            on_connect_fn: None,
140            _phantom: PhantomData,
141        }
142    }
143
144    /// Sets number of workers to start (per bind address).
145    ///
146    /// The default worker count is the determined by [`std::thread::available_parallelism()`]. See
147    /// its documentation to determine what behavior you should expect when server is run.
148    ///
149    /// Note that the server factory passed to [`new`](Self::new()) will be instantiated **at least
150    /// once per worker**. See [`bind()`](Self::bind()) docs for more on how worker count and bind
151    /// address resolution causes multiple server factory instantiations.
152    ///
153    /// `num` must be greater than 0.
154    ///
155    /// # Panics
156    ///
157    /// Panics if `num` is 0.
158    pub fn workers(mut self, num: usize) -> Self {
159        self.builder = self.builder.workers(num);
160        self
161    }
162
163    /// Sets server keep-alive preference.
164    ///
165    /// By default keep-alive is set to 5 seconds.
166    pub fn keep_alive<T: Into<KeepAlive>>(self, val: T) -> Self {
167        self.config.lock().unwrap().keep_alive = val.into();
168        self
169    }
170
171    /// Sets `TCP_NODELAY` value on accepted TCP connections.
172    ///
173    /// By default, accepted TCP connections keep the OS default.
174    /// This method overrides that behavior for all accepted TCP connections.
175    pub fn tcp_nodelay(self, enabled: bool) -> Self {
176        self.config.lock().unwrap().tcp_nodelay = Some(enabled);
177        self
178    }
179
180    /// Sets the maximum number of pending connections.
181    ///
182    /// This refers to the number of clients that can be waiting to be served. Exceeding this number
183    /// results in the client getting an error when attempting to connect. It should only affect
184    /// servers under significant load.
185    ///
186    /// Generally set in the 64–2048 range. Default value is 1024.
187    ///
188    /// This method will have no effect if called after a `bind()`.
189    pub fn backlog(mut self, backlog: u32) -> Self {
190        self.backlog = backlog;
191        self.builder = self.builder.backlog(backlog);
192        self
193    }
194
195    /// Sets the per-worker maximum number of concurrent connections.
196    ///
197    /// All socket listeners will stop accepting connections when this limit is reached for
198    /// each worker.
199    ///
200    /// By default max connections is set to a 25k.
201    pub fn max_connections(mut self, num: usize) -> Self {
202        self.builder = self.builder.max_concurrent_connections(num);
203        self
204    }
205
206    /// Sets the per-worker maximum concurrent TLS connection limit.
207    ///
208    /// All listeners will stop accepting connections when this limit is reached. It can be used to
209    /// limit the global TLS CPU usage.
210    ///
211    /// By default max connections is set to a 256.
212    #[allow(unused_variables)]
213    pub fn max_connection_rate(self, num: usize) -> Self {
214        #[cfg(feature = "__tls")]
215        actix_tls::accept::max_concurrent_tls_connect(num);
216        self
217    }
218
219    /// Sets max number of threads for each worker's blocking task thread pool.
220    ///
221    /// One thread pool is set up **per worker**; not shared across workers.
222    ///
223    /// By default, set to 512 divided by [available parallelism](std::thread::available_parallelism()).
224    pub fn worker_max_blocking_threads(mut self, num: usize) -> Self {
225        self.builder = self.builder.worker_max_blocking_threads(num);
226        self
227    }
228
229    /// Sets server client timeout for first request.
230    ///
231    /// Defines a timeout for reading client request head. If a client does not transmit the entire
232    /// set headers within this time, the request is terminated with a 408 (Request Timeout) error.
233    ///
234    /// To disable timeout set value to 0.
235    ///
236    /// By default client timeout is set to 5000 milliseconds.
237    pub fn client_request_timeout(self, dur: Duration) -> Self {
238        self.config.lock().unwrap().client_request_timeout = dur;
239        self
240    }
241
242    #[doc(hidden)]
243    #[deprecated(since = "4.0.0", note = "Renamed to `client_request_timeout`.")]
244    pub fn client_timeout(self, dur: Duration) -> Self {
245        self.client_request_timeout(dur)
246    }
247
248    /// Sets server connection shutdown timeout.
249    ///
250    /// Defines a timeout for connection shutdown. If a shutdown procedure does not complete within
251    /// this time, the request is dropped.
252    ///
253    /// To disable timeout set value to 0.
254    ///
255    /// By default client timeout is set to 1000 milliseconds.
256    pub fn client_disconnect_timeout(self, dur: Duration) -> Self {
257        self.config.lock().unwrap().client_disconnect_timeout = dur;
258        self
259    }
260
261    /// Sets TLS handshake timeout.
262    ///
263    /// Defines a timeout for TLS handshake. If the TLS handshake does not complete within this
264    /// time, the connection is closed.
265    ///
266    /// By default, the handshake timeout is 3 seconds.
267    #[cfg(feature = "__tls")]
268    pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
269        self.config
270            .lock()
271            .unwrap()
272            .tls_handshake_timeout
273            .replace(dur);
274
275        self
276    }
277
278    #[doc(hidden)]
279    #[deprecated(since = "4.0.0", note = "Renamed to `client_disconnect_timeout`.")]
280    pub fn client_shutdown(self, dur: u64) -> Self {
281        self.client_disconnect_timeout(Duration::from_millis(dur))
282    }
283
284    /// Sets whether HTTP/1 connections should support half-closures.
285    ///
286    /// Clients can choose to shutdown their writer-side of the connection after completing their
287    /// request and while waiting for the server response. Setting this to `false` will cause the
288    /// server to abort the connection handling as soon as it detects an EOF from the client.
289    ///
290    /// The default behavior is to allow, i.e. `true`
291    pub fn h1_allow_half_closed(self, allow: bool) -> Self {
292        self.config.lock().unwrap().h1_allow_half_closed = allow;
293        self
294    }
295
296    /// Sets the maximum response write buffer size for HTTP/1 connections.
297    ///
298    /// Once the response buffer reaches this size, the dispatcher flushes it to the I/O stream.
299    ///
300    /// The default value is 32 KiB.
301    ///
302    /// # Panics
303    ///
304    /// Panics if `size` is 0.
305    pub fn h1_write_buffer_size(self, size: usize) -> Self {
306        assert!(
307            size > 0,
308            "HTTP/1 write buffer size must be greater than zero"
309        );
310
311        self.config.lock().unwrap().h1_write_buffer_size = Some(size);
312        self
313    }
314
315    /// Sets initial stream-level flow control window size for HTTP/2 connections.
316    ///
317    /// Higher values can improve upload performance on high-latency links at the cost of higher
318    /// worst-case memory usage per connection.
319    ///
320    /// The default value is 1MiB.
321    #[cfg(feature = "http2")]
322    pub fn h2_initial_window_size(self, size: u32) -> Self {
323        self.config.lock().unwrap().h2_initial_window_size = Some(size);
324        self
325    }
326
327    /// Sets initial connection-level flow control window size for HTTP/2 connections.
328    ///
329    /// Higher values can improve upload performance on high-latency links at the cost of higher
330    /// worst-case memory usage per connection.
331    ///
332    /// The default value is 2MiB.
333    #[cfg(feature = "http2")]
334    pub fn h2_initial_connection_window_size(self, size: u32) -> Self {
335        self.config
336            .lock()
337            .unwrap()
338            .h2_initial_connection_window_size = Some(size);
339        self
340    }
341
342    /// Sets function that will be called once before each connection is handled.
343    ///
344    /// It will receive a `&std::any::Any`, which contains underlying connection type and an
345    /// [Extensions] container so that connection data can be accessed in middleware and handlers.
346    ///
347    /// # Connection Types
348    /// - `actix_tls::accept::openssl::TlsStream<actix_web::rt::net::TcpStream>` when using OpenSSL.
349    /// - `actix_tls::accept::rustls_0_20::TlsStream<actix_web::rt::net::TcpStream>` when using
350    ///   Rustls v0.20.
351    /// - `actix_tls::accept::rustls_0_21::TlsStream<actix_web::rt::net::TcpStream>` when using
352    ///   Rustls v0.21.
353    /// - `actix_tls::accept::rustls_0_22::TlsStream<actix_web::rt::net::TcpStream>` when using
354    ///   Rustls v0.22.
355    /// - `actix_tls::accept::rustls_0_23::TlsStream<actix_web::rt::net::TcpStream>` when using
356    ///   Rustls v0.23.
357    /// - `actix_web::rt::net::TcpStream` when no encryption is used.
358    ///
359    /// See the `on_connect` example for additional details.
360    pub fn on_connect<CB>(mut self, f: CB) -> HttpServer<F, I, S, B>
361    where
362        CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,
363    {
364        self.on_connect_fn = Some(Arc::new(f));
365        self
366    }
367
368    /// Sets server host name.
369    ///
370    /// Host name is used by application router as a hostname for url generation. Check
371    /// [`ConnectionInfo`](crate::dev::ConnectionInfo::host()) docs for more info.
372    ///
373    /// By default, hostname is set to "localhost".
374    pub fn server_hostname<T: AsRef<str>>(self, val: T) -> Self {
375        self.config.lock().unwrap().host = Some(val.as_ref().to_owned());
376        self
377    }
378
379    /// Flags the `System` to exit after server shutdown.
380    ///
381    /// Does nothing when running under `#[tokio::main]` runtime.
382    pub fn system_exit(mut self) -> Self {
383        self.builder = self.builder.system_exit();
384        self
385    }
386
387    /// Disables signal handling.
388    pub fn disable_signals(mut self) -> Self {
389        self.builder = self.builder.disable_signals();
390        self
391    }
392
393    /// Specify shutdown signal from a future.
394    ///
395    /// Using this method will prevent OS signal handlers being set up.
396    ///
397    /// Typically, a `CancellationToken` will be used, but any future _can_ be.
398    ///
399    /// # Examples
400    ///
401    /// ```no_run
402    /// use actix_web::{App, HttpServer};
403    /// use tokio_util::sync::CancellationToken;
404    ///
405    /// # #[actix_web::main]
406    /// # async fn main() -> std::io::Result<()> {
407    /// let stop_signal = CancellationToken::new();
408    ///
409    /// HttpServer::new(move || App::new())
410    ///     .shutdown_signal(stop_signal.cancelled_owned())
411    ///     .bind(("127.0.0.1", 8080))?
412    ///     .run()
413    ///     .await
414    /// # }
415    /// ```
416    pub fn shutdown_signal<Fut>(mut self, shutdown_signal: Fut) -> Self
417    where
418        Fut: Future<Output = ()> + Send + 'static,
419    {
420        self.builder = self.builder.shutdown_signal(shutdown_signal);
421        self
422    }
423
424    /// Sets timeout for graceful worker shutdown of workers.
425    ///
426    /// After receiving a stop signal, workers have this much time to finish serving requests.
427    /// Workers still alive after the timeout are force dropped.
428    ///
429    /// By default shutdown timeout sets to 30 seconds.
430    pub fn shutdown_timeout(mut self, sec: u64) -> Self {
431        self.builder = self.builder.shutdown_timeout(sec);
432        self
433    }
434
435    /// Returns addresses of bound sockets.
436    pub fn addrs(&self) -> Vec<net::SocketAddr> {
437        self.sockets.iter().map(|s| s.addr).collect()
438    }
439
440    /// Returns addresses of bound sockets and the scheme for it.
441    ///
442    /// This is useful when the server is bound from different sources with some sockets listening
443    /// on HTTP and some listening on HTTPS and the user should be presented with an enumeration of
444    /// which socket requires which protocol.
445    pub fn addrs_with_scheme(&self) -> Vec<(net::SocketAddr, &str)> {
446        self.sockets.iter().map(|s| (s.addr, s.scheme)).collect()
447    }
448
449    /// Resolves socket address(es) and binds server to created listener(s).
450    ///
451    /// # Hostname Resolution
452    ///
453    /// When `addrs` includes a hostname, it is possible for this method to bind to both the IPv4
454    /// and IPv6 addresses that result from a DNS lookup. You can test this by passing
455    /// `localhost:8080` and noting that the server binds to `127.0.0.1:8080` _and_ `[::1]:8080`. To
456    /// bind additional addresses, call this method multiple times.
457    ///
458    /// Note that, if a DNS lookup is required, resolving hostnames is a blocking operation.
459    ///
460    /// # Worker Count
461    ///
462    /// The `factory` will be instantiated multiple times in most scenarios. The number of
463    /// instantiations is number of [`workers`](Self::workers()) × number of sockets resolved by
464    /// `addrs`.
465    ///
466    /// For example, if you've manually set [`workers`](Self::workers()) to 2, and use `127.0.0.1`
467    /// as the bind `addrs`, then `factory` will be instantiated twice. However, using `localhost`
468    /// as the bind `addrs` can often resolve to both `127.0.0.1` (IPv4) _and_ `::1` (IPv6), causing
469    /// the `factory` to be instantiated 4 times (2 workers × 2 bind addresses).
470    ///
471    /// Using a bind address of `0.0.0.0`, which signals to use all interfaces, may also multiple
472    /// the number of instantiations in a similar way.
473    ///
474    /// # Dual-Stack IPv6
475    ///
476    /// On Windows, when this method creates an IPv6 listener (e.g., for `[::]:8080`), this
477    /// attempts to enable dual-stack mode so the socket can accept both IPv4 and IPv6
478    /// connections. On Linux and macOS, dual-stack is typically already the OS default. If you
479    /// need IPv6-only behavior on Windows, create the listener manually and pass it to
480    /// [`listen()`](Self::listen()).
481    ///
482    /// # Typical Usage
483    ///
484    /// In general, use `127.0.0.1:<port>` when testing locally and `0.0.0.0:<port>` when deploying
485    /// (with or without a reverse proxy or load balancer) so that the server is accessible.
486    ///
487    /// # Errors
488    ///
489    /// Returns an `io::Error` if:
490    /// - `addrs` cannot be resolved into one or more socket addresses;
491    /// - all the resolved socket addresses are already bound.
492    ///
493    /// # Example
494    ///
495    /// ```
496    /// # use actix_web::{App, HttpServer};
497    /// # fn inner() -> std::io::Result<()> {
498    /// HttpServer::new(|| App::new())
499    ///     .bind(("127.0.0.1", 8080))?
500    ///     .bind("[::1]:9000")?
501    /// # ; Ok(()) }
502    /// ```
503    pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
504        let sockets = bind_addrs(addrs, self.backlog)?;
505
506        for lst in sockets {
507            self = self.listen(lst)?;
508        }
509
510        Ok(self)
511    }
512
513    /// Resolves socket address(es) and binds server to created listener(s) for plaintext HTTP/1.x
514    /// or HTTP/2 connections.
515    ///
516    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
517    #[cfg(feature = "http2")]
518    pub fn bind_auto_h2c<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
519        let sockets = bind_addrs(addrs, self.backlog)?;
520
521        for lst in sockets {
522            self = self.listen_auto_h2c(lst)?;
523        }
524
525        Ok(self)
526    }
527
528    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
529    /// using Rustls v0.20.
530    ///
531    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
532    ///
533    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
534    #[cfg(feature = "rustls-0_20")]
535    pub fn bind_rustls<A: net::ToSocketAddrs>(
536        mut self,
537        addrs: A,
538        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
539    ) -> io::Result<Self> {
540        let sockets = bind_addrs(addrs, self.backlog)?;
541        for lst in sockets {
542            self = self.listen_rustls_0_20_inner(lst, config.clone())?;
543        }
544        Ok(self)
545    }
546
547    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
548    /// using Rustls v0.21.
549    ///
550    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
551    ///
552    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
553    #[cfg(feature = "rustls-0_21")]
554    pub fn bind_rustls_021<A: net::ToSocketAddrs>(
555        mut self,
556        addrs: A,
557        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
558    ) -> io::Result<Self> {
559        let sockets = bind_addrs(addrs, self.backlog)?;
560        for lst in sockets {
561            self = self.listen_rustls_0_21_inner(lst, config.clone())?;
562        }
563        Ok(self)
564    }
565
566    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
567    /// using Rustls v0.22.
568    ///
569    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
570    ///
571    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
572    #[cfg(feature = "rustls-0_22")]
573    pub fn bind_rustls_0_22<A: net::ToSocketAddrs>(
574        mut self,
575        addrs: A,
576        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
577    ) -> io::Result<Self> {
578        let sockets = bind_addrs(addrs, self.backlog)?;
579        for lst in sockets {
580            self = self.listen_rustls_0_22_inner(lst, config.clone())?;
581        }
582        Ok(self)
583    }
584
585    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
586    /// using Rustls v0.23.
587    ///
588    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
589    ///
590    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
591    #[cfg(feature = "rustls-0_23")]
592    pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
593        mut self,
594        addrs: A,
595        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
596    ) -> io::Result<Self> {
597        let sockets = bind_addrs(addrs, self.backlog)?;
598        for lst in sockets {
599            self = self.listen_rustls_0_23_inner(lst, config.clone())?;
600        }
601        Ok(self)
602    }
603
604    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
605    /// using OpenSSL.
606    ///
607    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
608    ///
609    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
610    #[cfg(feature = "openssl")]
611    pub fn bind_openssl<A>(mut self, addrs: A, builder: SslAcceptorBuilder) -> io::Result<Self>
612    where
613        A: net::ToSocketAddrs,
614    {
615        let sockets = bind_addrs(addrs, self.backlog)?;
616        let acceptor = openssl_acceptor(builder)?;
617
618        for lst in sockets {
619            self = self.listen_openssl_inner(lst, acceptor.clone())?;
620        }
621
622        Ok(self)
623    }
624
625    /// Binds to existing listener for accepting incoming connection requests.
626    ///
627    /// No changes are made to `lst`'s configuration. Ensure it is configured properly before
628    /// passing ownership to `listen()`.
629    pub fn listen(mut self, lst: net::TcpListener) -> io::Result<Self> {
630        let cfg = Arc::clone(&self.config);
631        let factory = self.factory.clone();
632        let addr = lst.local_addr().unwrap();
633
634        self.sockets.push(Socket {
635            addr,
636            scheme: "http",
637        });
638
639        let on_connect_fn = self.on_connect_fn.clone();
640        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
641
642        self.builder =
643            self.builder
644                .listen(format!("actix-web-service-{}", addr), lst, move || {
645                    let cfg = cfg.lock().unwrap();
646                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
647                    let shutdown_signal = graceful_shutdown_signal.clone();
648
649                    let mut svc = HttpService::build()
650                        .graceful_shutdown_signal(move || {
651                            let signal = shutdown_signal.clone();
652                            async move { signal.notified().await }
653                        })
654                        .keep_alive(cfg.keep_alive)
655                        .client_request_timeout(cfg.client_request_timeout)
656                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
657                        .h1_allow_half_closed(cfg.h1_allow_half_closed)
658                        .local_addr(addr);
659
660                    if let Some(enabled) = cfg.tcp_nodelay {
661                        svc = svc.tcp_nodelay(enabled);
662                    }
663
664                    if let Some(size) = cfg.h1_write_buffer_size {
665                        svc = svc.h1_write_buffer_size(size);
666                    }
667
668                    if let Some(val) = cfg.h2_initial_window_size {
669                        svc = svc.h2_initial_window_size(val);
670                    }
671
672                    if let Some(val) = cfg.h2_initial_connection_window_size {
673                        svc = svc.h2_initial_connection_window_size(val);
674                    }
675
676                    if let Some(handler) = on_connect_fn.clone() {
677                        svc =
678                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
679                    };
680
681                    let fac = factory()
682                        .into_factory()
683                        .map_err(|err| err.into().error_response());
684
685                    svc.finish(map_config(fac, move |_| {
686                        AppConfig::new(false, host.clone(), addr)
687                    }))
688                    .tcp()
689                })?;
690
691        Ok(self)
692    }
693
694    /// Binds to existing listener for accepting incoming plaintext HTTP/1.x or HTTP/2 connections.
695    #[cfg(feature = "http2")]
696    pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result<Self> {
697        let cfg = Arc::clone(&self.config);
698        let factory = self.factory.clone();
699        let addr = lst.local_addr().unwrap();
700
701        self.sockets.push(Socket {
702            addr,
703            scheme: "http",
704        });
705
706        let on_connect_fn = self.on_connect_fn.clone();
707        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
708
709        self.builder =
710            self.builder
711                .listen(format!("actix-web-service-{}", addr), lst, move || {
712                    let cfg = cfg.lock().unwrap();
713                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
714                    let shutdown_signal = graceful_shutdown_signal.clone();
715
716                    let mut svc = HttpService::build()
717                        .graceful_shutdown_signal(move || {
718                            let signal = shutdown_signal.clone();
719                            async move { signal.notified().await }
720                        })
721                        .keep_alive(cfg.keep_alive)
722                        .client_request_timeout(cfg.client_request_timeout)
723                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
724                        .h1_allow_half_closed(cfg.h1_allow_half_closed)
725                        .local_addr(addr);
726
727                    if let Some(enabled) = cfg.tcp_nodelay {
728                        svc = svc.tcp_nodelay(enabled);
729                    }
730
731                    if let Some(size) = cfg.h1_write_buffer_size {
732                        svc = svc.h1_write_buffer_size(size);
733                    }
734
735                    if let Some(val) = cfg.h2_initial_window_size {
736                        svc = svc.h2_initial_window_size(val);
737                    }
738
739                    if let Some(val) = cfg.h2_initial_connection_window_size {
740                        svc = svc.h2_initial_connection_window_size(val);
741                    }
742
743                    if let Some(handler) = on_connect_fn.clone() {
744                        svc =
745                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
746                    };
747
748                    let fac = factory()
749                        .into_factory()
750                        .map_err(|err| err.into().error_response());
751
752                    svc.finish(map_config(fac, move |_| {
753                        AppConfig::new(false, host.clone(), addr)
754                    }))
755                    .tcp_auto_h2c()
756                })?;
757
758        Ok(self)
759    }
760
761    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
762    /// v0.20.
763    ///
764    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
765    ///
766    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
767    #[cfg(feature = "rustls-0_20")]
768    pub fn listen_rustls(
769        self,
770        lst: net::TcpListener,
771        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
772    ) -> io::Result<Self> {
773        self.listen_rustls_0_20_inner(lst, config)
774    }
775
776    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
777    /// v0.21.
778    ///
779    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
780    ///
781    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
782    #[cfg(feature = "rustls-0_21")]
783    pub fn listen_rustls_0_21(
784        self,
785        lst: net::TcpListener,
786        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
787    ) -> io::Result<Self> {
788        self.listen_rustls_0_21_inner(lst, config)
789    }
790
791    #[cfg(feature = "rustls-0_20")]
792    fn listen_rustls_0_20_inner(
793        mut self,
794        lst: net::TcpListener,
795        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
796    ) -> io::Result<Self> {
797        let factory = self.factory.clone();
798        let cfg = Arc::clone(&self.config);
799        let addr = lst.local_addr().unwrap();
800        self.sockets.push(Socket {
801            addr,
802            scheme: "https",
803        });
804
805        let on_connect_fn = self.on_connect_fn.clone();
806        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
807
808        self.builder =
809            self.builder
810                .listen(format!("actix-web-service-{}", addr), lst, move || {
811                    let c = cfg.lock().unwrap();
812                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
813                    let shutdown_signal = graceful_shutdown_signal.clone();
814
815                    let mut svc = HttpService::build()
816                        .graceful_shutdown_signal(move || {
817                            let signal = shutdown_signal.clone();
818                            async move { signal.notified().await }
819                        })
820                        .keep_alive(c.keep_alive)
821                        .client_request_timeout(c.client_request_timeout)
822                        .h1_allow_half_closed(c.h1_allow_half_closed)
823                        .client_disconnect_timeout(c.client_disconnect_timeout);
824
825                    if let Some(enabled) = c.tcp_nodelay {
826                        svc = svc.tcp_nodelay(enabled);
827                    }
828
829                    if let Some(size) = c.h1_write_buffer_size {
830                        svc = svc.h1_write_buffer_size(size);
831                    }
832
833                    if let Some(val) = c.h2_initial_window_size {
834                        svc = svc.h2_initial_window_size(val);
835                    }
836
837                    if let Some(val) = c.h2_initial_connection_window_size {
838                        svc = svc.h2_initial_connection_window_size(val);
839                    }
840
841                    if let Some(handler) = on_connect_fn.clone() {
842                        svc = svc
843                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
844                    };
845
846                    let fac = factory()
847                        .into_factory()
848                        .map_err(|err| err.into().error_response());
849
850                    let acceptor_config = match c.tls_handshake_timeout {
851                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
852                        None => TlsAcceptorConfig::default(),
853                    };
854
855                    svc.finish(map_config(fac, move |_| {
856                        AppConfig::new(true, host.clone(), addr)
857                    }))
858                    .rustls_with_config(config.clone(), acceptor_config)
859                })?;
860
861        Ok(self)
862    }
863
864    #[cfg(feature = "rustls-0_21")]
865    fn listen_rustls_0_21_inner(
866        mut self,
867        lst: net::TcpListener,
868        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
869    ) -> io::Result<Self> {
870        let factory = self.factory.clone();
871        let cfg = Arc::clone(&self.config);
872        let addr = lst.local_addr().unwrap();
873        self.sockets.push(Socket {
874            addr,
875            scheme: "https",
876        });
877
878        let on_connect_fn = self.on_connect_fn.clone();
879        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
880
881        self.builder =
882            self.builder
883                .listen(format!("actix-web-service-{}", addr), lst, move || {
884                    let c = cfg.lock().unwrap();
885                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
886                    let shutdown_signal = graceful_shutdown_signal.clone();
887
888                    let mut svc = HttpService::build()
889                        .graceful_shutdown_signal(move || {
890                            let signal = shutdown_signal.clone();
891                            async move { signal.notified().await }
892                        })
893                        .keep_alive(c.keep_alive)
894                        .client_request_timeout(c.client_request_timeout)
895                        .h1_allow_half_closed(c.h1_allow_half_closed)
896                        .client_disconnect_timeout(c.client_disconnect_timeout);
897
898                    if let Some(enabled) = c.tcp_nodelay {
899                        svc = svc.tcp_nodelay(enabled);
900                    }
901
902                    if let Some(size) = c.h1_write_buffer_size {
903                        svc = svc.h1_write_buffer_size(size);
904                    }
905
906                    if let Some(val) = c.h2_initial_window_size {
907                        svc = svc.h2_initial_window_size(val);
908                    }
909
910                    if let Some(val) = c.h2_initial_connection_window_size {
911                        svc = svc.h2_initial_connection_window_size(val);
912                    }
913
914                    if let Some(handler) = on_connect_fn.clone() {
915                        svc = svc
916                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
917                    };
918
919                    let fac = factory()
920                        .into_factory()
921                        .map_err(|err| err.into().error_response());
922
923                    let acceptor_config = match c.tls_handshake_timeout {
924                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
925                        None => TlsAcceptorConfig::default(),
926                    };
927
928                    svc.finish(map_config(fac, move |_| {
929                        AppConfig::new(true, host.clone(), addr)
930                    }))
931                    .rustls_021_with_config(config.clone(), acceptor_config)
932                })?;
933
934        Ok(self)
935    }
936
937    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
938    /// v0.22.
939    ///
940    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
941    ///
942    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
943    #[cfg(feature = "rustls-0_22")]
944    pub fn listen_rustls_0_22(
945        self,
946        lst: net::TcpListener,
947        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
948    ) -> io::Result<Self> {
949        self.listen_rustls_0_22_inner(lst, config)
950    }
951
952    #[cfg(feature = "rustls-0_22")]
953    fn listen_rustls_0_22_inner(
954        mut self,
955        lst: net::TcpListener,
956        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
957    ) -> io::Result<Self> {
958        let factory = self.factory.clone();
959        let cfg = Arc::clone(&self.config);
960        let addr = lst.local_addr().unwrap();
961        self.sockets.push(Socket {
962            addr,
963            scheme: "https",
964        });
965
966        let on_connect_fn = self.on_connect_fn.clone();
967        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
968
969        self.builder =
970            self.builder
971                .listen(format!("actix-web-service-{}", addr), lst, move || {
972                    let c = cfg.lock().unwrap();
973                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
974                    let shutdown_signal = graceful_shutdown_signal.clone();
975
976                    let mut svc = HttpService::build()
977                        .graceful_shutdown_signal(move || {
978                            let signal = shutdown_signal.clone();
979                            async move { signal.notified().await }
980                        })
981                        .keep_alive(c.keep_alive)
982                        .client_request_timeout(c.client_request_timeout)
983                        .h1_allow_half_closed(c.h1_allow_half_closed)
984                        .client_disconnect_timeout(c.client_disconnect_timeout);
985
986                    if let Some(enabled) = c.tcp_nodelay {
987                        svc = svc.tcp_nodelay(enabled);
988                    }
989
990                    if let Some(size) = c.h1_write_buffer_size {
991                        svc = svc.h1_write_buffer_size(size);
992                    }
993
994                    if let Some(val) = c.h2_initial_window_size {
995                        svc = svc.h2_initial_window_size(val);
996                    }
997
998                    if let Some(val) = c.h2_initial_connection_window_size {
999                        svc = svc.h2_initial_connection_window_size(val);
1000                    }
1001
1002                    if let Some(handler) = on_connect_fn.clone() {
1003                        svc = svc
1004                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1005                    };
1006
1007                    let fac = factory()
1008                        .into_factory()
1009                        .map_err(|err| err.into().error_response());
1010
1011                    let acceptor_config = match c.tls_handshake_timeout {
1012                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1013                        None => TlsAcceptorConfig::default(),
1014                    };
1015
1016                    svc.finish(map_config(fac, move |_| {
1017                        AppConfig::new(true, host.clone(), addr)
1018                    }))
1019                    .rustls_0_22_with_config(config.clone(), acceptor_config)
1020                })?;
1021
1022        Ok(self)
1023    }
1024
1025    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
1026    /// v0.23.
1027    ///
1028    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
1029    ///
1030    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
1031    #[cfg(feature = "rustls-0_23")]
1032    pub fn listen_rustls_0_23(
1033        self,
1034        lst: net::TcpListener,
1035        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
1036    ) -> io::Result<Self> {
1037        self.listen_rustls_0_23_inner(lst, config)
1038    }
1039
1040    #[cfg(feature = "rustls-0_23")]
1041    fn listen_rustls_0_23_inner(
1042        mut self,
1043        lst: net::TcpListener,
1044        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
1045    ) -> io::Result<Self> {
1046        let factory = self.factory.clone();
1047        let cfg = Arc::clone(&self.config);
1048        let addr = lst.local_addr().unwrap();
1049        self.sockets.push(Socket {
1050            addr,
1051            scheme: "https",
1052        });
1053
1054        let on_connect_fn = self.on_connect_fn.clone();
1055        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1056
1057        self.builder =
1058            self.builder
1059                .listen(format!("actix-web-service-{}", addr), lst, move || {
1060                    let c = cfg.lock().unwrap();
1061                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
1062                    let shutdown_signal = graceful_shutdown_signal.clone();
1063
1064                    let mut svc = HttpService::build()
1065                        .graceful_shutdown_signal(move || {
1066                            let signal = shutdown_signal.clone();
1067                            async move { signal.notified().await }
1068                        })
1069                        .keep_alive(c.keep_alive)
1070                        .client_request_timeout(c.client_request_timeout)
1071                        .h1_allow_half_closed(c.h1_allow_half_closed)
1072                        .client_disconnect_timeout(c.client_disconnect_timeout);
1073
1074                    if let Some(enabled) = c.tcp_nodelay {
1075                        svc = svc.tcp_nodelay(enabled);
1076                    }
1077
1078                    if let Some(size) = c.h1_write_buffer_size {
1079                        svc = svc.h1_write_buffer_size(size);
1080                    }
1081
1082                    if let Some(val) = c.h2_initial_window_size {
1083                        svc = svc.h2_initial_window_size(val);
1084                    }
1085
1086                    if let Some(val) = c.h2_initial_connection_window_size {
1087                        svc = svc.h2_initial_connection_window_size(val);
1088                    }
1089
1090                    if let Some(handler) = on_connect_fn.clone() {
1091                        svc = svc
1092                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1093                    };
1094
1095                    let fac = factory()
1096                        .into_factory()
1097                        .map_err(|err| err.into().error_response());
1098
1099                    let acceptor_config = match c.tls_handshake_timeout {
1100                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1101                        None => TlsAcceptorConfig::default(),
1102                    };
1103
1104                    svc.finish(map_config(fac, move |_| {
1105                        AppConfig::new(true, host.clone(), addr)
1106                    }))
1107                    .rustls_0_23_with_config(config.clone(), acceptor_config)
1108                })?;
1109
1110        Ok(self)
1111    }
1112
1113    /// Binds to existing listener for accepting incoming TLS connection requests using OpenSSL.
1114    ///
1115    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
1116    ///
1117    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
1118    #[cfg(feature = "openssl")]
1119    pub fn listen_openssl(
1120        self,
1121        lst: net::TcpListener,
1122        builder: SslAcceptorBuilder,
1123    ) -> io::Result<Self> {
1124        self.listen_openssl_inner(lst, openssl_acceptor(builder)?)
1125    }
1126
1127    #[cfg(feature = "openssl")]
1128    fn listen_openssl_inner(
1129        mut self,
1130        lst: net::TcpListener,
1131        acceptor: SslAcceptor,
1132    ) -> io::Result<Self> {
1133        let factory = self.factory.clone();
1134        let cfg = Arc::clone(&self.config);
1135        let addr = lst.local_addr().unwrap();
1136
1137        self.sockets.push(Socket {
1138            addr,
1139            scheme: "https",
1140        });
1141
1142        let on_connect_fn = self.on_connect_fn.clone();
1143        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1144
1145        self.builder =
1146            self.builder
1147                .listen(format!("actix-web-service-{}", addr), lst, move || {
1148                    let c = cfg.lock().unwrap();
1149                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
1150                    let shutdown_signal = graceful_shutdown_signal.clone();
1151
1152                    let mut svc = HttpService::build()
1153                        .graceful_shutdown_signal(move || {
1154                            let signal = shutdown_signal.clone();
1155                            async move { signal.notified().await }
1156                        })
1157                        .keep_alive(c.keep_alive)
1158                        .client_request_timeout(c.client_request_timeout)
1159                        .client_disconnect_timeout(c.client_disconnect_timeout)
1160                        .h1_allow_half_closed(c.h1_allow_half_closed)
1161                        .local_addr(addr);
1162
1163                    if let Some(enabled) = c.tcp_nodelay {
1164                        svc = svc.tcp_nodelay(enabled);
1165                    }
1166
1167                    if let Some(size) = c.h1_write_buffer_size {
1168                        svc = svc.h1_write_buffer_size(size);
1169                    }
1170
1171                    if let Some(val) = c.h2_initial_window_size {
1172                        svc = svc.h2_initial_window_size(val);
1173                    }
1174
1175                    if let Some(val) = c.h2_initial_connection_window_size {
1176                        svc = svc.h2_initial_connection_window_size(val);
1177                    }
1178
1179                    if let Some(handler) = on_connect_fn.clone() {
1180                        svc = svc
1181                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1182                    };
1183
1184                    let fac = factory()
1185                        .into_factory()
1186                        .map_err(|err| err.into().error_response());
1187
1188                    // false positive lint (?)
1189                    #[allow(clippy::significant_drop_in_scrutinee)]
1190                    let acceptor_config = match c.tls_handshake_timeout {
1191                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1192                        None => TlsAcceptorConfig::default(),
1193                    };
1194
1195                    svc.finish(map_config(fac, move |_| {
1196                        AppConfig::new(true, host.clone(), addr)
1197                    }))
1198                    .openssl_with_config(acceptor.clone(), acceptor_config)
1199                })?;
1200
1201        Ok(self)
1202    }
1203
1204    /// Opens Unix Domain Socket (UDS) from `uds` path and binds server to created listener.
1205    #[cfg(unix)]
1206    pub fn bind_uds<A>(mut self, uds_path: A) -> io::Result<Self>
1207    where
1208        A: AsRef<std::path::Path>,
1209    {
1210        use actix_http::Protocol;
1211        use actix_rt::net::UnixStream;
1212        use actix_service::{fn_service, ServiceFactoryExt as _};
1213
1214        let cfg = Arc::clone(&self.config);
1215        let factory = self.factory.clone();
1216        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1217        let socket_addr =
1218            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1219
1220        self.sockets.push(Socket {
1221            scheme: "http",
1222            addr: socket_addr,
1223        });
1224
1225        self.builder = self.builder.bind_uds(
1226            format!("actix-web-service-{:?}", uds_path.as_ref()),
1227            uds_path,
1228            move || {
1229                let c = cfg.lock().unwrap();
1230                let config = AppConfig::new(
1231                    false,
1232                    c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1233                    socket_addr,
1234                );
1235
1236                let fac = factory()
1237                    .into_factory()
1238                    .map_err(|err| err.into().error_response());
1239
1240                fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1241                    let shutdown_signal = graceful_shutdown_signal.clone();
1242                    let mut svc = HttpService::build()
1243                        .graceful_shutdown_signal(move || {
1244                            let signal = shutdown_signal.clone();
1245                            async move { signal.notified().await }
1246                        })
1247                        .keep_alive(c.keep_alive)
1248                        .client_request_timeout(c.client_request_timeout)
1249                        .client_disconnect_timeout(c.client_disconnect_timeout)
1250                        .h1_allow_half_closed(c.h1_allow_half_closed);
1251
1252                    if let Some(size) = c.h1_write_buffer_size {
1253                        svc = svc.h1_write_buffer_size(size);
1254                    }
1255
1256                    svc.finish(map_config(fac, move |_| config.clone()))
1257                })
1258            },
1259        )?;
1260
1261        Ok(self)
1262    }
1263
1264    /// Binds to existing Unix Domain Socket (UDS) listener.
1265    #[cfg(unix)]
1266    pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
1267        use actix_http::Protocol;
1268        use actix_rt::net::UnixStream;
1269        use actix_service::{fn_service, ServiceFactoryExt as _};
1270
1271        let cfg = Arc::clone(&self.config);
1272        let factory = self.factory.clone();
1273        let socket_addr =
1274            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1275
1276        self.sockets.push(Socket {
1277            scheme: "http",
1278            addr: socket_addr,
1279        });
1280
1281        let addr = lst.local_addr()?;
1282        let name = format!("actix-web-service-{:?}", addr);
1283        let on_connect_fn = self.on_connect_fn.clone();
1284        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1285
1286        self.builder = self.builder.listen_uds(name, lst, move || {
1287            let c = cfg.lock().unwrap();
1288            let config = AppConfig::new(
1289                false,
1290                c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1291                socket_addr,
1292            );
1293
1294            fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1295                let shutdown_signal = graceful_shutdown_signal.clone();
1296                let mut svc = HttpService::build()
1297                    .graceful_shutdown_signal(move || {
1298                        let signal = shutdown_signal.clone();
1299                        async move { signal.notified().await }
1300                    })
1301                    .keep_alive(c.keep_alive)
1302                    .client_request_timeout(c.client_request_timeout)
1303                    .h1_allow_half_closed(c.h1_allow_half_closed)
1304                    .client_disconnect_timeout(c.client_disconnect_timeout);
1305
1306                if let Some(handler) = on_connect_fn.clone() {
1307                    svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1308                }
1309
1310                if let Some(size) = c.h1_write_buffer_size {
1311                    svc = svc.h1_write_buffer_size(size);
1312                }
1313
1314                let fac = factory()
1315                    .into_factory()
1316                    .map_err(|err| err.into().error_response());
1317
1318                svc.finish(map_config(fac, move |_| config.clone()))
1319            })
1320        })?;
1321        Ok(self)
1322    }
1323}
1324
1325impl<F, I, S, B> HttpServer<F, I, S, B>
1326where
1327    F: Fn() -> I + Send + Clone + 'static,
1328    I: IntoServiceFactory<S, Request>,
1329    S: ServiceFactory<Request, Config = AppConfig>,
1330    S::Error: Into<Error>,
1331    S::InitError: fmt::Debug,
1332    S::Response: Into<Response<B>>,
1333    S::Service: 'static,
1334    B: MessageBody,
1335{
1336    /// Start listening for incoming connections.
1337    ///
1338    /// # Workers
1339    /// This method starts a number of HTTP workers in separate threads. The number of workers in a
1340    /// set is defined by [`workers()`](Self::workers) or, by default, the number of the machine's
1341    /// physical cores. One worker set is created for each socket address to be bound. For example,
1342    /// if workers is set to 4, and there are 2 addresses to bind, then 8 worker threads will be
1343    /// spawned.
1344    ///
1345    /// # Panics
1346    /// This methods panics if no socket addresses were successfully bound or if no Tokio runtime
1347    /// is set up.
1348    pub fn run(self) -> Server {
1349        self.builder.run()
1350    }
1351}
1352
1353/// Bind TCP listeners to socket addresses resolved from `addrs` with options.
1354fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
1355    let mut err = None;
1356    let mut success = false;
1357    let mut sockets = Vec::new();
1358
1359    for addr in addrs.to_socket_addrs()? {
1360        match create_tcp_listener(addr, backlog) {
1361            Ok(lst) => {
1362                success = true;
1363                sockets.push(lst);
1364            }
1365            Err(error) => err = Some(error),
1366        }
1367    }
1368
1369    if success {
1370        Ok(sockets)
1371    } else if let Some(err) = err.take() {
1372        Err(err)
1373    } else {
1374        Err(io::Error::other("Could not bind to address"))
1375    }
1376}
1377
1378/// Creates a TCP listener from socket address and options.
1379fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
1380    use socket2::{Domain, Protocol, Socket, Type};
1381    let domain = Domain::for_address(addr);
1382    let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
1383    #[cfg(not(windows))]
1384    {
1385        socket.set_reuse_address(true)?;
1386    }
1387    // On Windows, IPV6_V6ONLY defaults to true, preventing IPv6 sockets from accepting IPv4
1388    // connections. Set it to false so that binding to [::] also accepts IPv4 traffic.
1389    #[cfg(windows)]
1390    if addr.is_ipv6() {
1391        if let Err(err) = socket.set_only_v6(false) {
1392            log::warn!("failed to set IPV6_V6ONLY=false: {err}");
1393        }
1394    }
1395    socket.bind(&addr.into())?;
1396    // clamp backlog to max u32 that fits in i32 range
1397    let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
1398    socket.listen(backlog)?;
1399    Ok(net::TcpListener::from(socket))
1400}
1401
1402/// Configures OpenSSL acceptor `builder` with ALPN protocols.
1403#[cfg(feature = "openssl")]
1404fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
1405    builder.set_alpn_select_callback(|_, protocols| {
1406        const H2: &[u8] = b"\x02h2";
1407        const H11: &[u8] = b"\x08http/1.1";
1408
1409        if protocols.windows(3).any(|window| window == H2) {
1410            Ok(b"h2")
1411        } else if protocols.windows(9).any(|window| window == H11) {
1412            Ok(b"http/1.1")
1413        } else {
1414            Err(AlpnError::NOACK)
1415        }
1416    });
1417
1418    builder.set_alpn_protos(b"\x08http/1.1\x02h2")?;
1419
1420    Ok(builder.build())
1421}