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); HTTP/1.x is
52///   always supported, and HTTP/2 is supported when the `http2` feature is enabled. Use either of
53///   the `.bind_rustls()` or `.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    /// # Call Order
348    /// The callback is captured when a listener is bound, so this must be called **before**
349    /// [`bind()`](Self::bind()) (or any other `bind_*`/`listen_*` method). Calling it afterwards
350    /// has no effect on the already-bound listeners.
351    ///
352    /// # Connection Types
353    /// - `actix_tls::accept::openssl::TlsStream<actix_web::rt::net::TcpStream>` when using OpenSSL.
354    /// - `actix_tls::accept::rustls_0_20::TlsStream<actix_web::rt::net::TcpStream>` when using
355    ///   Rustls v0.20.
356    /// - `actix_tls::accept::rustls_0_21::TlsStream<actix_web::rt::net::TcpStream>` when using
357    ///   Rustls v0.21.
358    /// - `actix_tls::accept::rustls_0_22::TlsStream<actix_web::rt::net::TcpStream>` when using
359    ///   Rustls v0.22.
360    /// - `actix_tls::accept::rustls_0_23::TlsStream<actix_web::rt::net::TcpStream>` when using
361    ///   Rustls v0.23.
362    /// - `actix_web::rt::net::TcpStream` when no encryption is used.
363    ///
364    /// See the `on_connect` example for additional details.
365    pub fn on_connect<CB>(mut self, f: CB) -> HttpServer<F, I, S, B>
366    where
367        CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,
368    {
369        self.on_connect_fn = Some(Arc::new(f));
370        self
371    }
372
373    /// Sets server host name.
374    ///
375    /// Host name is used by application router as a hostname for url generation. Check
376    /// [`ConnectionInfo`](crate::dev::ConnectionInfo::host()) docs for more info.
377    ///
378    /// By default, hostname is set to "localhost".
379    pub fn server_hostname<T: AsRef<str>>(self, val: T) -> Self {
380        self.config.lock().unwrap().host = Some(val.as_ref().to_owned());
381        self
382    }
383
384    /// Flags the `System` to exit after server shutdown.
385    ///
386    /// Does nothing when running under `#[tokio::main]` runtime.
387    pub fn system_exit(mut self) -> Self {
388        self.builder = self.builder.system_exit();
389        self
390    }
391
392    /// Disables signal handling.
393    pub fn disable_signals(mut self) -> Self {
394        self.builder = self.builder.disable_signals();
395        self
396    }
397
398    /// Specify shutdown signal from a future.
399    ///
400    /// Using this method will prevent OS signal handlers being set up.
401    ///
402    /// Typically, a `CancellationToken` will be used, but any future _can_ be.
403    ///
404    /// # Examples
405    ///
406    /// ```no_run
407    /// use actix_web::{App, HttpServer};
408    /// use tokio_util::sync::CancellationToken;
409    ///
410    /// # #[actix_web::main]
411    /// # async fn main() -> std::io::Result<()> {
412    /// let stop_signal = CancellationToken::new();
413    ///
414    /// HttpServer::new(move || App::new())
415    ///     .shutdown_signal(stop_signal.cancelled_owned())
416    ///     .bind(("127.0.0.1", 8080))?
417    ///     .run()
418    ///     .await
419    /// # }
420    /// ```
421    pub fn shutdown_signal<Fut>(mut self, shutdown_signal: Fut) -> Self
422    where
423        Fut: Future<Output = ()> + Send + 'static,
424    {
425        self.builder = self.builder.shutdown_signal(shutdown_signal);
426        self
427    }
428
429    /// Sets timeout for graceful worker shutdown of workers.
430    ///
431    /// After receiving a stop signal, workers have this much time to finish serving requests.
432    /// Workers still alive after the timeout are force dropped.
433    ///
434    /// By default shutdown timeout sets to 30 seconds.
435    pub fn shutdown_timeout(mut self, sec: u64) -> Self {
436        self.builder = self.builder.shutdown_timeout(sec);
437        self
438    }
439
440    /// Returns addresses of bound sockets.
441    pub fn addrs(&self) -> Vec<net::SocketAddr> {
442        self.sockets.iter().map(|s| s.addr).collect()
443    }
444
445    /// Returns addresses of bound sockets and the scheme for it.
446    ///
447    /// This is useful when the server is bound from different sources with some sockets listening
448    /// on HTTP and some listening on HTTPS and the user should be presented with an enumeration of
449    /// which socket requires which protocol.
450    pub fn addrs_with_scheme(&self) -> Vec<(net::SocketAddr, &str)> {
451        self.sockets.iter().map(|s| (s.addr, s.scheme)).collect()
452    }
453
454    /// Resolves socket address(es) and binds server to created listener(s).
455    ///
456    /// # Hostname Resolution
457    ///
458    /// When `addrs` includes a hostname, it is possible for this method to bind to both the IPv4
459    /// and IPv6 addresses that result from a DNS lookup. You can test this by passing
460    /// `localhost:8080` and noting that the server binds to `127.0.0.1:8080` _and_ `[::1]:8080`. To
461    /// bind additional addresses, call this method multiple times.
462    ///
463    /// Note that, if a DNS lookup is required, resolving hostnames is a blocking operation.
464    ///
465    /// # Worker Count
466    ///
467    /// The `factory` will be instantiated multiple times in most scenarios. The number of
468    /// instantiations is number of [`workers`](Self::workers()) × number of sockets resolved by
469    /// `addrs`.
470    ///
471    /// For example, if you've manually set [`workers`](Self::workers()) to 2, and use `127.0.0.1`
472    /// as the bind `addrs`, then `factory` will be instantiated twice. However, using `localhost`
473    /// as the bind `addrs` can often resolve to both `127.0.0.1` (IPv4) _and_ `::1` (IPv6), causing
474    /// the `factory` to be instantiated 4 times (2 workers × 2 bind addresses).
475    ///
476    /// Using a bind address of `0.0.0.0`, which signals to use all interfaces, may also multiple
477    /// the number of instantiations in a similar way.
478    ///
479    /// # Dual-Stack IPv6
480    ///
481    /// On Windows, when this method creates an IPv6 listener (e.g., for `[::]:8080`), this
482    /// attempts to enable dual-stack mode so the socket can accept both IPv4 and IPv6
483    /// connections. On Linux and macOS, dual-stack is typically already the OS default. If you
484    /// need IPv6-only behavior on Windows, create the listener manually and pass it to
485    /// [`listen()`](Self::listen()).
486    ///
487    /// # Typical Usage
488    ///
489    /// In general, use `127.0.0.1:<port>` when testing locally and `0.0.0.0:<port>` when deploying
490    /// (with or without a reverse proxy or load balancer) so that the server is accessible.
491    ///
492    /// # Errors
493    ///
494    /// Returns an `io::Error` if:
495    /// - `addrs` cannot be resolved into one or more socket addresses;
496    /// - all the resolved socket addresses are already bound.
497    ///
498    /// # Example
499    ///
500    /// ```
501    /// # use actix_web::{App, HttpServer};
502    /// # fn inner() -> std::io::Result<()> {
503    /// HttpServer::new(|| App::new())
504    ///     .bind(("127.0.0.1", 8080))?
505    ///     .bind("[::1]:9000")?
506    /// # ; Ok(()) }
507    /// ```
508    pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
509        let sockets = bind_addrs(addrs, self.backlog)?;
510
511        for lst in sockets {
512            self = self.listen(lst)?;
513        }
514
515        Ok(self)
516    }
517
518    /// Resolves socket address(es) and binds server to created listener(s) for plaintext HTTP/1.x
519    /// or HTTP/2 connections.
520    ///
521    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
522    #[cfg(feature = "http2")]
523    pub fn bind_auto_h2c<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
524        let sockets = bind_addrs(addrs, self.backlog)?;
525
526        for lst in sockets {
527            self = self.listen_auto_h2c(lst)?;
528        }
529
530        Ok(self)
531    }
532
533    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
534    /// using Rustls v0.20.
535    ///
536    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
537    ///
538    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
539    /// added when the `http2` feature is enabled.
540    #[cfg(feature = "rustls-0_20")]
541    pub fn bind_rustls<A: net::ToSocketAddrs>(
542        mut self,
543        addrs: A,
544        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
545    ) -> io::Result<Self> {
546        let sockets = bind_addrs(addrs, self.backlog)?;
547        for lst in sockets {
548            self = self.listen_rustls_0_20_inner(lst, config.clone())?;
549        }
550        Ok(self)
551    }
552
553    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
554    /// using Rustls v0.21.
555    ///
556    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
557    ///
558    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
559    /// added when the `http2` feature is enabled.
560    #[cfg(feature = "rustls-0_21")]
561    pub fn bind_rustls_021<A: net::ToSocketAddrs>(
562        mut self,
563        addrs: A,
564        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
565    ) -> io::Result<Self> {
566        let sockets = bind_addrs(addrs, self.backlog)?;
567        for lst in sockets {
568            self = self.listen_rustls_0_21_inner(lst, config.clone())?;
569        }
570        Ok(self)
571    }
572
573    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
574    /// using Rustls v0.22.
575    ///
576    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
577    ///
578    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
579    /// added when the `http2` feature is enabled.
580    #[cfg(feature = "rustls-0_22")]
581    pub fn bind_rustls_0_22<A: net::ToSocketAddrs>(
582        mut self,
583        addrs: A,
584        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
585    ) -> io::Result<Self> {
586        let sockets = bind_addrs(addrs, self.backlog)?;
587        for lst in sockets {
588            self = self.listen_rustls_0_22_inner(lst, config.clone())?;
589        }
590        Ok(self)
591    }
592
593    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
594    /// using Rustls v0.23.
595    ///
596    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
597    ///
598    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
599    /// added when the `http2` feature is enabled.
600    #[cfg(feature = "rustls-0_23")]
601    pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
602        mut self,
603        addrs: A,
604        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
605    ) -> io::Result<Self> {
606        let sockets = bind_addrs(addrs, self.backlog)?;
607        for lst in sockets {
608            self = self.listen_rustls_0_23_inner(lst, config.clone())?;
609        }
610        Ok(self)
611    }
612
613    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
614    /// using OpenSSL.
615    ///
616    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
617    ///
618    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
619    /// added when the `http2` feature is enabled.
620    #[cfg(feature = "openssl")]
621    pub fn bind_openssl<A>(mut self, addrs: A, builder: SslAcceptorBuilder) -> io::Result<Self>
622    where
623        A: net::ToSocketAddrs,
624    {
625        let sockets = bind_addrs(addrs, self.backlog)?;
626        let acceptor = openssl_acceptor(builder)?;
627
628        for lst in sockets {
629            self = self.listen_openssl_inner(lst, acceptor.clone())?;
630        }
631
632        Ok(self)
633    }
634
635    /// Binds to existing listener for accepting incoming connection requests.
636    ///
637    /// No changes are made to `lst`'s configuration. Ensure it is configured properly before
638    /// passing ownership to `listen()`.
639    pub fn listen(mut self, lst: net::TcpListener) -> io::Result<Self> {
640        let cfg = Arc::clone(&self.config);
641        let factory = self.factory.clone();
642        let addr = lst.local_addr().unwrap();
643
644        self.sockets.push(Socket {
645            addr,
646            scheme: "http",
647        });
648
649        let on_connect_fn = self.on_connect_fn.clone();
650        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
651
652        self.builder =
653            self.builder
654                .listen(format!("actix-web-service-{}", addr), lst, move || {
655                    let cfg = cfg.lock().unwrap();
656                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
657                    let shutdown_signal = graceful_shutdown_signal.clone();
658
659                    let mut svc = HttpService::build()
660                        .graceful_shutdown_signal(move || {
661                            let signal = shutdown_signal.clone();
662                            async move { signal.notified().await }
663                        })
664                        .keep_alive(cfg.keep_alive)
665                        .client_request_timeout(cfg.client_request_timeout)
666                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
667                        .h1_allow_half_closed(cfg.h1_allow_half_closed)
668                        .local_addr(addr);
669
670                    if let Some(enabled) = cfg.tcp_nodelay {
671                        svc = svc.tcp_nodelay(enabled);
672                    }
673
674                    if let Some(size) = cfg.h1_write_buffer_size {
675                        svc = svc.h1_write_buffer_size(size);
676                    }
677
678                    if let Some(val) = cfg.h2_initial_window_size {
679                        svc = svc.h2_initial_window_size(val);
680                    }
681
682                    if let Some(val) = cfg.h2_initial_connection_window_size {
683                        svc = svc.h2_initial_connection_window_size(val);
684                    }
685
686                    if let Some(handler) = on_connect_fn.clone() {
687                        svc =
688                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
689                    };
690
691                    let fac = factory()
692                        .into_factory()
693                        .map_err(|err| err.into().error_response());
694
695                    svc.finish(map_config(fac, move |_| {
696                        AppConfig::new(false, host.clone(), addr)
697                    }))
698                    .tcp()
699                })?;
700
701        Ok(self)
702    }
703
704    /// Binds to existing listener for accepting incoming plaintext HTTP/1.x or HTTP/2 connections.
705    #[cfg(feature = "http2")]
706    pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result<Self> {
707        let cfg = Arc::clone(&self.config);
708        let factory = self.factory.clone();
709        let addr = lst.local_addr().unwrap();
710
711        self.sockets.push(Socket {
712            addr,
713            scheme: "http",
714        });
715
716        let on_connect_fn = self.on_connect_fn.clone();
717        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
718
719        self.builder =
720            self.builder
721                .listen(format!("actix-web-service-{}", addr), lst, move || {
722                    let cfg = cfg.lock().unwrap();
723                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
724                    let shutdown_signal = graceful_shutdown_signal.clone();
725
726                    let mut svc = HttpService::build()
727                        .graceful_shutdown_signal(move || {
728                            let signal = shutdown_signal.clone();
729                            async move { signal.notified().await }
730                        })
731                        .keep_alive(cfg.keep_alive)
732                        .client_request_timeout(cfg.client_request_timeout)
733                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
734                        .h1_allow_half_closed(cfg.h1_allow_half_closed)
735                        .local_addr(addr);
736
737                    if let Some(enabled) = cfg.tcp_nodelay {
738                        svc = svc.tcp_nodelay(enabled);
739                    }
740
741                    if let Some(size) = cfg.h1_write_buffer_size {
742                        svc = svc.h1_write_buffer_size(size);
743                    }
744
745                    if let Some(val) = cfg.h2_initial_window_size {
746                        svc = svc.h2_initial_window_size(val);
747                    }
748
749                    if let Some(val) = cfg.h2_initial_connection_window_size {
750                        svc = svc.h2_initial_connection_window_size(val);
751                    }
752
753                    if let Some(handler) = on_connect_fn.clone() {
754                        svc =
755                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
756                    };
757
758                    let fac = factory()
759                        .into_factory()
760                        .map_err(|err| err.into().error_response());
761
762                    svc.finish(map_config(fac, move |_| {
763                        AppConfig::new(false, host.clone(), addr)
764                    }))
765                    .tcp_auto_h2c()
766                })?;
767
768        Ok(self)
769    }
770
771    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
772    /// v0.20.
773    ///
774    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
775    ///
776    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
777    /// added when the `http2` feature is enabled.
778    #[cfg(feature = "rustls-0_20")]
779    pub fn listen_rustls(
780        self,
781        lst: net::TcpListener,
782        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
783    ) -> io::Result<Self> {
784        self.listen_rustls_0_20_inner(lst, config)
785    }
786
787    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
788    /// v0.21.
789    ///
790    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
791    ///
792    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
793    /// added when the `http2` feature is enabled.
794    #[cfg(feature = "rustls-0_21")]
795    pub fn listen_rustls_0_21(
796        self,
797        lst: net::TcpListener,
798        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
799    ) -> io::Result<Self> {
800        self.listen_rustls_0_21_inner(lst, config)
801    }
802
803    #[cfg(feature = "rustls-0_20")]
804    fn listen_rustls_0_20_inner(
805        mut self,
806        lst: net::TcpListener,
807        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
808    ) -> io::Result<Self> {
809        let factory = self.factory.clone();
810        let cfg = Arc::clone(&self.config);
811        let addr = lst.local_addr().unwrap();
812        self.sockets.push(Socket {
813            addr,
814            scheme: "https",
815        });
816
817        let on_connect_fn = self.on_connect_fn.clone();
818        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
819
820        self.builder =
821            self.builder
822                .listen(format!("actix-web-service-{}", addr), lst, move || {
823                    let c = cfg.lock().unwrap();
824                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
825                    let shutdown_signal = graceful_shutdown_signal.clone();
826
827                    let mut svc = HttpService::build()
828                        .graceful_shutdown_signal(move || {
829                            let signal = shutdown_signal.clone();
830                            async move { signal.notified().await }
831                        })
832                        .keep_alive(c.keep_alive)
833                        .client_request_timeout(c.client_request_timeout)
834                        .h1_allow_half_closed(c.h1_allow_half_closed)
835                        .client_disconnect_timeout(c.client_disconnect_timeout);
836
837                    if let Some(enabled) = c.tcp_nodelay {
838                        svc = svc.tcp_nodelay(enabled);
839                    }
840
841                    if let Some(size) = c.h1_write_buffer_size {
842                        svc = svc.h1_write_buffer_size(size);
843                    }
844
845                    if let Some(val) = c.h2_initial_window_size {
846                        svc = svc.h2_initial_window_size(val);
847                    }
848
849                    if let Some(val) = c.h2_initial_connection_window_size {
850                        svc = svc.h2_initial_connection_window_size(val);
851                    }
852
853                    if let Some(handler) = on_connect_fn.clone() {
854                        svc = svc
855                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
856                    };
857
858                    let fac = factory()
859                        .into_factory()
860                        .map_err(|err| err.into().error_response());
861
862                    let acceptor_config = match c.tls_handshake_timeout {
863                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
864                        None => TlsAcceptorConfig::default(),
865                    };
866
867                    svc.finish(map_config(fac, move |_| {
868                        AppConfig::new(true, host.clone(), addr)
869                    }))
870                    .rustls_with_config(config.clone(), acceptor_config)
871                })?;
872
873        Ok(self)
874    }
875
876    #[cfg(feature = "rustls-0_21")]
877    fn listen_rustls_0_21_inner(
878        mut self,
879        lst: net::TcpListener,
880        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
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        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
892
893        self.builder =
894            self.builder
895                .listen(format!("actix-web-service-{}", addr), lst, move || {
896                    let c = cfg.lock().unwrap();
897                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
898                    let shutdown_signal = graceful_shutdown_signal.clone();
899
900                    let mut svc = HttpService::build()
901                        .graceful_shutdown_signal(move || {
902                            let signal = shutdown_signal.clone();
903                            async move { signal.notified().await }
904                        })
905                        .keep_alive(c.keep_alive)
906                        .client_request_timeout(c.client_request_timeout)
907                        .h1_allow_half_closed(c.h1_allow_half_closed)
908                        .client_disconnect_timeout(c.client_disconnect_timeout);
909
910                    if let Some(enabled) = c.tcp_nodelay {
911                        svc = svc.tcp_nodelay(enabled);
912                    }
913
914                    if let Some(size) = c.h1_write_buffer_size {
915                        svc = svc.h1_write_buffer_size(size);
916                    }
917
918                    if let Some(val) = c.h2_initial_window_size {
919                        svc = svc.h2_initial_window_size(val);
920                    }
921
922                    if let Some(val) = c.h2_initial_connection_window_size {
923                        svc = svc.h2_initial_connection_window_size(val);
924                    }
925
926                    if let Some(handler) = on_connect_fn.clone() {
927                        svc = svc
928                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
929                    };
930
931                    let fac = factory()
932                        .into_factory()
933                        .map_err(|err| err.into().error_response());
934
935                    let acceptor_config = match c.tls_handshake_timeout {
936                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
937                        None => TlsAcceptorConfig::default(),
938                    };
939
940                    svc.finish(map_config(fac, move |_| {
941                        AppConfig::new(true, host.clone(), addr)
942                    }))
943                    .rustls_021_with_config(config.clone(), acceptor_config)
944                })?;
945
946        Ok(self)
947    }
948
949    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
950    /// v0.22.
951    ///
952    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
953    ///
954    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
955    /// added when the `http2` feature is enabled.
956    #[cfg(feature = "rustls-0_22")]
957    pub fn listen_rustls_0_22(
958        self,
959        lst: net::TcpListener,
960        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
961    ) -> io::Result<Self> {
962        self.listen_rustls_0_22_inner(lst, config)
963    }
964
965    #[cfg(feature = "rustls-0_22")]
966    fn listen_rustls_0_22_inner(
967        mut self,
968        lst: net::TcpListener,
969        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
970    ) -> io::Result<Self> {
971        let factory = self.factory.clone();
972        let cfg = Arc::clone(&self.config);
973        let addr = lst.local_addr().unwrap();
974        self.sockets.push(Socket {
975            addr,
976            scheme: "https",
977        });
978
979        let on_connect_fn = self.on_connect_fn.clone();
980        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
981
982        self.builder =
983            self.builder
984                .listen(format!("actix-web-service-{}", addr), lst, move || {
985                    let c = cfg.lock().unwrap();
986                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
987                    let shutdown_signal = graceful_shutdown_signal.clone();
988
989                    let mut svc = HttpService::build()
990                        .graceful_shutdown_signal(move || {
991                            let signal = shutdown_signal.clone();
992                            async move { signal.notified().await }
993                        })
994                        .keep_alive(c.keep_alive)
995                        .client_request_timeout(c.client_request_timeout)
996                        .h1_allow_half_closed(c.h1_allow_half_closed)
997                        .client_disconnect_timeout(c.client_disconnect_timeout);
998
999                    if let Some(enabled) = c.tcp_nodelay {
1000                        svc = svc.tcp_nodelay(enabled);
1001                    }
1002
1003                    if let Some(size) = c.h1_write_buffer_size {
1004                        svc = svc.h1_write_buffer_size(size);
1005                    }
1006
1007                    if let Some(val) = c.h2_initial_window_size {
1008                        svc = svc.h2_initial_window_size(val);
1009                    }
1010
1011                    if let Some(val) = c.h2_initial_connection_window_size {
1012                        svc = svc.h2_initial_connection_window_size(val);
1013                    }
1014
1015                    if let Some(handler) = on_connect_fn.clone() {
1016                        svc = svc
1017                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1018                    };
1019
1020                    let fac = factory()
1021                        .into_factory()
1022                        .map_err(|err| err.into().error_response());
1023
1024                    let acceptor_config = match c.tls_handshake_timeout {
1025                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1026                        None => TlsAcceptorConfig::default(),
1027                    };
1028
1029                    svc.finish(map_config(fac, move |_| {
1030                        AppConfig::new(true, host.clone(), addr)
1031                    }))
1032                    .rustls_0_22_with_config(config.clone(), acceptor_config)
1033                })?;
1034
1035        Ok(self)
1036    }
1037
1038    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
1039    /// v0.23.
1040    ///
1041    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
1042    ///
1043    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
1044    /// added when the `http2` feature is enabled.
1045    #[cfg(feature = "rustls-0_23")]
1046    pub fn listen_rustls_0_23(
1047        self,
1048        lst: net::TcpListener,
1049        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
1050    ) -> io::Result<Self> {
1051        self.listen_rustls_0_23_inner(lst, config)
1052    }
1053
1054    #[cfg(feature = "rustls-0_23")]
1055    fn listen_rustls_0_23_inner(
1056        mut self,
1057        lst: net::TcpListener,
1058        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
1059    ) -> io::Result<Self> {
1060        let factory = self.factory.clone();
1061        let cfg = Arc::clone(&self.config);
1062        let addr = lst.local_addr().unwrap();
1063        self.sockets.push(Socket {
1064            addr,
1065            scheme: "https",
1066        });
1067
1068        let on_connect_fn = self.on_connect_fn.clone();
1069        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1070
1071        self.builder =
1072            self.builder
1073                .listen(format!("actix-web-service-{}", addr), lst, move || {
1074                    let c = cfg.lock().unwrap();
1075                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
1076                    let shutdown_signal = graceful_shutdown_signal.clone();
1077
1078                    let mut svc = HttpService::build()
1079                        .graceful_shutdown_signal(move || {
1080                            let signal = shutdown_signal.clone();
1081                            async move { signal.notified().await }
1082                        })
1083                        .keep_alive(c.keep_alive)
1084                        .client_request_timeout(c.client_request_timeout)
1085                        .h1_allow_half_closed(c.h1_allow_half_closed)
1086                        .client_disconnect_timeout(c.client_disconnect_timeout);
1087
1088                    if let Some(enabled) = c.tcp_nodelay {
1089                        svc = svc.tcp_nodelay(enabled);
1090                    }
1091
1092                    if let Some(size) = c.h1_write_buffer_size {
1093                        svc = svc.h1_write_buffer_size(size);
1094                    }
1095
1096                    if let Some(val) = c.h2_initial_window_size {
1097                        svc = svc.h2_initial_window_size(val);
1098                    }
1099
1100                    if let Some(val) = c.h2_initial_connection_window_size {
1101                        svc = svc.h2_initial_connection_window_size(val);
1102                    }
1103
1104                    if let Some(handler) = on_connect_fn.clone() {
1105                        svc = svc
1106                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1107                    };
1108
1109                    let fac = factory()
1110                        .into_factory()
1111                        .map_err(|err| err.into().error_response());
1112
1113                    let acceptor_config = match c.tls_handshake_timeout {
1114                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1115                        None => TlsAcceptorConfig::default(),
1116                    };
1117
1118                    svc.finish(map_config(fac, move |_| {
1119                        AppConfig::new(true, host.clone(), addr)
1120                    }))
1121                    .rustls_0_23_with_config(config.clone(), acceptor_config)
1122                })?;
1123
1124        Ok(self)
1125    }
1126
1127    /// Binds to existing listener for accepting incoming TLS connection requests using OpenSSL.
1128    ///
1129    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
1130    ///
1131    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
1132    /// added when the `http2` feature is enabled.
1133    #[cfg(feature = "openssl")]
1134    pub fn listen_openssl(
1135        self,
1136        lst: net::TcpListener,
1137        builder: SslAcceptorBuilder,
1138    ) -> io::Result<Self> {
1139        self.listen_openssl_inner(lst, openssl_acceptor(builder)?)
1140    }
1141
1142    #[cfg(feature = "openssl")]
1143    fn listen_openssl_inner(
1144        mut self,
1145        lst: net::TcpListener,
1146        acceptor: SslAcceptor,
1147    ) -> io::Result<Self> {
1148        let factory = self.factory.clone();
1149        let cfg = Arc::clone(&self.config);
1150        let addr = lst.local_addr().unwrap();
1151
1152        self.sockets.push(Socket {
1153            addr,
1154            scheme: "https",
1155        });
1156
1157        let on_connect_fn = self.on_connect_fn.clone();
1158        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1159
1160        self.builder =
1161            self.builder
1162                .listen(format!("actix-web-service-{}", addr), lst, move || {
1163                    let c = cfg.lock().unwrap();
1164                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
1165                    let shutdown_signal = graceful_shutdown_signal.clone();
1166
1167                    let mut svc = HttpService::build()
1168                        .graceful_shutdown_signal(move || {
1169                            let signal = shutdown_signal.clone();
1170                            async move { signal.notified().await }
1171                        })
1172                        .keep_alive(c.keep_alive)
1173                        .client_request_timeout(c.client_request_timeout)
1174                        .client_disconnect_timeout(c.client_disconnect_timeout)
1175                        .h1_allow_half_closed(c.h1_allow_half_closed)
1176                        .local_addr(addr);
1177
1178                    if let Some(enabled) = c.tcp_nodelay {
1179                        svc = svc.tcp_nodelay(enabled);
1180                    }
1181
1182                    if let Some(size) = c.h1_write_buffer_size {
1183                        svc = svc.h1_write_buffer_size(size);
1184                    }
1185
1186                    if let Some(val) = c.h2_initial_window_size {
1187                        svc = svc.h2_initial_window_size(val);
1188                    }
1189
1190                    if let Some(val) = c.h2_initial_connection_window_size {
1191                        svc = svc.h2_initial_connection_window_size(val);
1192                    }
1193
1194                    if let Some(handler) = on_connect_fn.clone() {
1195                        svc = svc
1196                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1197                    };
1198
1199                    let fac = factory()
1200                        .into_factory()
1201                        .map_err(|err| err.into().error_response());
1202
1203                    // false positive lint (?)
1204                    #[allow(clippy::significant_drop_in_scrutinee)]
1205                    let acceptor_config = match c.tls_handshake_timeout {
1206                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1207                        None => TlsAcceptorConfig::default(),
1208                    };
1209
1210                    svc.finish(map_config(fac, move |_| {
1211                        AppConfig::new(true, host.clone(), addr)
1212                    }))
1213                    .openssl_with_config(acceptor.clone(), acceptor_config)
1214                })?;
1215
1216        Ok(self)
1217    }
1218
1219    /// Opens Unix Domain Socket (UDS) from `uds` path and binds server to created listener.
1220    #[cfg(unix)]
1221    pub fn bind_uds<A>(mut self, uds_path: A) -> io::Result<Self>
1222    where
1223        A: AsRef<std::path::Path>,
1224    {
1225        use actix_http::Protocol;
1226        use actix_service::{fn_service, ServiceFactoryExt as _};
1227        use tokio::net::UnixStream;
1228
1229        let cfg = Arc::clone(&self.config);
1230        let factory = self.factory.clone();
1231        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1232        let socket_addr =
1233            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1234
1235        self.sockets.push(Socket {
1236            scheme: "http",
1237            addr: socket_addr,
1238        });
1239
1240        self.builder = self.builder.bind_uds(
1241            format!("actix-web-service-{:?}", uds_path.as_ref()),
1242            uds_path,
1243            move || {
1244                let c = cfg.lock().unwrap();
1245                let config = AppConfig::new(
1246                    false,
1247                    c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1248                    socket_addr,
1249                );
1250
1251                let fac = factory()
1252                    .into_factory()
1253                    .map_err(|err| err.into().error_response());
1254
1255                fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1256                    let shutdown_signal = graceful_shutdown_signal.clone();
1257                    let mut svc = HttpService::build()
1258                        .graceful_shutdown_signal(move || {
1259                            let signal = shutdown_signal.clone();
1260                            async move { signal.notified().await }
1261                        })
1262                        .keep_alive(c.keep_alive)
1263                        .client_request_timeout(c.client_request_timeout)
1264                        .client_disconnect_timeout(c.client_disconnect_timeout)
1265                        .h1_allow_half_closed(c.h1_allow_half_closed);
1266
1267                    if let Some(size) = c.h1_write_buffer_size {
1268                        svc = svc.h1_write_buffer_size(size);
1269                    }
1270
1271                    svc.finish(map_config(fac, move |_| config.clone()))
1272                })
1273            },
1274        )?;
1275
1276        Ok(self)
1277    }
1278
1279    /// Binds to existing Unix Domain Socket (UDS) listener.
1280    #[cfg(unix)]
1281    pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
1282        use actix_http::Protocol;
1283        use actix_service::{fn_service, ServiceFactoryExt as _};
1284        use tokio::net::UnixStream;
1285
1286        let cfg = Arc::clone(&self.config);
1287        let factory = self.factory.clone();
1288        let socket_addr =
1289            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1290
1291        self.sockets.push(Socket {
1292            scheme: "http",
1293            addr: socket_addr,
1294        });
1295
1296        let addr = lst.local_addr()?;
1297        let name = format!("actix-web-service-{:?}", addr);
1298        let on_connect_fn = self.on_connect_fn.clone();
1299        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1300
1301        self.builder = self.builder.listen_uds(name, lst, move || {
1302            let c = cfg.lock().unwrap();
1303            let config = AppConfig::new(
1304                false,
1305                c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1306                socket_addr,
1307            );
1308
1309            fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1310                let shutdown_signal = graceful_shutdown_signal.clone();
1311                let mut svc = HttpService::build()
1312                    .graceful_shutdown_signal(move || {
1313                        let signal = shutdown_signal.clone();
1314                        async move { signal.notified().await }
1315                    })
1316                    .keep_alive(c.keep_alive)
1317                    .client_request_timeout(c.client_request_timeout)
1318                    .h1_allow_half_closed(c.h1_allow_half_closed)
1319                    .client_disconnect_timeout(c.client_disconnect_timeout);
1320
1321                if let Some(handler) = on_connect_fn.clone() {
1322                    svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1323                }
1324
1325                if let Some(size) = c.h1_write_buffer_size {
1326                    svc = svc.h1_write_buffer_size(size);
1327                }
1328
1329                let fac = factory()
1330                    .into_factory()
1331                    .map_err(|err| err.into().error_response());
1332
1333                svc.finish(map_config(fac, move |_| config.clone()))
1334            })
1335        })?;
1336        Ok(self)
1337    }
1338}
1339
1340impl<F, I, S, B> HttpServer<F, I, S, B>
1341where
1342    F: Fn() -> I + Send + Clone + 'static,
1343    I: IntoServiceFactory<S, Request>,
1344    S: ServiceFactory<Request, Config = AppConfig>,
1345    S::Error: Into<Error>,
1346    S::InitError: fmt::Debug,
1347    S::Response: Into<Response<B>>,
1348    S::Service: 'static,
1349    B: MessageBody,
1350{
1351    /// Start listening for incoming connections.
1352    ///
1353    /// # Workers
1354    /// This method starts a number of HTTP workers in separate threads. The number of workers in a
1355    /// set is defined by [`workers()`](Self::workers) or, by default, the number of the machine's
1356    /// physical cores. One worker set is created for each socket address to be bound. For example,
1357    /// if workers is set to 4, and there are 2 addresses to bind, then 8 worker threads will be
1358    /// spawned.
1359    ///
1360    /// # Panics
1361    /// This methods panics if no socket addresses were successfully bound or if no Tokio runtime
1362    /// is set up.
1363    pub fn run(self) -> Server {
1364        self.builder.run()
1365    }
1366}
1367
1368/// Bind TCP listeners to socket addresses resolved from `addrs` with options.
1369fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
1370    let mut err = None;
1371    let mut success = false;
1372    let mut sockets = Vec::new();
1373
1374    for addr in addrs.to_socket_addrs()? {
1375        match create_tcp_listener(addr, backlog) {
1376            Ok(lst) => {
1377                success = true;
1378                sockets.push(lst);
1379            }
1380            Err(error) => err = Some(error),
1381        }
1382    }
1383
1384    if success {
1385        Ok(sockets)
1386    } else if let Some(err) = err.take() {
1387        Err(err)
1388    } else {
1389        Err(io::Error::other("Could not bind to address"))
1390    }
1391}
1392
1393/// Creates a TCP listener from socket address and options.
1394fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
1395    use socket2::{Domain, Protocol, Socket, Type};
1396    let domain = Domain::for_address(addr);
1397    let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
1398    #[cfg(not(windows))]
1399    {
1400        socket.set_reuse_address(true)?;
1401    }
1402    // On Windows, IPV6_V6ONLY defaults to true, preventing IPv6 sockets from accepting IPv4
1403    // connections. Set it to false so that binding to [::] also accepts IPv4 traffic.
1404    #[cfg(windows)]
1405    if addr.is_ipv6() {
1406        if let Err(err) = socket.set_only_v6(false) {
1407            log::warn!("failed to set IPV6_V6ONLY=false: {err}");
1408        }
1409    }
1410    socket.bind(&addr.into())?;
1411    // clamp backlog to max u32 that fits in i32 range
1412    let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
1413    socket.listen(backlog)?;
1414    Ok(net::TcpListener::from(socket))
1415}
1416
1417/// Configures OpenSSL acceptor `builder` with ALPN protocols.
1418#[cfg(feature = "openssl")]
1419fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
1420    builder.set_alpn_select_callback(|_, protocols| {
1421        const H11: &[u8] = b"\x08http/1.1";
1422
1423        #[cfg(feature = "http2")]
1424        {
1425            const H2: &[u8] = b"\x02h2";
1426
1427            if protocols.windows(3).any(|window| window == H2) {
1428                return Ok(b"h2");
1429            }
1430        }
1431
1432        if protocols.windows(9).any(|window| window == H11) {
1433            Ok(b"http/1.1")
1434        } else {
1435            Err(AlpnError::NOACK)
1436        }
1437    });
1438
1439    #[cfg(feature = "http2")]
1440    let protos = b"\x08http/1.1\x02h2";
1441    #[cfg(not(feature = "http2"))]
1442    let protos = b"\x08http/1.1";
1443    builder.set_alpn_protos(protos)?;
1444
1445    Ok(builder.build())
1446}