h3/server/
builder.rs

1//! Builder of HTTP/3 server connections.
2//!
3//! Use this struct to create a new [`Connection`].
4//! Settings for the [`Connection`] can be provided here.
5//!
6//! # Example
7//!
8//! ```rust
9//! fn doc<C,B>(conn: C)
10//! where
11//! C: h3::quic::Connection<B>,
12//! B: bytes::Buf,
13//! {
14//!     let mut server_builder = h3::server::builder();
15//!     // Set the maximum header size
16//!     server_builder.max_field_section_size(1000);
17//!     // do not send grease types
18//!     server_builder.send_grease(false);
19//!     // Build the Connection
20//!     let mut h3_conn = server_builder.build(conn);
21//! }
22//! ```
23
24use std::{collections::HashSet, result::Result, sync::Arc};
25
26use bytes::Buf;
27
28use tokio::sync::mpsc;
29
30use crate::{
31    config::Config,
32    connection::ConnectionInner,
33    error::ConnectionError,
34    quic::{self},
35    shared_state::SharedState,
36};
37
38use super::connection::Connection;
39
40/// Create a builder of HTTP/3 server connections
41///
42/// This function creates a [`Builder`] that carries settings that can
43/// be shared between server connections.
44pub fn builder() -> Builder {
45    Builder::new()
46}
47
48/// Builder of HTTP/3 server connections.
49pub struct Builder {
50    pub(crate) config: Config,
51}
52
53impl Builder {
54    /// Creates a new [`Builder`] with default settings.
55    pub(super) fn new() -> Self {
56        Builder {
57            config: Default::default(),
58        }
59    }
60
61    // Not public API, just used in unit tests
62    #[doc(hidden)]
63    #[cfg(test)]
64    pub fn send_settings(&mut self, value: bool) -> &mut Self {
65        self.config.send_settings = value;
66        self
67    }
68
69    /// Set the maximum header size this client is willing to accept
70    ///
71    /// See [header size constraints] section of the specification for details.
72    ///
73    /// [header size constraints]: https://www.rfc-editor.org/rfc/rfc9114.html#name-header-size-constraints
74    pub fn max_field_section_size(&mut self, value: u64) -> &mut Self {
75        self.config.settings.max_field_section_size = value;
76        self
77    }
78
79    /// Send grease values to the Client.
80    /// See [setting](https://www.rfc-editor.org/rfc/rfc9114.html#settings-parameters), [frame](https://www.rfc-editor.org/rfc/rfc9114.html#frame-reserved) and [stream](https://www.rfc-editor.org/rfc/rfc9114.html#stream-grease) for more information.
81    #[inline]
82    pub fn send_grease(&mut self, value: bool) -> &mut Self {
83        self.config.send_grease = value;
84        self
85    }
86
87    /// Indicates to the peer that WebTransport is supported.
88    ///
89    /// See: [establishing a webtransport session](https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3/#section-3.1)
90    ///
91    ///
92    /// **Server**:
93    /// Supporting for webtransport also requires setting `enable_extended_connect` `enable_datagram`
94    /// and `max_webtransport_sessions`.
95    #[inline]
96    pub fn enable_webtransport(&mut self, value: bool) -> &mut Self {
97        self.config.settings.enable_webtransport = value;
98        self
99    }
100
101    /// Enables the extended CONNECT protocol required for various HTTP/3 extensions.
102    pub fn enable_extended_connect(&mut self, value: bool) -> &mut Self {
103        self.config.settings.enable_extended_connect = value;
104        self
105    }
106
107    /// Limits the maximum number of WebTransport sessions
108    pub fn max_webtransport_sessions(&mut self, value: u64) -> &mut Self {
109        self.config.settings.max_webtransport_sessions = value;
110        self
111    }
112
113    /// Indicates that the client or server supports HTTP/3 datagrams
114    ///
115    /// See: <https://www.rfc-editor.org/rfc/rfc9297#section-2.1.1>
116    pub fn enable_datagram(&mut self, value: bool) -> &mut Self {
117        self.config.settings.enable_datagram = value;
118        self
119    }
120}
121
122impl Builder {
123    /// Build an HTTP/3 connection from a QUIC connection
124    ///
125    /// This method creates a [`Connection`] instance with the settings in the [`Builder`].
126    pub async fn build<C, B>(&self, conn: C) -> Result<Connection<C, B>, ConnectionError>
127    where
128        C: quic::Connection<B>,
129        B: Buf,
130    {
131        let (sender, receiver) = mpsc::unbounded_channel();
132        let shared = SharedState::default();
133
134        Ok(Connection {
135            inner: ConnectionInner::new(conn, Arc::new(shared), self.config).await?,
136            max_field_section_size: self.config.settings.max_field_section_size,
137            request_end_send: sender,
138            request_end_recv: receiver,
139            ongoing_streams: HashSet::new(),
140            sent_closing: None,
141            recv_closing: None,
142            last_accepted_stream: None,
143        })
144    }
145}