1use bytes::{Buf, BufMut, Bytes};
2use url::Url;
3
4pub use web_transport_quinn as quinn;
6
7pub use web_transport_quinn::CongestionControl;
8
9#[derive(Default, Clone)]
11pub struct ClientBuilder {
12 inner: quinn::ClientBuilder,
13 protocols: Vec<String>,
14}
15
16impl ClientBuilder {
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 pub fn with_congestion_control(self, cc: CongestionControl) -> Self {
23 Self {
24 inner: self.inner.with_congestion_control(cc),
25 ..self
26 }
27 }
28
29 pub fn with_protocols<I, S>(mut self, protocols: I) -> Self
33 where
34 I: IntoIterator<Item = S>,
35 S: AsRef<str>,
36 {
37 self.protocols = protocols
38 .into_iter()
39 .map(|p| p.as_ref().to_string())
40 .collect();
41 self
42 }
43
44 pub fn with_server_certificate_hashes(self, hashes: Vec<Vec<u8>>) -> Result<Client, Error> {
46 Ok(Client {
47 inner: self.inner.with_server_certificate_hashes(hashes)?,
48 protocols: self.protocols,
49 })
50 }
51
52 pub fn with_system_roots(self) -> Result<Client, Error> {
54 Ok(Client {
55 inner: self.inner.with_system_roots()?,
56 protocols: self.protocols,
57 })
58 }
59}
60
61#[derive(Clone, Debug)]
63pub struct Client {
64 inner: quinn::Client,
65 protocols: Vec<String>,
66}
67
68impl Client {
69 pub async fn connect(&self, url: Url) -> Result<Session, Error> {
71 let request =
72 quinn::proto::ConnectRequest::new(url).with_protocols(self.protocols.iter().cloned());
73 Ok(self.inner.connect(request).await?.into())
74 }
75}
76
77pub struct Server {
84 inner: quinn::Server,
85}
86
87impl From<quinn::Server> for Server {
88 fn from(server: quinn::Server) -> Self {
89 Self { inner: server }
90 }
91}
92
93impl Server {
94 pub async fn accept(&mut self) -> Result<Option<Session>, Error> {
96 match self.inner.accept().await {
97 Some(session) => Ok(Some(session.ok().await?.into())),
99 None => Ok(None),
100 }
101 }
102}
103
104#[derive(Clone, PartialEq, Eq)]
109pub struct Session {
110 inner: quinn::Session,
111}
112
113impl Session {
114 pub async fn accept_uni(&self) -> Result<RecvStream, Error> {
118 let stream = self.inner.accept_uni().await?;
119 Ok(RecvStream::new(stream))
120 }
121
122 pub async fn accept_bi(&self) -> Result<(SendStream, RecvStream), Error> {
124 let (s, r) = self.inner.accept_bi().await?;
125 Ok((SendStream::new(s), RecvStream::new(r)))
126 }
127
128 pub async fn open_bi(&self) -> Result<(SendStream, RecvStream), Error> {
130 Ok(self
131 .inner
132 .open_bi()
133 .await
134 .map(|(s, r)| (SendStream::new(s), RecvStream::new(r)))?)
135 }
136
137 pub async fn open_uni(&self) -> Result<SendStream, Error> {
139 Ok(self.inner.open_uni().await.map(SendStream::new)?)
140 }
141
142 pub async fn send_datagram(&self, payload: Bytes) -> Result<(), Error> {
152 Ok(self.inner.send_datagram(payload)?)
154 }
155
156 pub async fn max_datagram_size(&self) -> usize {
158 self.inner.max_datagram_size()
159 }
160
161 pub async fn recv_datagram(&self) -> Result<Bytes, Error> {
163 Ok(self.inner.read_datagram().await?)
164 }
165
166 pub fn close(&self, code: u32, reason: &str) {
168 self.inner.close(code, reason.as_bytes())
169 }
170
171 pub async fn closed(&self) -> Error {
173 self.inner.closed().await.into()
174 }
175
176 pub fn url(&self) -> Option<&Url> {
179 self.inner.request().map(|request| &request.url)
180 }
181
182 pub fn protocol(&self) -> Option<&str> {
187 self.inner.protocol()
188 }
189}
190
191impl From<quinn::Session> for Session {
193 fn from(session: quinn::Session) -> Self {
194 Session { inner: session }
195 }
196}
197
198pub struct SendStream {
203 inner: quinn::SendStream,
204}
205
206impl SendStream {
207 fn new(inner: quinn::SendStream) -> Self {
208 Self { inner }
209 }
210
211 #[must_use = "returns the number of bytes written"]
213 pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
214 self.inner.write(buf).await.map_err(Into::into)
215 }
216
217 pub async fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Result<usize, Error> {
219 let size = buf.chunk().len();
221 let chunk = buf.copy_to_bytes(size);
222 self.inner.write_chunk(chunk).await?;
223 Ok(size)
224 }
225
226 pub fn set_priority(&mut self, order: i32) {
230 self.inner.set_priority(order).ok();
231 }
232
233 pub fn reset(&mut self, code: u32) {
235 self.inner.reset(code).ok();
236 }
237
238 pub fn finish(&mut self) -> Result<(), Error> {
242 self.inner
243 .finish()
244 .map_err(|_| Error::Write(quinn::WriteError::ClosedStream))?;
245 Ok(())
246 }
247
248 pub async fn closed(&mut self) -> Result<Option<u8>, Error> {
253 match self.inner.stopped().await {
254 Ok(None) => Ok(None),
255 Ok(Some(code)) => Ok(Some(code as u8)),
256 Err(e) => Err(Error::Session(e)),
257 }
258 }
259}
260
261pub struct RecvStream {
266 inner: quinn::RecvStream,
267}
268
269impl RecvStream {
270 fn new(inner: quinn::RecvStream) -> Self {
271 Self { inner }
272 }
273
274 pub async fn read(&mut self, max: usize) -> Result<Option<Bytes>, Error> {
278 Ok(self
279 .inner
280 .read_chunk(max, true)
281 .await?
282 .map(|chunk| chunk.bytes))
283 }
284
285 pub async fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Result<Option<usize>, Error> {
290 let dst = buf.chunk_mut();
291 let dst = unsafe { &mut *(dst as *mut _ as *mut [u8]) };
292
293 let size = match self.inner.read(dst).await? {
294 Some(size) if size > 0 => size,
295 _ => return Ok(None),
296 };
297
298 unsafe { buf.advance_mut(size) };
299
300 Ok(Some(size))
301 }
302
303 pub fn stop(&mut self, code: u32) {
305 self.inner.stop(code).ok();
306 }
307
308 pub async fn closed(&mut self) -> Result<Option<u8>, Error> {
314 match self.inner.received_reset().await {
315 Ok(None) => Ok(None),
316 Ok(Some(code)) => Ok(Some(code as u8)),
317 Err(e) => Err(Error::Session(e)),
318 }
319 }
320}
321
322#[derive(Debug, thiserror::Error, Clone)]
327pub enum Error {
328 #[error("session error: {0}")]
329 Session(#[from] quinn::SessionError),
330
331 #[error("server error: {0}")]
332 Server(#[from] quinn::ServerError),
333
334 #[error("client error: {0}")]
335 Client(#[from] quinn::ClientError),
336
337 #[error("write error: {0}")]
338 Write(quinn::WriteError),
339
340 #[error("read error: {0}")]
341 Read(quinn::ReadError),
342}
343
344impl From<quinn::WriteError> for Error {
345 fn from(e: quinn::WriteError) -> Self {
346 match e {
347 quinn::WriteError::SessionError(e) => Error::Session(e),
348 e => Error::Write(e),
349 }
350 }
351}
352impl From<quinn::ReadError> for Error {
353 fn from(e: quinn::ReadError) -> Self {
354 match e {
355 quinn::ReadError::SessionError(e) => Error::Session(e),
356 e => Error::Read(e),
357 }
358 }
359}