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    /// # 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    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
534    /// added when the `http2` feature is enabled.
535    #[cfg(feature = "rustls-0_20")]
536    pub fn bind_rustls<A: net::ToSocketAddrs>(
537        mut self,
538        addrs: A,
539        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
540    ) -> io::Result<Self> {
541        let sockets = bind_addrs(addrs, self.backlog)?;
542        for lst in sockets {
543            self = self.listen_rustls_0_20_inner(lst, config.clone())?;
544        }
545        Ok(self)
546    }
547
548    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
549    /// using Rustls v0.21.
550    ///
551    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
552    ///
553    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
554    /// added when the `http2` feature is enabled.
555    #[cfg(feature = "rustls-0_21")]
556    pub fn bind_rustls_021<A: net::ToSocketAddrs>(
557        mut self,
558        addrs: A,
559        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
560    ) -> io::Result<Self> {
561        let sockets = bind_addrs(addrs, self.backlog)?;
562        for lst in sockets {
563            self = self.listen_rustls_0_21_inner(lst, config.clone())?;
564        }
565        Ok(self)
566    }
567
568    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
569    /// using Rustls v0.22.
570    ///
571    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
572    ///
573    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
574    /// added when the `http2` feature is enabled.
575    #[cfg(feature = "rustls-0_22")]
576    pub fn bind_rustls_0_22<A: net::ToSocketAddrs>(
577        mut self,
578        addrs: A,
579        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
580    ) -> io::Result<Self> {
581        let sockets = bind_addrs(addrs, self.backlog)?;
582        for lst in sockets {
583            self = self.listen_rustls_0_22_inner(lst, config.clone())?;
584        }
585        Ok(self)
586    }
587
588    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
589    /// using Rustls v0.23.
590    ///
591    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
592    ///
593    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
594    /// added when the `http2` feature is enabled.
595    #[cfg(feature = "rustls-0_23")]
596    pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
597        mut self,
598        addrs: A,
599        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
600    ) -> io::Result<Self> {
601        let sockets = bind_addrs(addrs, self.backlog)?;
602        for lst in sockets {
603            self = self.listen_rustls_0_23_inner(lst, config.clone())?;
604        }
605        Ok(self)
606    }
607
608    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
609    /// using OpenSSL.
610    ///
611    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
612    ///
613    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
614    /// added when the `http2` feature is enabled.
615    #[cfg(feature = "openssl")]
616    pub fn bind_openssl<A>(mut self, addrs: A, builder: SslAcceptorBuilder) -> io::Result<Self>
617    where
618        A: net::ToSocketAddrs,
619    {
620        let sockets = bind_addrs(addrs, self.backlog)?;
621        let acceptor = openssl_acceptor(builder)?;
622
623        for lst in sockets {
624            self = self.listen_openssl_inner(lst, acceptor.clone())?;
625        }
626
627        Ok(self)
628    }
629
630    /// Binds to existing listener for accepting incoming connection requests.
631    ///
632    /// No changes are made to `lst`'s configuration. Ensure it is configured properly before
633    /// passing ownership to `listen()`.
634    pub fn listen(mut self, lst: net::TcpListener) -> io::Result<Self> {
635        let cfg = Arc::clone(&self.config);
636        let factory = self.factory.clone();
637        let addr = lst.local_addr().unwrap();
638
639        self.sockets.push(Socket {
640            addr,
641            scheme: "http",
642        });
643
644        let on_connect_fn = self.on_connect_fn.clone();
645        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
646
647        self.builder =
648            self.builder
649                .listen(format!("actix-web-service-{}", addr), lst, move || {
650                    let cfg = cfg.lock().unwrap();
651                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
652                    let shutdown_signal = graceful_shutdown_signal.clone();
653
654                    let mut svc = HttpService::build()
655                        .graceful_shutdown_signal(move || {
656                            let signal = shutdown_signal.clone();
657                            async move { signal.notified().await }
658                        })
659                        .keep_alive(cfg.keep_alive)
660                        .client_request_timeout(cfg.client_request_timeout)
661                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
662                        .h1_allow_half_closed(cfg.h1_allow_half_closed)
663                        .local_addr(addr);
664
665                    if let Some(enabled) = cfg.tcp_nodelay {
666                        svc = svc.tcp_nodelay(enabled);
667                    }
668
669                    if let Some(size) = cfg.h1_write_buffer_size {
670                        svc = svc.h1_write_buffer_size(size);
671                    }
672
673                    if let Some(val) = cfg.h2_initial_window_size {
674                        svc = svc.h2_initial_window_size(val);
675                    }
676
677                    if let Some(val) = cfg.h2_initial_connection_window_size {
678                        svc = svc.h2_initial_connection_window_size(val);
679                    }
680
681                    if let Some(handler) = on_connect_fn.clone() {
682                        svc =
683                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
684                    };
685
686                    let fac = factory()
687                        .into_factory()
688                        .map_err(|err| err.into().error_response());
689
690                    svc.finish(map_config(fac, move |_| {
691                        AppConfig::new(false, host.clone(), addr)
692                    }))
693                    .tcp()
694                })?;
695
696        Ok(self)
697    }
698
699    /// Binds to existing listener for accepting incoming plaintext HTTP/1.x or HTTP/2 connections.
700    #[cfg(feature = "http2")]
701    pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result<Self> {
702        let cfg = Arc::clone(&self.config);
703        let factory = self.factory.clone();
704        let addr = lst.local_addr().unwrap();
705
706        self.sockets.push(Socket {
707            addr,
708            scheme: "http",
709        });
710
711        let on_connect_fn = self.on_connect_fn.clone();
712        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
713
714        self.builder =
715            self.builder
716                .listen(format!("actix-web-service-{}", addr), lst, move || {
717                    let cfg = cfg.lock().unwrap();
718                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
719                    let shutdown_signal = graceful_shutdown_signal.clone();
720
721                    let mut svc = HttpService::build()
722                        .graceful_shutdown_signal(move || {
723                            let signal = shutdown_signal.clone();
724                            async move { signal.notified().await }
725                        })
726                        .keep_alive(cfg.keep_alive)
727                        .client_request_timeout(cfg.client_request_timeout)
728                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
729                        .h1_allow_half_closed(cfg.h1_allow_half_closed)
730                        .local_addr(addr);
731
732                    if let Some(enabled) = cfg.tcp_nodelay {
733                        svc = svc.tcp_nodelay(enabled);
734                    }
735
736                    if let Some(size) = cfg.h1_write_buffer_size {
737                        svc = svc.h1_write_buffer_size(size);
738                    }
739
740                    if let Some(val) = cfg.h2_initial_window_size {
741                        svc = svc.h2_initial_window_size(val);
742                    }
743
744                    if let Some(val) = cfg.h2_initial_connection_window_size {
745                        svc = svc.h2_initial_connection_window_size(val);
746                    }
747
748                    if let Some(handler) = on_connect_fn.clone() {
749                        svc =
750                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
751                    };
752
753                    let fac = factory()
754                        .into_factory()
755                        .map_err(|err| err.into().error_response());
756
757                    svc.finish(map_config(fac, move |_| {
758                        AppConfig::new(false, host.clone(), addr)
759                    }))
760                    .tcp_auto_h2c()
761                })?;
762
763        Ok(self)
764    }
765
766    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
767    /// v0.20.
768    ///
769    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
770    ///
771    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
772    /// added when the `http2` feature is enabled.
773    #[cfg(feature = "rustls-0_20")]
774    pub fn listen_rustls(
775        self,
776        lst: net::TcpListener,
777        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
778    ) -> io::Result<Self> {
779        self.listen_rustls_0_20_inner(lst, config)
780    }
781
782    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
783    /// v0.21.
784    ///
785    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
786    ///
787    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
788    /// added when the `http2` feature is enabled.
789    #[cfg(feature = "rustls-0_21")]
790    pub fn listen_rustls_0_21(
791        self,
792        lst: net::TcpListener,
793        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
794    ) -> io::Result<Self> {
795        self.listen_rustls_0_21_inner(lst, config)
796    }
797
798    #[cfg(feature = "rustls-0_20")]
799    fn listen_rustls_0_20_inner(
800        mut self,
801        lst: net::TcpListener,
802        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
803    ) -> io::Result<Self> {
804        let factory = self.factory.clone();
805        let cfg = Arc::clone(&self.config);
806        let addr = lst.local_addr().unwrap();
807        self.sockets.push(Socket {
808            addr,
809            scheme: "https",
810        });
811
812        let on_connect_fn = self.on_connect_fn.clone();
813        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
814
815        self.builder =
816            self.builder
817                .listen(format!("actix-web-service-{}", addr), lst, move || {
818                    let c = cfg.lock().unwrap();
819                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
820                    let shutdown_signal = graceful_shutdown_signal.clone();
821
822                    let mut svc = HttpService::build()
823                        .graceful_shutdown_signal(move || {
824                            let signal = shutdown_signal.clone();
825                            async move { signal.notified().await }
826                        })
827                        .keep_alive(c.keep_alive)
828                        .client_request_timeout(c.client_request_timeout)
829                        .h1_allow_half_closed(c.h1_allow_half_closed)
830                        .client_disconnect_timeout(c.client_disconnect_timeout);
831
832                    if let Some(enabled) = c.tcp_nodelay {
833                        svc = svc.tcp_nodelay(enabled);
834                    }
835
836                    if let Some(size) = c.h1_write_buffer_size {
837                        svc = svc.h1_write_buffer_size(size);
838                    }
839
840                    if let Some(val) = c.h2_initial_window_size {
841                        svc = svc.h2_initial_window_size(val);
842                    }
843
844                    if let Some(val) = c.h2_initial_connection_window_size {
845                        svc = svc.h2_initial_connection_window_size(val);
846                    }
847
848                    if let Some(handler) = on_connect_fn.clone() {
849                        svc = svc
850                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
851                    };
852
853                    let fac = factory()
854                        .into_factory()
855                        .map_err(|err| err.into().error_response());
856
857                    let acceptor_config = match c.tls_handshake_timeout {
858                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
859                        None => TlsAcceptorConfig::default(),
860                    };
861
862                    svc.finish(map_config(fac, move |_| {
863                        AppConfig::new(true, host.clone(), addr)
864                    }))
865                    .rustls_with_config(config.clone(), acceptor_config)
866                })?;
867
868        Ok(self)
869    }
870
871    #[cfg(feature = "rustls-0_21")]
872    fn listen_rustls_0_21_inner(
873        mut self,
874        lst: net::TcpListener,
875        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
876    ) -> io::Result<Self> {
877        let factory = self.factory.clone();
878        let cfg = Arc::clone(&self.config);
879        let addr = lst.local_addr().unwrap();
880        self.sockets.push(Socket {
881            addr,
882            scheme: "https",
883        });
884
885        let on_connect_fn = self.on_connect_fn.clone();
886        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
887
888        self.builder =
889            self.builder
890                .listen(format!("actix-web-service-{}", addr), lst, move || {
891                    let c = cfg.lock().unwrap();
892                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
893                    let shutdown_signal = graceful_shutdown_signal.clone();
894
895                    let mut svc = HttpService::build()
896                        .graceful_shutdown_signal(move || {
897                            let signal = shutdown_signal.clone();
898                            async move { signal.notified().await }
899                        })
900                        .keep_alive(c.keep_alive)
901                        .client_request_timeout(c.client_request_timeout)
902                        .h1_allow_half_closed(c.h1_allow_half_closed)
903                        .client_disconnect_timeout(c.client_disconnect_timeout);
904
905                    if let Some(enabled) = c.tcp_nodelay {
906                        svc = svc.tcp_nodelay(enabled);
907                    }
908
909                    if let Some(size) = c.h1_write_buffer_size {
910                        svc = svc.h1_write_buffer_size(size);
911                    }
912
913                    if let Some(val) = c.h2_initial_window_size {
914                        svc = svc.h2_initial_window_size(val);
915                    }
916
917                    if let Some(val) = c.h2_initial_connection_window_size {
918                        svc = svc.h2_initial_connection_window_size(val);
919                    }
920
921                    if let Some(handler) = on_connect_fn.clone() {
922                        svc = svc
923                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
924                    };
925
926                    let fac = factory()
927                        .into_factory()
928                        .map_err(|err| err.into().error_response());
929
930                    let acceptor_config = match c.tls_handshake_timeout {
931                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
932                        None => TlsAcceptorConfig::default(),
933                    };
934
935                    svc.finish(map_config(fac, move |_| {
936                        AppConfig::new(true, host.clone(), addr)
937                    }))
938                    .rustls_021_with_config(config.clone(), acceptor_config)
939                })?;
940
941        Ok(self)
942    }
943
944    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
945    /// v0.22.
946    ///
947    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
948    ///
949    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
950    /// added when the `http2` feature is enabled.
951    #[cfg(feature = "rustls-0_22")]
952    pub fn listen_rustls_0_22(
953        self,
954        lst: net::TcpListener,
955        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
956    ) -> io::Result<Self> {
957        self.listen_rustls_0_22_inner(lst, config)
958    }
959
960    #[cfg(feature = "rustls-0_22")]
961    fn listen_rustls_0_22_inner(
962        mut self,
963        lst: net::TcpListener,
964        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
965    ) -> io::Result<Self> {
966        let factory = self.factory.clone();
967        let cfg = Arc::clone(&self.config);
968        let addr = lst.local_addr().unwrap();
969        self.sockets.push(Socket {
970            addr,
971            scheme: "https",
972        });
973
974        let on_connect_fn = self.on_connect_fn.clone();
975        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
976
977        self.builder =
978            self.builder
979                .listen(format!("actix-web-service-{}", addr), lst, move || {
980                    let c = cfg.lock().unwrap();
981                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
982                    let shutdown_signal = graceful_shutdown_signal.clone();
983
984                    let mut svc = HttpService::build()
985                        .graceful_shutdown_signal(move || {
986                            let signal = shutdown_signal.clone();
987                            async move { signal.notified().await }
988                        })
989                        .keep_alive(c.keep_alive)
990                        .client_request_timeout(c.client_request_timeout)
991                        .h1_allow_half_closed(c.h1_allow_half_closed)
992                        .client_disconnect_timeout(c.client_disconnect_timeout);
993
994                    if let Some(enabled) = c.tcp_nodelay {
995                        svc = svc.tcp_nodelay(enabled);
996                    }
997
998                    if let Some(size) = c.h1_write_buffer_size {
999                        svc = svc.h1_write_buffer_size(size);
1000                    }
1001
1002                    if let Some(val) = c.h2_initial_window_size {
1003                        svc = svc.h2_initial_window_size(val);
1004                    }
1005
1006                    if let Some(val) = c.h2_initial_connection_window_size {
1007                        svc = svc.h2_initial_connection_window_size(val);
1008                    }
1009
1010                    if let Some(handler) = on_connect_fn.clone() {
1011                        svc = svc
1012                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1013                    };
1014
1015                    let fac = factory()
1016                        .into_factory()
1017                        .map_err(|err| err.into().error_response());
1018
1019                    let acceptor_config = match c.tls_handshake_timeout {
1020                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1021                        None => TlsAcceptorConfig::default(),
1022                    };
1023
1024                    svc.finish(map_config(fac, move |_| {
1025                        AppConfig::new(true, host.clone(), addr)
1026                    }))
1027                    .rustls_0_22_with_config(config.clone(), acceptor_config)
1028                })?;
1029
1030        Ok(self)
1031    }
1032
1033    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
1034    /// v0.23.
1035    ///
1036    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
1037    ///
1038    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
1039    /// added when the `http2` feature is enabled.
1040    #[cfg(feature = "rustls-0_23")]
1041    pub fn listen_rustls_0_23(
1042        self,
1043        lst: net::TcpListener,
1044        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
1045    ) -> io::Result<Self> {
1046        self.listen_rustls_0_23_inner(lst, config)
1047    }
1048
1049    #[cfg(feature = "rustls-0_23")]
1050    fn listen_rustls_0_23_inner(
1051        mut self,
1052        lst: net::TcpListener,
1053        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
1054    ) -> io::Result<Self> {
1055        let factory = self.factory.clone();
1056        let cfg = Arc::clone(&self.config);
1057        let addr = lst.local_addr().unwrap();
1058        self.sockets.push(Socket {
1059            addr,
1060            scheme: "https",
1061        });
1062
1063        let on_connect_fn = self.on_connect_fn.clone();
1064        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1065
1066        self.builder =
1067            self.builder
1068                .listen(format!("actix-web-service-{}", addr), lst, move || {
1069                    let c = cfg.lock().unwrap();
1070                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
1071                    let shutdown_signal = graceful_shutdown_signal.clone();
1072
1073                    let mut svc = HttpService::build()
1074                        .graceful_shutdown_signal(move || {
1075                            let signal = shutdown_signal.clone();
1076                            async move { signal.notified().await }
1077                        })
1078                        .keep_alive(c.keep_alive)
1079                        .client_request_timeout(c.client_request_timeout)
1080                        .h1_allow_half_closed(c.h1_allow_half_closed)
1081                        .client_disconnect_timeout(c.client_disconnect_timeout);
1082
1083                    if let Some(enabled) = c.tcp_nodelay {
1084                        svc = svc.tcp_nodelay(enabled);
1085                    }
1086
1087                    if let Some(size) = c.h1_write_buffer_size {
1088                        svc = svc.h1_write_buffer_size(size);
1089                    }
1090
1091                    if let Some(val) = c.h2_initial_window_size {
1092                        svc = svc.h2_initial_window_size(val);
1093                    }
1094
1095                    if let Some(val) = c.h2_initial_connection_window_size {
1096                        svc = svc.h2_initial_connection_window_size(val);
1097                    }
1098
1099                    if let Some(handler) = on_connect_fn.clone() {
1100                        svc = svc
1101                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1102                    };
1103
1104                    let fac = factory()
1105                        .into_factory()
1106                        .map_err(|err| err.into().error_response());
1107
1108                    let acceptor_config = match c.tls_handshake_timeout {
1109                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1110                        None => TlsAcceptorConfig::default(),
1111                    };
1112
1113                    svc.finish(map_config(fac, move |_| {
1114                        AppConfig::new(true, host.clone(), addr)
1115                    }))
1116                    .rustls_0_23_with_config(config.clone(), acceptor_config)
1117                })?;
1118
1119        Ok(self)
1120    }
1121
1122    /// Binds to existing listener for accepting incoming TLS connection requests using OpenSSL.
1123    ///
1124    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
1125    ///
1126    /// The "http/1.1" ALPN protocol is added to any configured ones. The "h2" protocol is also
1127    /// added when the `http2` feature is enabled.
1128    #[cfg(feature = "openssl")]
1129    pub fn listen_openssl(
1130        self,
1131        lst: net::TcpListener,
1132        builder: SslAcceptorBuilder,
1133    ) -> io::Result<Self> {
1134        self.listen_openssl_inner(lst, openssl_acceptor(builder)?)
1135    }
1136
1137    #[cfg(feature = "openssl")]
1138    fn listen_openssl_inner(
1139        mut self,
1140        lst: net::TcpListener,
1141        acceptor: SslAcceptor,
1142    ) -> io::Result<Self> {
1143        let factory = self.factory.clone();
1144        let cfg = Arc::clone(&self.config);
1145        let addr = lst.local_addr().unwrap();
1146
1147        self.sockets.push(Socket {
1148            addr,
1149            scheme: "https",
1150        });
1151
1152        let on_connect_fn = self.on_connect_fn.clone();
1153        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1154
1155        self.builder =
1156            self.builder
1157                .listen(format!("actix-web-service-{}", addr), lst, move || {
1158                    let c = cfg.lock().unwrap();
1159                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
1160                    let shutdown_signal = graceful_shutdown_signal.clone();
1161
1162                    let mut svc = HttpService::build()
1163                        .graceful_shutdown_signal(move || {
1164                            let signal = shutdown_signal.clone();
1165                            async move { signal.notified().await }
1166                        })
1167                        .keep_alive(c.keep_alive)
1168                        .client_request_timeout(c.client_request_timeout)
1169                        .client_disconnect_timeout(c.client_disconnect_timeout)
1170                        .h1_allow_half_closed(c.h1_allow_half_closed)
1171                        .local_addr(addr);
1172
1173                    if let Some(enabled) = c.tcp_nodelay {
1174                        svc = svc.tcp_nodelay(enabled);
1175                    }
1176
1177                    if let Some(size) = c.h1_write_buffer_size {
1178                        svc = svc.h1_write_buffer_size(size);
1179                    }
1180
1181                    if let Some(val) = c.h2_initial_window_size {
1182                        svc = svc.h2_initial_window_size(val);
1183                    }
1184
1185                    if let Some(val) = c.h2_initial_connection_window_size {
1186                        svc = svc.h2_initial_connection_window_size(val);
1187                    }
1188
1189                    if let Some(handler) = on_connect_fn.clone() {
1190                        svc = svc
1191                            .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1192                    };
1193
1194                    let fac = factory()
1195                        .into_factory()
1196                        .map_err(|err| err.into().error_response());
1197
1198                    // false positive lint (?)
1199                    #[allow(clippy::significant_drop_in_scrutinee)]
1200                    let acceptor_config = match c.tls_handshake_timeout {
1201                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
1202                        None => TlsAcceptorConfig::default(),
1203                    };
1204
1205                    svc.finish(map_config(fac, move |_| {
1206                        AppConfig::new(true, host.clone(), addr)
1207                    }))
1208                    .openssl_with_config(acceptor.clone(), acceptor_config)
1209                })?;
1210
1211        Ok(self)
1212    }
1213
1214    /// Opens Unix Domain Socket (UDS) from `uds` path and binds server to created listener.
1215    #[cfg(unix)]
1216    pub fn bind_uds<A>(mut self, uds_path: A) -> io::Result<Self>
1217    where
1218        A: AsRef<std::path::Path>,
1219    {
1220        use actix_http::Protocol;
1221        use actix_service::{fn_service, ServiceFactoryExt as _};
1222        use tokio::net::UnixStream;
1223
1224        let cfg = Arc::clone(&self.config);
1225        let factory = self.factory.clone();
1226        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1227        let socket_addr =
1228            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1229
1230        self.sockets.push(Socket {
1231            scheme: "http",
1232            addr: socket_addr,
1233        });
1234
1235        self.builder = self.builder.bind_uds(
1236            format!("actix-web-service-{:?}", uds_path.as_ref()),
1237            uds_path,
1238            move || {
1239                let c = cfg.lock().unwrap();
1240                let config = AppConfig::new(
1241                    false,
1242                    c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1243                    socket_addr,
1244                );
1245
1246                let fac = factory()
1247                    .into_factory()
1248                    .map_err(|err| err.into().error_response());
1249
1250                fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1251                    let shutdown_signal = graceful_shutdown_signal.clone();
1252                    let mut svc = HttpService::build()
1253                        .graceful_shutdown_signal(move || {
1254                            let signal = shutdown_signal.clone();
1255                            async move { signal.notified().await }
1256                        })
1257                        .keep_alive(c.keep_alive)
1258                        .client_request_timeout(c.client_request_timeout)
1259                        .client_disconnect_timeout(c.client_disconnect_timeout)
1260                        .h1_allow_half_closed(c.h1_allow_half_closed);
1261
1262                    if let Some(size) = c.h1_write_buffer_size {
1263                        svc = svc.h1_write_buffer_size(size);
1264                    }
1265
1266                    svc.finish(map_config(fac, move |_| config.clone()))
1267                })
1268            },
1269        )?;
1270
1271        Ok(self)
1272    }
1273
1274    /// Binds to existing Unix Domain Socket (UDS) listener.
1275    #[cfg(unix)]
1276    pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
1277        use actix_http::Protocol;
1278        use actix_service::{fn_service, ServiceFactoryExt as _};
1279        use tokio::net::UnixStream;
1280
1281        let cfg = Arc::clone(&self.config);
1282        let factory = self.factory.clone();
1283        let socket_addr =
1284            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
1285
1286        self.sockets.push(Socket {
1287            scheme: "http",
1288            addr: socket_addr,
1289        });
1290
1291        let addr = lst.local_addr()?;
1292        let name = format!("actix-web-service-{:?}", addr);
1293        let on_connect_fn = self.on_connect_fn.clone();
1294        let graceful_shutdown_signal = self.graceful_shutdown_signal.clone();
1295
1296        self.builder = self.builder.listen_uds(name, lst, move || {
1297            let c = cfg.lock().unwrap();
1298            let config = AppConfig::new(
1299                false,
1300                c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
1301                socket_addr,
1302            );
1303
1304            fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
1305                let shutdown_signal = graceful_shutdown_signal.clone();
1306                let mut svc = HttpService::build()
1307                    .graceful_shutdown_signal(move || {
1308                        let signal = shutdown_signal.clone();
1309                        async move { signal.notified().await }
1310                    })
1311                    .keep_alive(c.keep_alive)
1312                    .client_request_timeout(c.client_request_timeout)
1313                    .h1_allow_half_closed(c.h1_allow_half_closed)
1314                    .client_disconnect_timeout(c.client_disconnect_timeout);
1315
1316                if let Some(handler) = on_connect_fn.clone() {
1317                    svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
1318                }
1319
1320                if let Some(size) = c.h1_write_buffer_size {
1321                    svc = svc.h1_write_buffer_size(size);
1322                }
1323
1324                let fac = factory()
1325                    .into_factory()
1326                    .map_err(|err| err.into().error_response());
1327
1328                svc.finish(map_config(fac, move |_| config.clone()))
1329            })
1330        })?;
1331        Ok(self)
1332    }
1333}
1334
1335impl<F, I, S, B> HttpServer<F, I, S, B>
1336where
1337    F: Fn() -> I + Send + Clone + 'static,
1338    I: IntoServiceFactory<S, Request>,
1339    S: ServiceFactory<Request, Config = AppConfig>,
1340    S::Error: Into<Error>,
1341    S::InitError: fmt::Debug,
1342    S::Response: Into<Response<B>>,
1343    S::Service: 'static,
1344    B: MessageBody,
1345{
1346    /// Start listening for incoming connections.
1347    ///
1348    /// # Workers
1349    /// This method starts a number of HTTP workers in separate threads. The number of workers in a
1350    /// set is defined by [`workers()`](Self::workers) or, by default, the number of the machine's
1351    /// physical cores. One worker set is created for each socket address to be bound. For example,
1352    /// if workers is set to 4, and there are 2 addresses to bind, then 8 worker threads will be
1353    /// spawned.
1354    ///
1355    /// # Panics
1356    /// This methods panics if no socket addresses were successfully bound or if no Tokio runtime
1357    /// is set up.
1358    pub fn run(self) -> Server {
1359        self.builder.run()
1360    }
1361}
1362
1363/// Bind TCP listeners to socket addresses resolved from `addrs` with options.
1364fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
1365    let mut err = None;
1366    let mut success = false;
1367    let mut sockets = Vec::new();
1368
1369    for addr in addrs.to_socket_addrs()? {
1370        match create_tcp_listener(addr, backlog) {
1371            Ok(lst) => {
1372                success = true;
1373                sockets.push(lst);
1374            }
1375            Err(error) => err = Some(error),
1376        }
1377    }
1378
1379    if success {
1380        Ok(sockets)
1381    } else if let Some(err) = err.take() {
1382        Err(err)
1383    } else {
1384        Err(io::Error::other("Could not bind to address"))
1385    }
1386}
1387
1388/// Creates a TCP listener from socket address and options.
1389fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
1390    use socket2::{Domain, Protocol, Socket, Type};
1391    let domain = Domain::for_address(addr);
1392    let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
1393    #[cfg(not(windows))]
1394    {
1395        socket.set_reuse_address(true)?;
1396    }
1397    // On Windows, IPV6_V6ONLY defaults to true, preventing IPv6 sockets from accepting IPv4
1398    // connections. Set it to false so that binding to [::] also accepts IPv4 traffic.
1399    #[cfg(windows)]
1400    if addr.is_ipv6() {
1401        if let Err(err) = socket.set_only_v6(false) {
1402            log::warn!("failed to set IPV6_V6ONLY=false: {err}");
1403        }
1404    }
1405    socket.bind(&addr.into())?;
1406    // clamp backlog to max u32 that fits in i32 range
1407    let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
1408    socket.listen(backlog)?;
1409    Ok(net::TcpListener::from(socket))
1410}
1411
1412/// Configures OpenSSL acceptor `builder` with ALPN protocols.
1413#[cfg(feature = "openssl")]
1414fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
1415    builder.set_alpn_select_callback(|_, protocols| {
1416        const H11: &[u8] = b"\x08http/1.1";
1417
1418        #[cfg(feature = "http2")]
1419        {
1420            const H2: &[u8] = b"\x02h2";
1421
1422            if protocols.windows(3).any(|window| window == H2) {
1423                return Ok(b"h2");
1424            }
1425        }
1426
1427        if protocols.windows(9).any(|window| window == H11) {
1428            Ok(b"http/1.1")
1429        } else {
1430            Err(AlpnError::NOACK)
1431        }
1432    });
1433
1434    #[cfg(feature = "http2")]
1435    let protos = b"\x08http/1.1\x02h2";
1436    #[cfg(not(feature = "http2"))]
1437    let protos = b"\x08http/1.1";
1438    builder.set_alpn_protos(protos)?;
1439
1440    Ok(builder.build())
1441}