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