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