Skip to main content

tonic/transport/server/
mod.rs

1/*
2 *
3 * Copyright 2025 gRPC authors.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25//! Server implementation and builder.
26
27mod conn;
28mod display_error_stack;
29mod incoming;
30mod io_stream;
31mod service;
32#[cfg(feature = "_tls-any")]
33mod tls;
34#[cfg(unix)]
35mod unix;
36
37use tokio_stream::StreamExt as _;
38use tracing::{debug, trace};
39
40#[cfg(feature = "router")]
41use crate::{server::NamedService, service::Routes};
42
43#[cfg(feature = "router")]
44use std::convert::Infallible;
45
46pub use conn::{Connected, TcpConnectInfo};
47use hyper_util::{
48    rt::{TokioExecutor, TokioIo, TokioTimer},
49    server::conn::auto::{Builder as ConnectionBuilder, HttpServerConnExec},
50    service::TowerToHyperService,
51};
52#[cfg(feature = "_tls-any")]
53pub use tls::ServerTlsConfig;
54
55#[cfg(feature = "_tls-any")]
56pub use conn::TlsConnectInfo;
57
58#[cfg(feature = "_tls-any")]
59use self::service::TlsAcceptor;
60
61#[cfg(unix)]
62pub use unix::UdsConnectInfo;
63
64pub use incoming::TcpIncoming;
65
66#[cfg(feature = "_tls-any")]
67use crate::transport::Error;
68
69use self::service::{ConnectInfoLayer, ServerIo};
70use super::service::GrpcTimeout;
71use crate::body::Body;
72use crate::service::RecoverErrorLayer;
73use crate::transport::server::display_error_stack::DisplayErrorStack;
74use bytes::Bytes;
75use http::{Request, Response};
76use http_body_util::BodyExt;
77use hyper::{body::Incoming, service::Service as HyperService};
78use pin_project::pin_project;
79use std::{
80    fmt,
81    future::{self, Future},
82    marker::PhantomData,
83    net::SocketAddr,
84    pin::{Pin, pin},
85    sync::Arc,
86    task::{Context, Poll, ready},
87    time::Duration,
88};
89use tokio::io::{AsyncRead, AsyncWrite};
90use tokio_stream::Stream;
91use tower::{
92    Service, ServiceBuilder, ServiceExt,
93    layer::Layer,
94    layer::util::{Identity, Stack},
95    limit::concurrency::ConcurrencyLimitLayer,
96    load_shed::LoadShedLayer,
97    util::BoxCloneService,
98};
99
100type BoxService = tower::util::BoxCloneService<Request<Body>, Response<Body>, crate::BoxError>;
101type TraceInterceptor = Arc<dyn Fn(&http::Request<()>) -> tracing::Span + Send + Sync + 'static>;
102
103const DEFAULT_HTTP2_KEEPALIVE_TIMEOUT: Duration = Duration::from_secs(20);
104
105/// A default batteries included `transport` server.
106///
107/// This provides an easy builder pattern style builder [`Server`] on top of
108/// `hyper` connections. This builder exposes easy configuration parameters
109/// for providing a fully featured http2 based gRPC server. This should provide
110/// a very good out of the box http2 server for use with tonic but is also a
111/// reference implementation that should be a good starting point for anyone
112/// wanting to create a more complex and/or specific implementation.
113#[derive(Clone)]
114pub struct Server<L = Identity> {
115    trace_interceptor: Option<TraceInterceptor>,
116    concurrency_limit: Option<usize>,
117    load_shed: bool,
118    timeout: Option<Duration>,
119    #[cfg(feature = "_tls-any")]
120    tls: Option<TlsAcceptor>,
121    init_stream_window_size: Option<u32>,
122    init_connection_window_size: Option<u32>,
123    max_concurrent_streams: Option<u32>,
124    tcp_keepalive: Option<Duration>,
125    tcp_keepalive_interval: Option<Duration>,
126    tcp_keepalive_retries: Option<u32>,
127    tcp_nodelay: bool,
128    http2_keepalive_interval: Option<Duration>,
129    http2_keepalive_timeout: Duration,
130    http2_adaptive_window: Option<bool>,
131    http2_max_pending_accept_reset_streams: Option<usize>,
132    http2_max_local_error_reset_streams: Option<usize>,
133    http2_max_header_list_size: Option<u32>,
134    max_frame_size: Option<u32>,
135    accept_http1: bool,
136    service_builder: ServiceBuilder<L>,
137    max_connection_age: Option<Duration>,
138    max_connection_age_grace: Option<Duration>,
139}
140
141impl Default for Server<Identity> {
142    fn default() -> Self {
143        Self {
144            trace_interceptor: None,
145            concurrency_limit: None,
146            load_shed: false,
147            timeout: None,
148            #[cfg(feature = "_tls-any")]
149            tls: None,
150            init_stream_window_size: None,
151            init_connection_window_size: None,
152            max_concurrent_streams: None,
153            tcp_keepalive: None,
154            tcp_keepalive_interval: None,
155            tcp_keepalive_retries: None,
156            tcp_nodelay: true,
157            http2_keepalive_interval: None,
158            http2_keepalive_timeout: DEFAULT_HTTP2_KEEPALIVE_TIMEOUT,
159            http2_adaptive_window: None,
160            http2_max_pending_accept_reset_streams: None,
161            http2_max_local_error_reset_streams: None,
162            http2_max_header_list_size: None,
163            max_frame_size: None,
164            accept_http1: false,
165            service_builder: Default::default(),
166            max_connection_age: None,
167            max_connection_age_grace: None,
168        }
169    }
170}
171
172/// A stack based [`Service`] router.
173#[cfg(feature = "router")]
174#[derive(Clone, Debug)]
175pub struct Router<L = Identity> {
176    server: Server<L>,
177    routes: Routes,
178}
179
180impl Server {
181    /// Create a new server builder that can configure a [`Server`].
182    pub fn builder() -> Self {
183        Self::default()
184    }
185}
186
187impl<L> Server<L> {
188    /// Configure TLS for this server.
189    #[cfg(feature = "_tls-any")]
190    pub fn tls_config(self, tls_config: ServerTlsConfig) -> Result<Self, Error> {
191        Ok(Server {
192            tls: Some(tls_config.tls_acceptor().map_err(Error::from_source)?),
193            ..self
194        })
195    }
196
197    /// Set the concurrency limit applied to on requests inbound per connection.
198    ///
199    /// # Example
200    ///
201    /// ```
202    /// # use tonic::transport::Server;
203    /// # use tower_service::Service;
204    /// # let builder = Server::builder();
205    /// builder.concurrency_limit_per_connection(32);
206    /// ```
207    #[must_use]
208    pub fn concurrency_limit_per_connection(self, limit: usize) -> Self {
209        Server {
210            concurrency_limit: Some(limit),
211            ..self
212        }
213    }
214
215    /// Enable or disable load shedding. The default is disabled.
216    ///
217    /// When load shedding is enabled, if the service responds with not ready
218    /// the request will immediately be rejected with a
219    /// [`resource_exhausted`](https://docs.rs/tonic/latest/tonic/struct.Status.html#method.resource_exhausted) error.
220    /// The default is to buffer requests. This is especially useful in combination with
221    /// setting a concurrency limit per connection.
222    ///
223    /// # Example
224    ///
225    /// ```
226    /// # use tonic::transport::Server;
227    /// # use tower_service::Service;
228    /// # let builder = Server::builder();
229    /// builder.load_shed(true);
230    /// ```
231    #[must_use]
232    pub fn load_shed(self, load_shed: bool) -> Self {
233        Server { load_shed, ..self }
234    }
235
236    /// Set a timeout on for all request handlers.
237    ///
238    /// # Example
239    ///
240    /// ```
241    /// # use tonic::transport::Server;
242    /// # use tower_service::Service;
243    /// # use std::time::Duration;
244    /// # let builder = Server::builder();
245    /// builder.timeout(Duration::from_secs(30));
246    /// ```
247    #[must_use]
248    pub fn timeout(self, timeout: Duration) -> Self {
249        Server {
250            timeout: Some(timeout),
251            ..self
252        }
253    }
254
255    /// Sets the [`SETTINGS_INITIAL_WINDOW_SIZE`][spec] option for HTTP2
256    /// stream-level flow control.
257    ///
258    /// Default is 65,535
259    ///
260    /// [spec]: https://httpwg.org/specs/rfc9113.html#InitialWindowSize
261    #[must_use]
262    pub fn initial_stream_window_size(self, sz: impl Into<Option<u32>>) -> Self {
263        Server {
264            init_stream_window_size: sz.into(),
265            ..self
266        }
267    }
268
269    /// Sets the max connection-level flow control for HTTP2
270    ///
271    /// Default is 65,535
272    #[must_use]
273    pub fn initial_connection_window_size(self, sz: impl Into<Option<u32>>) -> Self {
274        Server {
275            init_connection_window_size: sz.into(),
276            ..self
277        }
278    }
279
280    /// Sets the [`SETTINGS_MAX_CONCURRENT_STREAMS`][spec] option for HTTP2
281    /// connections.
282    ///
283    /// Default is no limit (`None`).
284    ///
285    /// [spec]: https://httpwg.org/specs/rfc9113.html#n-stream-concurrency
286    #[must_use]
287    pub fn max_concurrent_streams(self, max: impl Into<Option<u32>>) -> Self {
288        Server {
289            max_concurrent_streams: max.into(),
290            ..self
291        }
292    }
293
294    /// Sets the maximum time option in milliseconds that a connection may exist
295    ///
296    /// Default is no limit (`None`).
297    ///
298    /// # Example
299    ///
300    /// ```
301    /// # use tonic::transport::Server;
302    /// # use tower_service::Service;
303    /// # use std::time::Duration;
304    /// # let builder = Server::builder();
305    /// builder.max_connection_age(Duration::from_secs(60));
306    /// ```
307    #[must_use]
308    pub fn max_connection_age(self, max_connection_age: Duration) -> Self {
309        Server {
310            max_connection_age: Some(max_connection_age),
311            ..self
312        }
313    }
314
315    /// Sets the maximum duration that a connection may continue to exist
316    /// **after** the graceful shutdown period (`max_connection_age`) has elapsed.
317    ///
318    /// This timeout only takes effect *after* a connection has exceeded its
319    /// configured `max_connection_age`. Once that happens, the server will begin
320    /// graceful shutdown for the connection. If the connection does not close
321    /// gracefully within the `max_connection_age_grace` duration, the server will then
322    /// forcefully terminate it.
323    ///
324    /// If no `max_connection_age` is configured, this forced shutdown timeout will
325    /// **never trigger**, because the server will not know when to begin the
326    /// graceful shutdown phase.
327    ///
328    /// Default is no limit (`None`).
329    ///
330    /// ```
331    /// # use tonic::transport::Server;
332    /// # use tower_service::Service;
333    /// # use std::time::Duration;
334    /// # let builder = Server::builder();
335    /// builder.max_connection_age_grace(Duration::from_secs(60));
336    /// ```
337    #[must_use]
338    pub fn max_connection_age_grace(self, max_connection_age_grace: Duration) -> Self {
339        Server {
340            max_connection_age_grace: Some(max_connection_age_grace),
341            ..self
342        }
343    }
344
345    /// Set whether HTTP2 Ping frames are enabled on accepted connections.
346    ///
347    /// If `None` is specified, HTTP2 keepalive is disabled, otherwise the duration
348    /// specified will be the time interval between HTTP2 Ping frames.
349    /// The timeout for receiving an acknowledgement of the keepalive ping
350    /// can be set with [`Server::http2_keepalive_timeout`].
351    ///
352    /// Default is no HTTP2 keepalive (`None`)
353    ///
354    #[must_use]
355    pub fn http2_keepalive_interval(self, http2_keepalive_interval: Option<Duration>) -> Self {
356        Server {
357            http2_keepalive_interval,
358            ..self
359        }
360    }
361
362    /// Sets a timeout for receiving an acknowledgement of the keepalive ping.
363    ///
364    /// If the ping is not acknowledged within the timeout, the connection will be closed.
365    /// Does nothing if http2_keep_alive_interval is disabled.
366    ///
367    /// Default is 20 seconds.
368    ///
369    #[must_use]
370    pub fn http2_keepalive_timeout(mut self, http2_keepalive_timeout: Option<Duration>) -> Self {
371        if let Some(timeout) = http2_keepalive_timeout {
372            self.http2_keepalive_timeout = timeout;
373        }
374        self
375    }
376
377    /// Sets whether to use an adaptive flow control. Defaults to false.
378    /// Enabling this will override the limits set in http2_initial_stream_window_size and
379    /// http2_initial_connection_window_size.
380    #[must_use]
381    pub fn http2_adaptive_window(self, enabled: Option<bool>) -> Self {
382        Server {
383            http2_adaptive_window: enabled,
384            ..self
385        }
386    }
387
388    /// Configures the maximum number of pending reset streams allowed before a GOAWAY will be sent.
389    ///
390    /// This will default to whatever the default in h2 is. As of v0.3.17, it is 20.
391    ///
392    /// See <https://github.com/hyperium/hyper/issues/2877> for more information.
393    #[must_use]
394    pub fn http2_max_pending_accept_reset_streams(self, max: Option<usize>) -> Self {
395        Server {
396            http2_max_pending_accept_reset_streams: max,
397            ..self
398        }
399    }
400
401    /// Configures the maximum number of local reset streams allowed before a GOAWAY will be sent.
402    ///
403    /// This will default to whatever the default in hyper is.
404    #[must_use]
405    pub fn http2_max_local_error_reset_streams(self, max: Option<usize>) -> Self {
406        Server {
407            http2_max_local_error_reset_streams: max,
408            ..self
409        }
410    }
411
412    /// Set whether TCP keepalive messages are enabled on accepted connections.
413    ///
414    /// If `None` is specified, keepalive is disabled, otherwise the duration
415    /// specified will be the time to remain idle before sending TCP keepalive
416    /// probes.
417    ///
418    /// Important: This setting is ignored when using `serve_with_incoming`.
419    ///
420    /// Default is no keepalive (`None`)
421    ///
422    #[must_use]
423    pub fn tcp_keepalive(self, tcp_keepalive: Option<Duration>) -> Self {
424        Server {
425            tcp_keepalive,
426            ..self
427        }
428    }
429
430    /// Set the value of `TCP_KEEPINTVL` option for accepted connections.
431    ///
432    /// This option specifies the time interval between subsequent keepalive probes.
433    /// This setting only takes effect if [`tcp_keepalive`](Self::tcp_keepalive) is also set.
434    ///
435    /// Important: This setting is ignored when using `serve_with_incoming`.
436    ///
437    /// Default is `None` (system default).
438    ///
439    /// Note: This option is only available on some platforms (Linux, macOS, Windows, etc.).
440    #[must_use]
441    pub fn tcp_keepalive_interval(self, tcp_keepalive_interval: Option<Duration>) -> Self {
442        Server {
443            tcp_keepalive_interval,
444            ..self
445        }
446    }
447
448    /// Set the value of `TCP_KEEPCNT` option for accepted connections.
449    ///
450    /// This option specifies the maximum number of keepalive probes that should be sent
451    /// before dropping the connection.
452    /// This setting only takes effect if [`tcp_keepalive`](Self::tcp_keepalive) is also set.
453    ///
454    /// Important: This setting is ignored when using `serve_with_incoming`.
455    ///
456    /// Default is `None` (system default).
457    ///
458    /// Note: This option is only available on some platforms (Linux, macOS, Windows, etc.).
459    #[must_use]
460    pub fn tcp_keepalive_retries(self, tcp_keepalive_retries: Option<u32>) -> Self {
461        Server {
462            tcp_keepalive_retries,
463            ..self
464        }
465    }
466
467    /// Set the value of `TCP_NODELAY` option for accepted connections. Enabled by default.
468    ///
469    /// Important: This setting is ignored when using `serve_with_incoming`.
470    #[must_use]
471    pub fn tcp_nodelay(self, enabled: bool) -> Self {
472        Server {
473            tcp_nodelay: enabled,
474            ..self
475        }
476    }
477
478    /// Sets the max size of received header frames.
479    ///
480    /// This will default to whatever the default in hyper is. As of v1.4.1, it is 16 KiB.
481    #[must_use]
482    pub fn http2_max_header_list_size(self, max: impl Into<Option<u32>>) -> Self {
483        Server {
484            http2_max_header_list_size: max.into(),
485            ..self
486        }
487    }
488
489    /// Sets the maximum frame size to use for HTTP2.
490    ///
491    /// Passing `None` will do nothing.
492    ///
493    /// If not set, will default from underlying transport.
494    #[must_use]
495    pub fn max_frame_size(self, frame_size: impl Into<Option<u32>>) -> Self {
496        Server {
497            max_frame_size: frame_size.into(),
498            ..self
499        }
500    }
501
502    /// Allow this server to accept http1 requests.
503    ///
504    /// Accepting http1 requests is only useful when developing `grpc-web`
505    /// enabled services. If this setting is set to `true` but services are
506    /// not correctly configured to handle grpc-web requests, your server may
507    /// return confusing (but correct) protocol errors.
508    ///
509    /// Default is `false`.
510    #[must_use]
511    pub fn accept_http1(self, accept_http1: bool) -> Self {
512        Server {
513            accept_http1,
514            ..self
515        }
516    }
517
518    /// Intercept inbound headers and add a [`tracing::Span`] to each response future.
519    #[must_use]
520    pub fn trace_fn<F>(self, f: F) -> Self
521    where
522        F: Fn(&http::Request<()>) -> tracing::Span + Send + Sync + 'static,
523    {
524        Server {
525            trace_interceptor: Some(Arc::new(f)),
526            ..self
527        }
528    }
529
530    /// Create a router with the `S` typed service as the first service.
531    ///
532    /// This will clone the `Server` builder and create a router that will
533    /// route around different services.
534    #[cfg(feature = "router")]
535    pub fn add_service<S>(&mut self, svc: S) -> Router<L>
536    where
537        S: Service<Request<Body>, Error = Infallible>
538            + NamedService
539            + Clone
540            + Send
541            + Sync
542            + 'static,
543        S::Response: axum::response::IntoResponse,
544        S::Future: Send + 'static,
545        L: Clone,
546    {
547        Router::new(self.clone(), Routes::new(svc))
548    }
549
550    /// Create a router with the optional `S` typed service as the first service.
551    ///
552    /// This will clone the `Server` builder and create a router that will
553    /// route around different services.
554    ///
555    /// # Note
556    /// Even when the argument given is `None` this will capture *all* requests to this service name.
557    /// As a result, one cannot use this to toggle between two identically named implementations.
558    #[cfg(feature = "router")]
559    pub fn add_optional_service<S>(&mut self, svc: Option<S>) -> Router<L>
560    where
561        S: Service<Request<Body>, Error = Infallible>
562            + NamedService
563            + Clone
564            + Send
565            + Sync
566            + 'static,
567        S::Response: axum::response::IntoResponse,
568        S::Future: Send + 'static,
569        L: Clone,
570    {
571        let routes = svc.map(Routes::new).unwrap_or_default();
572        Router::new(self.clone(), routes)
573    }
574
575    /// Create a router with given [`Routes`].
576    ///
577    /// This will clone the `Server` builder and create a router that will
578    /// route around different services that were already added to the provided `routes`.
579    #[cfg(feature = "router")]
580    pub fn add_routes(&mut self, routes: Routes) -> Router<L>
581    where
582        L: Clone,
583    {
584        Router::new(self.clone(), routes)
585    }
586
587    /// Set the [Tower] [`Layer`] all services will be wrapped in.
588    ///
589    /// This enables using middleware from the [Tower ecosystem][eco].
590    ///
591    /// # Example
592    ///
593    /// ```
594    /// # use tonic::transport::Server;
595    /// # use tower_service::Service;
596    /// use tower::timeout::TimeoutLayer;
597    /// use std::time::Duration;
598    ///
599    /// # let mut builder = Server::builder();
600    /// builder.layer(TimeoutLayer::new(Duration::from_secs(30)));
601    /// ```
602    ///
603    /// Note that timeouts should be set using [`Server::timeout`]. `TimeoutLayer` is only used
604    /// here as an example.
605    ///
606    /// You can build more complex layers using [`ServiceBuilder`]. Those layers can include
607    /// [interceptors]:
608    ///
609    /// ```
610    /// # use tonic::transport::Server;
611    /// # use tower_service::Service;
612    /// use tower::ServiceBuilder;
613    /// use std::time::Duration;
614    /// use tonic::{Request, Status, service::InterceptorLayer};
615    ///
616    /// fn auth_interceptor(request: Request<()>) -> Result<Request<()>, Status> {
617    ///     if valid_credentials(&request) {
618    ///         Ok(request)
619    ///     } else {
620    ///         Err(Status::unauthenticated("invalid credentials"))
621    ///     }
622    /// }
623    ///
624    /// fn valid_credentials(request: &Request<()>) -> bool {
625    ///     // ...
626    ///     # true
627    /// }
628    ///
629    /// fn some_other_interceptor(request: Request<()>) -> Result<Request<()>, Status> {
630    ///     Ok(request)
631    /// }
632    ///
633    /// let layer = ServiceBuilder::new()
634    ///     .load_shed()
635    ///     .timeout(Duration::from_secs(30))
636    ///     .layer(InterceptorLayer::new(auth_interceptor))
637    ///     .layer(InterceptorLayer::new(some_other_interceptor))
638    ///     .into_inner();
639    ///
640    /// Server::builder().layer(layer);
641    /// ```
642    ///
643    /// [Tower]: https://github.com/tower-rs/tower
644    /// [`Layer`]: tower::layer::Layer
645    /// [eco]: https://github.com/tower-rs
646    /// [`ServiceBuilder`]: tower::ServiceBuilder
647    /// [interceptors]: crate::service::Interceptor
648    pub fn layer<NewLayer>(self, new_layer: NewLayer) -> Server<Stack<NewLayer, L>> {
649        Server {
650            service_builder: self.service_builder.layer(new_layer),
651            trace_interceptor: self.trace_interceptor,
652            concurrency_limit: self.concurrency_limit,
653            load_shed: self.load_shed,
654            timeout: self.timeout,
655            #[cfg(feature = "_tls-any")]
656            tls: self.tls,
657            init_stream_window_size: self.init_stream_window_size,
658            init_connection_window_size: self.init_connection_window_size,
659            max_concurrent_streams: self.max_concurrent_streams,
660            tcp_keepalive: self.tcp_keepalive,
661            tcp_keepalive_interval: self.tcp_keepalive_interval,
662            tcp_keepalive_retries: self.tcp_keepalive_retries,
663            tcp_nodelay: self.tcp_nodelay,
664            http2_keepalive_interval: self.http2_keepalive_interval,
665            http2_keepalive_timeout: self.http2_keepalive_timeout,
666            http2_adaptive_window: self.http2_adaptive_window,
667            http2_max_pending_accept_reset_streams: self.http2_max_pending_accept_reset_streams,
668            http2_max_header_list_size: self.http2_max_header_list_size,
669            http2_max_local_error_reset_streams: self.http2_max_local_error_reset_streams,
670            max_frame_size: self.max_frame_size,
671            accept_http1: self.accept_http1,
672            max_connection_age: self.max_connection_age,
673            max_connection_age_grace: self.max_connection_age_grace,
674        }
675    }
676
677    fn bind_incoming(&self, addr: SocketAddr) -> Result<TcpIncoming, super::Error> {
678        Ok(TcpIncoming::bind(addr)
679            .map_err(super::Error::from_source)?
680            .with_nodelay(Some(self.tcp_nodelay))
681            .with_keepalive(self.tcp_keepalive)
682            .with_keepalive_interval(self.tcp_keepalive_interval)
683            .with_keepalive_retries(self.tcp_keepalive_retries))
684    }
685
686    /// Serve the service.
687    pub async fn serve<S, ResBody>(self, addr: SocketAddr, svc: S) -> Result<(), super::Error>
688    where
689        L: Layer<S>,
690        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
691        <<L as Layer<S>>::Service as Service<Request<Body>>>::Future: Send,
692        <<L as Layer<S>>::Service as Service<Request<Body>>>::Error:
693            Into<crate::BoxError> + Send + 'static,
694        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
695        ResBody::Error: Into<crate::BoxError>,
696    {
697        let incoming = self.bind_incoming(addr)?;
698        self.serve_with_incoming(svc, incoming).await
699    }
700
701    /// Serve the service with the shutdown signal.
702    pub async fn serve_with_shutdown<S, F, ResBody>(
703        self,
704        addr: SocketAddr,
705        svc: S,
706        signal: F,
707    ) -> Result<(), super::Error>
708    where
709        L: Layer<S>,
710        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
711        <<L as Layer<S>>::Service as Service<Request<Body>>>::Future: Send,
712        <<L as Layer<S>>::Service as Service<Request<Body>>>::Error:
713            Into<crate::BoxError> + Send + 'static,
714        F: Future<Output = ()>,
715        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
716        ResBody::Error: Into<crate::BoxError>,
717    {
718        let incoming = self.bind_incoming(addr)?;
719        self.serve_with_incoming_shutdown(svc, incoming, signal)
720            .await
721    }
722
723    /// Serve the service on the provided incoming stream.
724    ///
725    /// The `tcp_nodelay` and `tcp_keepalive` settings are ignored when using this method.
726    pub async fn serve_with_incoming<S, I, IO, IE, ResBody>(
727        self,
728        svc: S,
729        incoming: I,
730    ) -> Result<(), super::Error>
731    where
732        L: Layer<S>,
733        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
734        <<L as Layer<S>>::Service as Service<Request<Body>>>::Future: Send,
735        <<L as Layer<S>>::Service as Service<Request<Body>>>::Error:
736            Into<crate::BoxError> + Send + 'static,
737        I: Stream<Item = Result<IO, IE>>,
738        IO: AsyncRead + AsyncWrite + Connected + Unpin + Send + 'static,
739        IE: Into<crate::BoxError>,
740        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
741        ResBody::Error: Into<crate::BoxError>,
742    {
743        self.serve_internal(svc, incoming, Option::<future::Ready<()>>::None)
744            .await
745    }
746
747    /// Serve the service with the signal on the provided incoming stream.
748    ///
749    /// When `signal` completes, this function drops `incoming`.
750    /// If `incoming` is a [`TcpIncoming`], drop closes the listen socket.
751    /// The function then waits for accepted connections to close.
752    pub async fn serve_with_incoming_shutdown<S, I, F, IO, IE, ResBody>(
753        self,
754        svc: S,
755        incoming: I,
756        signal: F,
757    ) -> Result<(), super::Error>
758    where
759        L: Layer<S>,
760        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
761        <<L as Layer<S>>::Service as Service<Request<Body>>>::Future: Send,
762        <<L as Layer<S>>::Service as Service<Request<Body>>>::Error:
763            Into<crate::BoxError> + Send + 'static,
764        I: Stream<Item = Result<IO, IE>>,
765        IO: AsyncRead + AsyncWrite + Connected + Unpin + Send + 'static,
766        IE: Into<crate::BoxError>,
767        F: Future<Output = ()>,
768        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
769        ResBody::Error: Into<crate::BoxError>,
770    {
771        self.serve_internal(svc, incoming, Some(signal)).await
772    }
773
774    async fn serve_internal<S, I, F, IO, IE, ResBody>(
775        self,
776        svc: S,
777        incoming: I,
778        signal: Option<F>,
779    ) -> Result<(), super::Error>
780    where
781        L: Layer<S>,
782        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
783        <<L as Layer<S>>::Service as Service<Request<Body>>>::Future: Send,
784        <<L as Layer<S>>::Service as Service<Request<Body>>>::Error:
785            Into<crate::BoxError> + Send + 'static,
786        I: Stream<Item = Result<IO, IE>>,
787        IO: AsyncRead + AsyncWrite + Connected + Unpin + Send + 'static,
788        IE: Into<crate::BoxError>,
789        F: Future<Output = ()>,
790        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
791        ResBody::Error: Into<crate::BoxError>,
792    {
793        let trace_interceptor = self.trace_interceptor.clone();
794        let concurrency_limit = self.concurrency_limit;
795        let load_shed = self.load_shed;
796        let init_connection_window_size = self.init_connection_window_size;
797        let init_stream_window_size = self.init_stream_window_size;
798        let max_concurrent_streams = self.max_concurrent_streams;
799        let timeout = self.timeout;
800        let max_header_list_size = self.http2_max_header_list_size;
801        let max_frame_size = self.max_frame_size;
802        let http2_only = !self.accept_http1;
803
804        let http2_keepalive_interval = self.http2_keepalive_interval;
805        let http2_keepalive_timeout = self.http2_keepalive_timeout;
806        let http2_adaptive_window = self.http2_adaptive_window;
807        let http2_max_pending_accept_reset_streams = self.http2_max_pending_accept_reset_streams;
808        let http2_max_local_error_reset_streams = self.http2_max_local_error_reset_streams;
809        let max_connection_age = self.max_connection_age;
810        let max_connection_age_grace = self.max_connection_age_grace;
811
812        let svc = self.service_builder.service(svc);
813
814        let incoming = io_stream::ServerIoStream::new(
815            incoming,
816            #[cfg(feature = "_tls-any")]
817            self.tls,
818        );
819        let mut svc = MakeSvc {
820            inner: svc,
821            concurrency_limit,
822            load_shed,
823            timeout,
824            trace_interceptor,
825            _io: PhantomData,
826        };
827
828        let server = {
829            let mut builder = ConnectionBuilder::new(TokioExecutor::new());
830
831            if http2_only {
832                builder = builder.http2_only();
833            }
834
835            builder
836                .http2()
837                .timer(TokioTimer::new())
838                .initial_connection_window_size(init_connection_window_size)
839                .initial_stream_window_size(init_stream_window_size)
840                .max_concurrent_streams(max_concurrent_streams)
841                .keep_alive_interval(http2_keepalive_interval)
842                .keep_alive_timeout(http2_keepalive_timeout)
843                .adaptive_window(http2_adaptive_window.unwrap_or_default())
844                .max_pending_accept_reset_streams(http2_max_pending_accept_reset_streams)
845                .max_local_error_reset_streams(http2_max_local_error_reset_streams)
846                .max_frame_size(max_frame_size);
847
848            if let Some(max_header_list_size) = max_header_list_size {
849                builder.http2().max_header_list_size(max_header_list_size);
850            }
851
852            // hyper only enforces its default HTTP/1 header read timeout (30s) when a timer is set.
853            builder.http1().timer(TokioTimer::new());
854
855            builder
856        };
857
858        let (signal_tx, signal_rx) = tokio::sync::watch::channel(());
859        let signal_tx = Arc::new(signal_tx);
860
861        let graceful = signal.is_some();
862        let mut sig = pin!(Fuse { inner: signal });
863
864        // Scope the accept loop so `incoming` is dropped as soon as we stop
865        // accepting. For `TcpIncoming` that closes the listen socket immediately
866        // (kernel stops SYN-ACKing). Holding it until after drain leaves the
867        // port bound: new clients complete TCP, then hang until their deadline.
868        {
869            let mut incoming = pin!(incoming);
870
871            loop {
872                tokio::select! {
873                    _ = &mut sig => {
874                        trace!("signal received, shutting down");
875                        break;
876                    },
877                    io = incoming.next() => {
878                        let io = match io {
879                            Some(Ok(io)) => io,
880                            Some(Err(e)) => {
881                                trace!("error accepting connection: {}", DisplayErrorStack(&*e));
882                                continue;
883                            },
884                            None => {
885                                break
886                            },
887                        };
888
889                        trace!("connection accepted");
890
891                        let req_svc = svc
892                            .call(&io)
893                            .await
894                            .map_err(super::Error::from_source)?;
895
896                        let hyper_io = TokioIo::new(io);
897                        let hyper_svc = TowerToHyperService::new(req_svc.map_request(|req: Request<Incoming>| req.map(Body::new)));
898
899                        serve_connection(hyper_io, hyper_svc, server.clone(), graceful.then(|| signal_rx.clone()), max_connection_age, max_connection_age_grace);
900                    }
901                }
902            }
903        }
904
905        if graceful {
906            let _ = signal_tx.send(());
907            drop(signal_rx);
908            trace!(
909                "waiting for {} connections to close",
910                signal_tx.receiver_count()
911            );
912
913            // Wait for all connections to close
914            signal_tx.closed().await;
915        }
916
917        Ok(())
918    }
919}
920
921enum TimeoutAction {
922    GracefulShutdown,
923    ForcefulShutdown,
924}
925
926async fn connection_timeout_future(
927    max_connection_age: Option<Duration>,
928    max_connection_age_grace: Option<Duration>,
929) -> TimeoutAction {
930    if let Some(age) = max_connection_age {
931        tokio::time::sleep(age).await;
932
933        if let Some(grace) = max_connection_age_grace {
934            tokio::time::sleep(grace).await;
935            TimeoutAction::ForcefulShutdown
936        } else {
937            TimeoutAction::GracefulShutdown
938        }
939    } else {
940        future::pending().await
941    }
942}
943
944// This is moved to its own function as a way to get around
945// https://github.com/rust-lang/rust/issues/102211
946fn serve_connection<B, IO, S, E>(
947    hyper_io: IO,
948    hyper_svc: S,
949    builder: ConnectionBuilder<E>,
950    mut watcher: Option<tokio::sync::watch::Receiver<()>>,
951    max_connection_age: Option<Duration>,
952    max_connection_age_grace: Option<Duration>,
953) where
954    B: http_body::Body + Send + 'static,
955    B::Data: Send,
956    B::Error: Into<Box<dyn std::error::Error + Send + Sync>> + Send + Sync,
957    IO: hyper::rt::Read + hyper::rt::Write + Unpin + Send + 'static,
958    S: HyperService<Request<Incoming>, Response = Response<B>> + Clone + Send + 'static,
959    S::Future: Send + 'static,
960    S::Error: Into<Box<dyn std::error::Error + Send + Sync>> + Send,
961    E: HttpServerConnExec<S::Future, B> + Send + Sync + 'static,
962{
963    tokio::spawn(async move {
964        {
965            let mut sig = pin!(Fuse {
966                inner: watcher.as_mut().map(|w| w.changed()),
967            });
968
969            let mut conn = pin!(builder.serve_connection(hyper_io, hyper_svc));
970
971            let mut connection_timeout = pin!(Fuse {
972                inner: Some(connection_timeout_future(
973                    max_connection_age,
974                    max_connection_age_grace,
975                )),
976            });
977
978            loop {
979                tokio::select! {
980                    rv = &mut conn => {
981                        if let Err(err) = rv {
982                            debug!("failed serving connection: {}", DisplayErrorStack(&*err));
983                        }
984                        break;
985                    },
986                    timeout_action = &mut connection_timeout => {
987                        match timeout_action {
988                            TimeoutAction::GracefulShutdown => {
989                                conn.as_mut().graceful_shutdown();
990                            },
991                            TimeoutAction::ForcefulShutdown => {
992                                debug!("forcefully closed connection");
993                                break;
994                            }
995                        }
996                    },
997                    _ = &mut sig => {
998                        conn.as_mut().graceful_shutdown();
999                    },
1000                }
1001            }
1002        }
1003
1004        drop(watcher);
1005        trace!("connection closed");
1006    });
1007}
1008
1009#[cfg(feature = "router")]
1010impl<L> Router<L> {
1011    pub(crate) fn new(server: Server<L>, routes: Routes) -> Self {
1012        Self { server, routes }
1013    }
1014}
1015
1016#[cfg(feature = "router")]
1017impl<L> Router<L> {
1018    /// Add a new service to this router.
1019    pub fn add_service<S>(mut self, svc: S) -> Self
1020    where
1021        S: Service<Request<Body>, Error = Infallible>
1022            + NamedService
1023            + Clone
1024            + Send
1025            + Sync
1026            + 'static,
1027        S::Response: axum::response::IntoResponse,
1028        S::Future: Send + 'static,
1029    {
1030        self.routes = self.routes.add_service(svc);
1031        self
1032    }
1033
1034    /// Add a new optional service to this router.
1035    ///
1036    /// # Note
1037    /// Even when the argument given is `None` this will capture *all* requests to this service name.
1038    /// As a result, one cannot use this to toggle between two identically named implementations.
1039    pub fn add_optional_service<S>(mut self, svc: Option<S>) -> Self
1040    where
1041        S: Service<Request<Body>, Error = Infallible>
1042            + NamedService
1043            + Clone
1044            + Send
1045            + Sync
1046            + 'static,
1047        S::Response: axum::response::IntoResponse,
1048        S::Future: Send + 'static,
1049    {
1050        if let Some(svc) = svc {
1051            self.routes = self.routes.add_service(svc);
1052        }
1053        self
1054    }
1055
1056    /// Consume this [`Server`] creating a future that will execute the server
1057    /// on [tokio]'s default executor.
1058    ///
1059    /// [`Server`]: struct.Server.html
1060    /// [tokio]: https://docs.rs/tokio
1061    pub async fn serve<ResBody>(self, addr: SocketAddr) -> Result<(), super::Error>
1062    where
1063        L: Layer<Routes> + Clone,
1064        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
1065        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Future: Send,
1066        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Error:
1067            Into<crate::BoxError> + Send,
1068        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
1069        ResBody::Error: Into<crate::BoxError>,
1070    {
1071        self.server.serve(addr, self.routes.prepare()).await
1072    }
1073
1074    /// Consume this [`Server`] creating a future that will execute the server
1075    /// on [tokio]'s default executor. And shutdown when the provided signal
1076    /// is received.
1077    ///
1078    /// [`Server`]: struct.Server.html
1079    /// [tokio]: https://docs.rs/tokio
1080    pub async fn serve_with_shutdown<F: Future<Output = ()>, ResBody>(
1081        self,
1082        addr: SocketAddr,
1083        signal: F,
1084    ) -> Result<(), super::Error>
1085    where
1086        L: Layer<Routes>,
1087        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
1088        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Future: Send,
1089        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Error:
1090            Into<crate::BoxError> + Send,
1091        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
1092        ResBody::Error: Into<crate::BoxError>,
1093    {
1094        self.server
1095            .serve_with_shutdown(addr, self.routes.prepare(), signal)
1096            .await
1097    }
1098
1099    /// Consume this [`Server`] creating a future that will execute the server
1100    /// on the provided incoming stream of `AsyncRead + AsyncWrite`.
1101    ///
1102    /// This method discards any provided [`Server`] TCP configuration.
1103    ///
1104    /// [`Server`]: struct.Server.html
1105    pub async fn serve_with_incoming<I, IO, IE, ResBody>(
1106        self,
1107        incoming: I,
1108    ) -> Result<(), super::Error>
1109    where
1110        I: Stream<Item = Result<IO, IE>>,
1111        IO: AsyncRead + AsyncWrite + Connected + Unpin + Send + 'static,
1112        IE: Into<crate::BoxError>,
1113        L: Layer<Routes>,
1114        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
1115        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Future: Send,
1116        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Error:
1117            Into<crate::BoxError> + Send,
1118        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
1119        ResBody::Error: Into<crate::BoxError>,
1120    {
1121        self.server
1122            .serve_with_incoming(self.routes.prepare(), incoming)
1123            .await
1124    }
1125
1126    /// Consume this [`Server`] creating a future that will execute the server
1127    /// on the provided incoming stream of `AsyncRead + AsyncWrite`. Similar to
1128    /// `serve_with_shutdown` this method will also take a signal future to
1129    /// gracefully shutdown the server.
1130    ///
1131    /// When `signal` completes, `incoming` is dropped immediately (closing a
1132    /// TCP listener) and already-accepted connections are then drained.
1133    ///
1134    /// This method discards any provided [`Server`] TCP configuration.
1135    ///
1136    /// [`Server`]: struct.Server.html
1137    pub async fn serve_with_incoming_shutdown<I, IO, IE, F, ResBody>(
1138        self,
1139        incoming: I,
1140        signal: F,
1141    ) -> Result<(), super::Error>
1142    where
1143        I: Stream<Item = Result<IO, IE>>,
1144        IO: AsyncRead + AsyncWrite + Connected + Unpin + Send + 'static,
1145        IE: Into<crate::BoxError>,
1146        F: Future<Output = ()>,
1147        L: Layer<Routes>,
1148        L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
1149        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Future: Send,
1150        <<L as Layer<Routes>>::Service as Service<Request<Body>>>::Error:
1151            Into<crate::BoxError> + Send,
1152        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
1153        ResBody::Error: Into<crate::BoxError>,
1154    {
1155        self.server
1156            .serve_with_incoming_shutdown(self.routes.prepare(), incoming, signal)
1157            .await
1158    }
1159}
1160
1161impl<L> fmt::Debug for Server<L> {
1162    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1163        f.debug_struct("Builder").finish()
1164    }
1165}
1166
1167#[derive(Clone)]
1168struct Svc<S> {
1169    inner: S,
1170    trace_interceptor: Option<TraceInterceptor>,
1171}
1172
1173impl<S, ResBody> Service<Request<Body>> for Svc<S>
1174where
1175    S: Service<Request<Body>, Response = Response<ResBody>>,
1176    S::Error: Into<crate::BoxError>,
1177    ResBody: http_body::Body<Data = Bytes> + Send + 'static,
1178    ResBody::Error: Into<crate::BoxError>,
1179{
1180    type Response = Response<Body>;
1181    type Error = crate::BoxError;
1182    type Future = SvcFuture<S::Future>;
1183
1184    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
1185        self.inner.poll_ready(cx).map_err(Into::into)
1186    }
1187
1188    fn call(&mut self, mut req: Request<Body>) -> Self::Future {
1189        let span = if let Some(trace_interceptor) = &self.trace_interceptor {
1190            let (parts, body) = req.into_parts();
1191            let bodyless_request = Request::from_parts(parts, ());
1192
1193            let span = trace_interceptor(&bodyless_request);
1194
1195            let (parts, _) = bodyless_request.into_parts();
1196            req = Request::from_parts(parts, body);
1197
1198            span
1199        } else {
1200            tracing::Span::none()
1201        };
1202
1203        SvcFuture {
1204            inner: self.inner.call(req),
1205            span,
1206        }
1207    }
1208}
1209
1210#[pin_project]
1211struct SvcFuture<F> {
1212    #[pin]
1213    inner: F,
1214    span: tracing::Span,
1215}
1216
1217impl<F, E, ResBody> Future for SvcFuture<F>
1218where
1219    F: Future<Output = Result<Response<ResBody>, E>>,
1220    E: Into<crate::BoxError>,
1221    ResBody: http_body::Body<Data = Bytes> + Send + 'static,
1222    ResBody::Error: Into<crate::BoxError>,
1223{
1224    type Output = Result<Response<Body>, crate::BoxError>;
1225
1226    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1227        let this = self.project();
1228        let _guard = this.span.enter();
1229
1230        let response: Response<ResBody> = ready!(this.inner.poll(cx)).map_err(Into::into)?;
1231        let response = response.map(|body| Body::new(body.map_err(Into::into)));
1232        Poll::Ready(Ok(response))
1233    }
1234}
1235
1236impl<S> fmt::Debug for Svc<S> {
1237    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1238        f.debug_struct("Svc").finish()
1239    }
1240}
1241
1242#[derive(Clone)]
1243struct MakeSvc<S, IO> {
1244    concurrency_limit: Option<usize>,
1245    load_shed: bool,
1246    timeout: Option<Duration>,
1247    inner: S,
1248    trace_interceptor: Option<TraceInterceptor>,
1249    _io: PhantomData<fn() -> IO>,
1250}
1251
1252impl<S, ResBody, IO> Service<&ServerIo<IO>> for MakeSvc<S, IO>
1253where
1254    IO: Connected + 'static,
1255    S: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
1256    S::Future: Send,
1257    S::Error: Into<crate::BoxError> + Send,
1258    ResBody: http_body::Body<Data = Bytes> + Send + 'static,
1259    ResBody::Error: Into<crate::BoxError>,
1260{
1261    type Response = BoxService;
1262    type Error = crate::BoxError;
1263    type Future = future::Ready<Result<Self::Response, Self::Error>>;
1264
1265    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
1266        Ok(()).into()
1267    }
1268
1269    fn call(&mut self, io: &ServerIo<IO>) -> Self::Future {
1270        let conn_info = io.connect_info();
1271
1272        let svc = self.inner.clone();
1273        let concurrency_limit = self.concurrency_limit;
1274        let timeout = self.timeout;
1275        let trace_interceptor = self.trace_interceptor.clone();
1276
1277        let svc = ServiceBuilder::new()
1278            .layer(RecoverErrorLayer::new())
1279            .option_layer(self.load_shed.then_some(LoadShedLayer::new()))
1280            .option_layer(concurrency_limit.map(ConcurrencyLimitLayer::new))
1281            .layer_fn(|s| GrpcTimeout::new(s, timeout))
1282            .service(svc);
1283
1284        let svc = ServiceBuilder::new()
1285            .layer(BoxCloneService::layer())
1286            .layer(ConnectInfoLayer::new(conn_info.clone()))
1287            .service(Svc {
1288                inner: svc,
1289                trace_interceptor,
1290            });
1291
1292        future::ready(Ok(svc))
1293    }
1294}
1295
1296// From `futures-util` crate, borrowed since this is the only dependency tonic requires.
1297// LICENSE: MIT or Apache-2.0
1298// A future which only yields `Poll::Ready` once, and thereafter yields `Poll::Pending`.
1299#[pin_project]
1300struct Fuse<F> {
1301    #[pin]
1302    inner: Option<F>,
1303}
1304
1305impl<F> Future for Fuse<F>
1306where
1307    F: Future,
1308{
1309    type Output = F::Output;
1310
1311    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1312        match self.as_mut().project().inner.as_pin_mut() {
1313            Some(fut) => fut.poll(cx).map(|output| {
1314                self.project().inner.set(None);
1315                output
1316            }),
1317            None => Poll::Pending,
1318        }
1319    }
1320}
1321
1322#[cfg(test)]
1323mod tests {
1324    use super::*;
1325    use crate::transport::Server;
1326    use std::time::Duration;
1327
1328    #[tokio::test(start_paused = true)]
1329    async fn test_connection_timeout_no_max_age() {
1330        let future = connection_timeout_future(None, None);
1331
1332        tokio::select! {
1333            _ = future => {
1334                panic!("timeout future should never complete when max_connection_age is None");
1335            }
1336            _ = tokio::time::sleep(Duration::from_secs(1000)) => {
1337            }
1338        }
1339    }
1340
1341    #[tokio::test(start_paused = true)]
1342    async fn test_connection_timeout_with_max_connection_age() {
1343        let future = connection_timeout_future(Some(Duration::from_secs(10)), None);
1344
1345        let action = future.await;
1346        assert!(matches!(action, TimeoutAction::GracefulShutdown));
1347    }
1348
1349    #[tokio::test(start_paused = true)]
1350    async fn test_connection_timeout_with_max_connection_age_grace() {
1351        let mut future = pin!(connection_timeout_future(
1352            Some(Duration::from_secs(10)),
1353            Some(Duration::from_secs(5)),
1354        ));
1355
1356        tokio::select! {
1357            _ = &mut future => {
1358                panic!("should not complete before max_connection_age");
1359            }
1360            _ = tokio::time::sleep(Duration::from_secs(9)) => {}
1361        }
1362
1363        tokio::select! {
1364            _ = &mut future => {
1365                panic!("should not complete before max_connection_age_grace");
1366            }
1367            _ = tokio::time::sleep(Duration::from_secs(4)) => {}
1368        }
1369
1370        let action = future.await;
1371        assert!(matches!(action, TimeoutAction::ForcefulShutdown));
1372    }
1373
1374    #[tokio::test(start_paused = true)]
1375    async fn test_connection_timeout_polled_after_graceful_shutdown() {
1376        // Reproduce #2522: connection_timeout polled after GracefulShutdown
1377        let mut future = pin!(Fuse {
1378            inner: Some(connection_timeout_future(
1379                Some(Duration::from_secs(10)),
1380                None,
1381            ))
1382        });
1383
1384        // First poll: should return GracefulShutdown after 10s
1385        let action = tokio::select! {
1386            action = &mut future => action,
1387            _ = tokio::time::sleep(Duration::from_secs(11)) => {
1388                panic!("timeout future should complete after max_connection_age");
1389            }
1390        };
1391        assert!(matches!(action, TimeoutAction::GracefulShutdown));
1392
1393        // Second poll: Fuse should return Pending, not panic
1394        tokio::select! {
1395            _ = &mut future => {
1396                panic!("fused future should not complete again");
1397            }
1398            _ = tokio::time::sleep(Duration::from_secs(1)) => {
1399                // OK: future is fused, returns Pending
1400            }
1401        }
1402    }
1403
1404    #[test]
1405    fn server_tcp_defaults() {
1406        const EXAMPLE_TCP_KEEPALIVE: Duration = Duration::from_secs(10);
1407        const EXAMPLE_TCP_KEEPALIVE_INTERVAL: Duration = Duration::from_secs(5);
1408        const EXAMPLE_TCP_KEEPALIVE_RETRIES: u32 = 3;
1409
1410        // Using ::builder() or ::default() should do the same thing
1411        let server_via_builder = Server::builder();
1412        assert!(server_via_builder.tcp_nodelay);
1413        assert_eq!(server_via_builder.tcp_keepalive, None);
1414        assert_eq!(server_via_builder.tcp_keepalive_interval, None);
1415        assert_eq!(server_via_builder.tcp_keepalive_retries, None);
1416        let server_via_default = Server::default();
1417        assert!(server_via_default.tcp_nodelay);
1418        assert_eq!(server_via_default.tcp_keepalive, None);
1419        assert_eq!(server_via_default.tcp_keepalive_interval, None);
1420        assert_eq!(server_via_default.tcp_keepalive_retries, None);
1421
1422        // overriding should be possible
1423        let server_via_builder = Server::builder()
1424            .tcp_nodelay(false)
1425            .tcp_keepalive(Some(EXAMPLE_TCP_KEEPALIVE))
1426            .tcp_keepalive_interval(Some(EXAMPLE_TCP_KEEPALIVE_INTERVAL))
1427            .tcp_keepalive_retries(Some(EXAMPLE_TCP_KEEPALIVE_RETRIES));
1428        assert!(!server_via_builder.tcp_nodelay);
1429        assert_eq!(
1430            server_via_builder.tcp_keepalive,
1431            Some(EXAMPLE_TCP_KEEPALIVE)
1432        );
1433        assert_eq!(
1434            server_via_builder.tcp_keepalive_interval,
1435            Some(EXAMPLE_TCP_KEEPALIVE_INTERVAL)
1436        );
1437        assert_eq!(
1438            server_via_builder.tcp_keepalive_retries,
1439            Some(EXAMPLE_TCP_KEEPALIVE_RETRIES)
1440        );
1441    }
1442
1443    #[tokio::test]
1444    async fn http1_header_read_timeout_is_enforced() {
1445        use tokio::io::{AsyncReadExt, AsyncWriteExt};
1446
1447        let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
1448        let addr = listener.local_addr().unwrap();
1449        tokio::spawn(
1450            Server::builder()
1451                .accept_http1(true)
1452                .add_routes(Routes::default())
1453                .serve_with_incoming(TcpIncoming::from(listener)),
1454        );
1455
1456        let mut client = tokio::net::TcpStream::connect(addr).await.unwrap();
1457        client
1458            .write_all(b"POST / HTTP/1.1\r\nHost: x\r\n")
1459            .await
1460            .unwrap();
1461
1462        // Let the server start reading the request head, then jump past hyper's default 30s
1463        // header read timeout. Auto-advance is avoided on purpose: it races with socket I/O.
1464        tokio::time::sleep(Duration::from_millis(200)).await;
1465        tokio::time::pause();
1466        tokio::time::advance(Duration::from_secs(31)).await;
1467        tokio::time::resume();
1468
1469        let mut buf = [0u8; 64];
1470        let read = tokio::time::timeout(Duration::from_secs(5), client.read(&mut buf)).await;
1471        assert!(
1472            read.is_ok(),
1473            "connection with unfinished HTTP/1 headers was not closed"
1474        );
1475    }
1476}