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}