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