Skip to main content

musli_web/
ws.rs

1//! The server side of the websocket protocol.
2//!
3//! See [`server()`] for how to use with [axum].
4//!
5//! A connection starts life as a [`Connect`], which cannot send anything.
6//! [`Connect::connect`] performs the [negotiation protocol] and hands back the
7//! [`Server`], so by the time there is anything able to write a message the
8//! [`Format`] it will be encoded with has been agreed with the client. A client
9//! which does not negotiate never gets a [`Server`] at all.
10//!
11//! Handlers are implemented via the [`Handler`] trait, which allows returning
12//! various forms of responses dictated through the [`IntoResponse`] trait. This
13//! is primarily implemented for `bool`, where returning `false` indicates that
14//! the given request kind is not supported.
15//!
16//! A handler can also fail a request by returning an error, see
17//! [Errors](#errors) below.
18//!
19//! A connection can carry the lists of several [`define!`] invocations, such
20//! as one shipped by a library beside the application's own. Either one list
21//! [includes] the other and its handler routes the included requests by
22//! matching on their variant, or the handlers of the two lists are combined
23//! with [`Handler::or`], which routes each request to the handler whose list
24//! knows its id. In both cases a clash between the ids of the lists fails to
25//! compile.
26//!
27//! [`define!`]: crate::api::define
28//! [includes]: crate::api::define#including-other-lists
29//!
30//! ```
31//! use musli_web::api::MessageId;
32//! use musli_web::ws;
33//!
34//! mod api {
35//!     use musli::{Decode, Encode};
36//!     use musli_web::api;
37//!
38//!     #[derive(Encode, Decode)]
39//!     pub struct HelloRequest<'de> {
40//!         pub message: &'de str,
41//!     }
42//!
43//!     #[derive(Encode, Decode)]
44//!     pub struct HelloResponse<'de> {
45//!         pub message: &'de str,
46//!     }
47//!
48//!     #[derive(Encode, Decode)]
49//!     pub struct TickEvent<'de> {
50//!         pub message: &'de str,
51//!         pub tick: u32,
52//!     }
53//!
54//!     api::define! {
55//!         pub type Hello;
56//!
57//!         impl Endpoint for Hello {
58//!             impl<'de> Request for HelloRequest<'de>;
59//!             type Response<'de> = HelloResponse<'de>;
60//!         }
61//!
62//!         pub type Tick;
63//!
64//!         impl Broadcast for Tick {
65//!             impl<'de> Event for TickEvent<'de>;
66//!         }
67//!     }
68//! }
69//!
70//! #[derive(Debug, Clone)]
71//! enum Broadcast {
72//!     Tick { tick: u32 },
73//! }
74//!
75//! #[derive(Clone)]
76//! struct MyHandler;
77//!
78//! impl ws::Handler for MyHandler {
79//!     type Id = api::Request;
80//!     type Response = Option<()>;
81//!
82//!     async fn handle(
83//!         &self,
84//!         id: Self::Id,
85//!         incoming: &mut ws::Incoming<'_>,
86//!         outgoing: &mut ws::Outgoing<'_>,
87//!     ) -> Self::Response {
88//!         tracing::info!("Handling: {id:?}");
89//!
90//!         match id {
91//!             api::Request::Hello => {
92//!                 let request = incoming.read::<api::HelloRequest<'_>>()?;
93//!
94//!                 outgoing.write(api::HelloResponse {
95//!                     message: request.message,
96//!                 });
97//!
98//!                 Some(())
99//!             }
100//!             api::Request::Unknown(id) => {
101//!                 tracing::info!("Unknown request id: {}", id.get());
102//!                 None
103//!             }
104//!         }
105//!     }
106//! }
107//! ```
108//!
109//! # Errors
110//!
111//! A handler whose [`Handler::Response`] is a `Result<T, E>` fails the request
112//! it is handling by returning `Err(E)`. What reaches the client depends on
113//! `E`, see [`ResponseError`]:
114//!
115//! * Anything which implements [`fmt::Display`], such as a `String` or an
116//!   `anyhow::Error`, is sent as *text*. The client sees the message through
117//!   `web::Error::as_server_error`.
118//! * A [`TypedError<E>`] is sent as a *typed error*. The value it wraps is
119//!   encoded in the body format of the connection, just like a response, so
120//!   the client can decode it back into `E` with `web::Error::server_error`
121//!   instead of parsing a message. Its [`fmt::Display`] text is sent along as
122//!   the message, so code which only looks at the message keeps working.
123//! * An error type which implements [`ResponseError`] by hand decides for each
124//!   error whether it is typed, which keeps internal failures out of what the
125//!   client is told. See [`ResponseError`] for an example.
126//!
127//! Putting the error type in the API crate shared by the server and the client
128//! keeps the two in agreement:
129//!
130//! ```
131//! use core::fmt;
132//!
133//! use musli_web::ws::{self, TypedError};
134//!
135//! mod api {
136//!     use musli::{Decode, Encode};
137//!     use musli_web::api;
138//!
139//!     /// Why the server refused a request.
140//!     #[derive(Debug, PartialEq, Encode, Decode)]
141//!     pub enum ServerError {
142//!         NotFound,
143//!         Forbidden { reason: String },
144//!     }
145//!
146//!     #[derive(Encode, Decode)]
147//!     pub struct DeleteRequest {
148//!         pub id: u32,
149//!     }
150//!
151//!     #[derive(Encode, Decode)]
152//!     pub struct DeleteResponse;
153//!
154//!     api::define! {
155//!         pub type Delete;
156//!
157//!         impl Endpoint for Delete {
158//!             impl Request for DeleteRequest;
159//!             type Response<'de> = DeleteResponse;
160//!         }
161//!     }
162//! }
163//!
164//! impl fmt::Display for api::ServerError {
165//!     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166//!         match self {
167//!             Self::NotFound => write!(f, "Not found"),
168//!             Self::Forbidden { reason } => write!(f, "Forbidden: {reason}"),
169//!         }
170//!     }
171//! }
172//!
173//! #[derive(Clone)]
174//! struct MyHandler;
175//!
176//! impl ws::Handler for MyHandler {
177//!     type Id = api::Request;
178//!     type Response = Result<bool, TypedError<api::ServerError>>;
179//!
180//!     async fn handle(
181//!         &self,
182//!         id: Self::Id,
183//!         incoming: &mut ws::Incoming<'_>,
184//!         outgoing: &mut ws::Outgoing<'_>,
185//!     ) -> Self::Response {
186//!         match id {
187//!             api::Request::Delete => {
188//!                 let Some(request) = incoming.read::<api::DeleteRequest>() else {
189//!                     return Ok(false);
190//!                 };
191//!
192//!                 if request.id == 0 {
193//!                     // `?` converts into a `TypedError` too.
194//!                     return Err(TypedError(api::ServerError::Forbidden {
195//!                         reason: String::from("The root cannot be deleted"),
196//!                     }));
197//!                 }
198//!
199//!                 outgoing.write(api::DeleteResponse);
200//!                 Ok(true)
201//!             }
202//!             api::Request::Unknown(..) => Ok(false),
203//!         }
204//!     }
205//! }
206//! ```
207//!
208//! On the client, the error such a request fails with decodes back with
209//! `error.server_error::<api::ServerError>()`, which returns `Ok(None)` for an
210//! error which is not typed. See `web::Error::server_error` and
211//! `client::Error::server_error`.
212//!
213//! Errors the server produces on its own, such as for a request no handler
214//! supports or one which could not be decoded, are always text, so a client
215//! should be prepared for a server error which carries no payload.
216//!
217//! # Broadcast origin
218//!
219//! A broadcast can say which channel caused it. When a request over a
220//! channel changes something every client shows, write the resulting
221//! broadcast with [`Server::broadcast_from`] and the [`Incoming::channel`] of
222//! that request as its origin. The client reads the origin back as the
223//! channel of the broadcast packet, so the page which made the change can
224//! recognize its own echo with `web::Packet::is_from` and skip it, while every
225//! other page applies it. There is no need to carry the origin in the body of
226//! the event.
227//!
228//! This relies on channel ids being unique across every connection, since
229//! the broadcast is written by the [`Server`] of each connection and not only
230//! the one the request came in over. That is the default, see
231//! [`ChannelAllocator`].
232//!
233//! ```
234//! use musli_web::api::ChannelId;
235//! use musli_web::ws;
236//! use tokio::sync::broadcast::Sender;
237//!
238//! mod api {
239//!     use musli::{Decode, Encode};
240//!     use musli_web::api;
241//!
242//!     #[derive(Encode, Decode)]
243//!     pub struct RenameRequest<'de> {
244//!         pub name: &'de str,
245//!     }
246//!
247//!     #[derive(Encode, Decode)]
248//!     pub struct RenameResponse;
249//!
250//!     #[derive(Encode, Decode)]
251//!     pub struct RenamedEvent<'de> {
252//!         pub name: &'de str,
253//!     }
254//!
255//!     api::define! {
256//!         pub type Rename;
257//!
258//!         impl Endpoint for Rename {
259//!             impl<'de> Request for RenameRequest<'de>;
260//!             type Response<'de> = RenameResponse;
261//!         }
262//!
263//!         pub type Renamed;
264//!
265//!         impl Broadcast for Renamed {
266//!             impl<'de> Event for RenamedEvent<'de>;
267//!         }
268//!     }
269//! }
270//!
271//! /// A change which every connection forwards to its client.
272//! #[derive(Clone)]
273//! struct Change {
274//!     name: String,
275//!     /// The channel whose request made the change.
276//!     origin: ChannelId,
277//! }
278//!
279//! #[derive(Clone)]
280//! struct MyHandler {
281//!     changes: Sender<Change>,
282//! }
283//!
284//! impl ws::Handler for MyHandler {
285//!     type Id = api::Request;
286//!     type Response = Option<()>;
287//!
288//!     async fn handle(
289//!         &self,
290//!         id: Self::Id,
291//!         incoming: &mut ws::Incoming<'_>,
292//!         outgoing: &mut ws::Outgoing<'_>,
293//!     ) -> Self::Response {
294//!         match id {
295//!             api::Request::Rename => {
296//!                 let request = incoming.read::<api::RenameRequest<'_>>()?;
297//!
298//!                 _ = self.changes.send(Change {
299//!                     name: request.name.to_owned(),
300//!                     origin: incoming.channel(),
301//!                 });
302//!
303//!                 outgoing.write(api::RenameResponse);
304//!                 Some(())
305//!             }
306//!             api::Request::Unknown(..) => None,
307//!         }
308//!     }
309//! }
310//!
311//! /// Called by the connection loop of every connection for each change it
312//! /// receives from the shared sender.
313//! fn forward<S>(server: &mut ws::Server<S, MyHandler>, change: &Change) -> Result<(), ws::Error>
314//! where
315//!     S: ws::ServerImpl,
316//!     ws::Error: From<S::Error>,
317//! {
318//!     server.broadcast_from(api::RenamedEvent { name: &change.name }, change.origin)
319//! }
320//! ```
321//!
322//! The client which sent the request compares the origin to its own channel:
323//!
324//! ```text
325//! if packet.is_from(channel.id()) {
326//!     // Our own change, which is already shown.
327//!     return;
328//! }
329//! ```
330//!
331//! `is_from` is never true for [`ChannelId::NONE`], so a page which has not
332//! opened its channel yet, or a broadcast written with [`Server::broadcast`],
333//! never counts as an echo.
334//!
335//! [`server()`]: crate::axum08::server
336//! [axum]: <https://docs.rs/axum>
337//! [negotiation protocol]: crate::api#negotiating-the-format
338
339use core::convert::Infallible;
340use core::fmt::{self, Write};
341use core::future::Future;
342use core::mem;
343use core::num::NonZeroU16;
344use core::pin::Pin;
345use core::task::{Context, Poll};
346
347use alloc::boxed::Box;
348use alloc::collections::{BTreeSet, VecDeque};
349use alloc::string::String;
350use alloc::sync::Arc;
351use alloc::vec::Vec;
352
353use std::sync::{LazyLock, Mutex, MutexGuard, PoisonError};
354
355use bytes::Bytes;
356use rand::prelude::*;
357use rand::rngs::SmallRng;
358use tokio::task::JoinSet;
359use tokio::time::{Duration, Instant, Sleep};
360
361use crate::Buf;
362use crate::api::{
363    Broadcast, ChannelId, DecodeBody, EncodeBody, ErrorMessage, Event, Format, Id, IdSet,
364    MessageId, Mode, RequestHeader, ResponseHeader, VERSION,
365};
366use crate::buf::{BufPool, InvalidFrame};
367use crate::format;
368
369const MAX_CAPACITY: usize = 1048576;
370const DEFAULT_MAX_IN_FLIGHT: usize = 128;
371const DEFAULT_MAX_OUTBOUND: usize = 8 * 1048576;
372/// The default number of channels one client may hold open at once.
373const DEFAULT_MAX_CHANNELS: usize = 1024;
374const CLOSE_NORMAL: u16 = 1000;
375const CLOSE_PROTOCOL_ERROR: u16 = 1002;
376const CLOSE_POLICY_VIOLATION: u16 = 1008;
377const CLOSE_TIMEOUT: Duration = Duration::from_secs(30);
378const PING_TIMEOUT: Duration = Duration::from_secs(10);
379const DEFAULT_SEED: u64 = 0xdeadbeef;
380
381/// A websocket message.
382#[derive(Debug)]
383pub(crate) enum Message {
384    /// A text message.
385    Text(Bytes),
386    /// A binary message.
387    Binary(Bytes),
388    /// A ping message.
389    Ping(Bytes),
390    /// A pong message.
391    Pong(Bytes),
392    /// A close message.
393    Close,
394}
395
396pub(crate) mod socket_sealed {
397    pub trait Sealed {}
398}
399
400pub(crate) trait SocketImpl
401where
402    Self: self::socket_sealed::Sealed,
403{
404    #[doc(hidden)]
405    type Message;
406
407    #[doc(hidden)]
408    type Error: fmt::Debug;
409
410    #[doc(hidden)]
411    fn poll_next(
412        self: Pin<&mut Self>,
413        ctx: &mut Context<'_>,
414    ) -> Poll<Option<Result<Message, Self::Error>>>;
415
416    #[doc(hidden)]
417    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
418
419    #[doc(hidden)]
420    fn start_send(self: Pin<&mut Self>, item: Self::Message) -> Result<(), Self::Error>;
421
422    #[doc(hidden)]
423    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
424}
425
426pub(crate) mod server_sealed {
427    pub trait Sealed {}
428}
429
430/// The details of how a [`Server`] is implemented.
431///
432/// See [`AxumServer`] for an example.
433///
434/// [`AxumServer`]: crate::axum08::AxumServer
435pub trait ServerImpl
436where
437    Self: self::server_sealed::Sealed,
438{
439    #[doc(hidden)]
440    type Error: fmt::Debug;
441
442    #[doc(hidden)]
443    type Message;
444
445    #[doc(hidden)]
446    #[allow(private_bounds)]
447    type Socket: SocketImpl<Message = Self::Message, Error = Self::Error>;
448
449    #[doc(hidden)]
450    fn ping(data: Bytes) -> Self::Message;
451
452    #[doc(hidden)]
453    fn pong(data: Bytes) -> Self::Message;
454
455    #[doc(hidden)]
456    fn binary(data: &[u8]) -> Self::Message;
457
458    #[doc(hidden)]
459    fn text(data: &[u8]) -> Self::Message;
460
461    #[doc(hidden)]
462    fn close(code: u16, reason: &str) -> Self::Message;
463}
464
465#[derive(Debug)]
466enum ErrorKind {
467    #[cfg(feature = "axum-core05")]
468    AxumCore05 {
469        error: axum_core05::Error,
470    },
471    FormatError,
472    InvalidFrame {
473        error: InvalidFrame,
474    },
475    Incoming {
476        error: format::Error,
477    },
478    Outgoing {
479        error: format::Error,
480    },
481    EncodeBroadcastHeader {
482        error: format::Error,
483    },
484    EncodeBroadcast {
485        error: format::Error,
486    },
487    EncodeConnectHeader {
488        error: format::Error,
489    },
490    ErrorMessageHeader {
491        error: format::Error,
492    },
493    ErrorMessage {
494        error: format::Error,
495    },
496    EncodeErrorPayload {
497        error: format::Error,
498    },
499    OutOfBounds {
500        offset: usize,
501        len: usize,
502    },
503    /// The connection went away before the format had been negotiated.
504    NotNegotiated,
505    /// The client sent a message other than a negotiation as its first message.
506    ExpectedNegotiate {
507        id: u16,
508    },
509    /// The client sent a malformed envelope during negotiation.
510    NegotiateHeader {
511        error: format::Error,
512    },
513    /// The client wrote a header this build does not know about, which means it
514    /// is speaking a protocol this server does not have.
515    UnknownHeader {
516        error: format::Error,
517    },
518    /// The client stated a protocol version this server does not speak.
519    UnsupportedVersion {
520        error: format::Error,
521    },
522    /// The client stated an application version other than the one this
523    /// server states, see [`Connect::app_version`].
524    Incompatible {
525        server: u32,
526        client: u32,
527    },
528}
529
530/// The error produced by the server side of the websocket protocol
531#[derive(Debug)]
532pub struct Error {
533    kind: ErrorKind,
534}
535
536impl Error {
537    #[inline]
538    const fn new(kind: ErrorKind) -> Self {
539        Self { kind }
540    }
541
542    pub(crate) fn incoming(error: format::Error) -> Self {
543        Self::new(ErrorKind::Incoming { error })
544    }
545
546    pub(crate) fn outgoing(error: format::Error) -> Self {
547        Self::new(ErrorKind::Outgoing { error })
548    }
549
550    pub(crate) fn encode_broadcast_header(error: format::Error) -> Self {
551        Self::new(ErrorKind::EncodeBroadcastHeader { error })
552    }
553
554    pub(crate) fn encode_broadcast(error: format::Error) -> Self {
555        Self::new(ErrorKind::EncodeBroadcast { error })
556    }
557
558    pub(crate) fn encode_connect_header(error: format::Error) -> Self {
559        Self::new(ErrorKind::EncodeConnectHeader { error })
560    }
561
562    pub(crate) fn encode_error_message_header(error: format::Error) -> Self {
563        Self::new(ErrorKind::ErrorMessageHeader { error })
564    }
565
566    pub(crate) fn encode_error_message(error: format::Error) -> Self {
567        Self::new(ErrorKind::ErrorMessage { error })
568    }
569
570    /// Test if the connection was refused because the client states an
571    /// application version other than the one this server states.
572    ///
573    /// This is what [`Connect::connect`] fails with for a client built against
574    /// a different version of the application's API, see
575    /// [`Connect::app_version`]. It is the client which is out of date (or the
576    /// server), not the connection which is broken, so it is usually worth
577    /// logging at a lower level than other errors.
578    #[inline]
579    pub fn is_incompatible(&self) -> bool {
580        matches!(self.kind, ErrorKind::Incompatible { .. })
581    }
582}
583
584impl fmt::Display for Error {
585    #[inline]
586    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587        match &self.kind {
588            #[cfg(feature = "axum-core05")]
589            ErrorKind::AxumCore05 { .. } => write!(f, "Error in axum-core"),
590            ErrorKind::FormatError => write!(f, "Error formatting error response"),
591            ErrorKind::InvalidFrame { error } => error.fmt(f),
592            ErrorKind::Incoming { .. } => {
593                write!(f, "Encoding error when decoding incoming message")
594            }
595            ErrorKind::Outgoing { .. } => {
596                write!(f, "Encoding error when encoding outgoing message")
597            }
598            ErrorKind::EncodeBroadcastHeader { .. } => {
599                write!(f, "Encoding error when encoding broadcast header")
600            }
601            ErrorKind::EncodeBroadcast { .. } => {
602                write!(f, "Encoding error when broadcasting message")
603            }
604            ErrorKind::EncodeConnectHeader { .. } => {
605                write!(f, "Encoding error when encoding connect header")
606            }
607            ErrorKind::ErrorMessageHeader { .. } => {
608                write!(f, "Encoding error when encoding error message header")
609            }
610            ErrorKind::ErrorMessage { .. } => {
611                write!(f, "Encoding error when encoding error message")
612            }
613            ErrorKind::EncodeErrorPayload { .. } => {
614                write!(f, "Encoding error when encoding typed error")
615            }
616            ErrorKind::OutOfBounds { offset, len } => {
617                write!(
618                    f,
619                    "Error when reading message: offset {} is out of bounds for length {}",
620                    offset, len
621                )
622            }
623            ErrorKind::NotNegotiated => {
624                write!(f, "Connection closed before the format was negotiated")
625            }
626            ErrorKind::ExpectedNegotiate { id } => {
627                write!(
628                    f,
629                    "Expected a negotiation as the first message, but got message id {id}"
630                )
631            }
632            ErrorKind::NegotiateHeader { .. } => {
633                write!(f, "Encoding error when decoding negotiation header")
634            }
635            ErrorKind::UnknownHeader { error } => {
636                write!(f, "Client sent a header this server does not know: {error}")
637            }
638            ErrorKind::UnsupportedVersion { error } => {
639                write!(f, "Client speaks a different protocol: {error}")
640            }
641            ErrorKind::Incompatible { server, client } => {
642                write!(
643                    f,
644                    "Client states application version {client}, this server states {server}"
645                )
646            }
647        }
648    }
649}
650
651impl core::error::Error for Error {
652    #[inline]
653    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
654        match &self.kind {
655            #[cfg(feature = "axum-core05")]
656            ErrorKind::AxumCore05 { error } => Some(error),
657            ErrorKind::Incoming { error } => Some(error),
658            ErrorKind::Outgoing { error } => Some(error),
659            ErrorKind::EncodeBroadcastHeader { error } => Some(error),
660            ErrorKind::EncodeBroadcast { error } => Some(error),
661            ErrorKind::EncodeConnectHeader { error } => Some(error),
662            ErrorKind::ErrorMessageHeader { error } => Some(error),
663            ErrorKind::ErrorMessage { error } => Some(error),
664            ErrorKind::EncodeErrorPayload { error } => Some(error),
665            ErrorKind::NegotiateHeader { error } => Some(error),
666            ErrorKind::UnknownHeader { error } => Some(error),
667            ErrorKind::UnsupportedVersion { error } => Some(error),
668            _ => None,
669        }
670    }
671}
672
673#[cfg(feature = "axum-core05")]
674impl From<axum_core05::Error> for Error {
675    #[inline]
676    fn from(error: axum_core05::Error) -> Self {
677        Self::new(ErrorKind::AxumCore05 { error })
678    }
679}
680
681impl From<ErrorKind> for Error {
682    #[inline]
683    fn from(kind: ErrorKind) -> Self {
684        Self::new(kind)
685    }
686}
687
688impl From<InvalidFrame> for Error {
689    #[inline]
690    fn from(error: InvalidFrame) -> Self {
691        Self::new(ErrorKind::InvalidFrame { error })
692    }
693}
694
695type Result<T, E = Error> = core::result::Result<T, E>;
696
697/// The response meta from handling a request.
698pub struct Response {
699    handled: bool,
700}
701
702/// An error a handler can fail a request with.
703///
704/// This decides what the client receives, see [Errors](self#errors). It is
705/// implemented for:
706///
707/// * Every type which implements [`fmt::Display`], which is sent as text. The
708///   client sees it through `web::Error::as_server_error`.
709/// * [`TypedError<E>`], which is sent as a typed error. The client can decode
710///   it back into `E` with `web::Error::server_error`.
711///
712/// It can also be implemented by hand for an error type which does not
713/// implement [`fmt::Display`], to decide per error whether it is typed. This is
714/// useful to keep internal failures out of the typed error the client sees.
715///
716/// # Examples
717///
718/// ```
719/// use core::fmt;
720///
721/// use musli::{Decode, Encode};
722/// use musli_web::ws::{self, ErrorPayload, ResponseError};
723///
724/// /// The error the client is told about, shared through the API crate.
725/// #[derive(Debug, Encode, Decode)]
726/// pub enum AuthError {
727///     Expired,
728///     Denied,
729/// }
730///
731/// /// What the handler fails with.
732/// enum HandlerError {
733///     Auth(AuthError),
734///     Internal(String),
735/// }
736///
737/// impl ResponseError for HandlerError {
738///     fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
739///         match self {
740///             HandlerError::Auth(AuthError::Expired) => write!(f, "Session expired"),
741///             HandlerError::Auth(AuthError::Denied) => write!(f, "Access denied"),
742///             // NB: The details stay on the server.
743///             HandlerError::Internal(..) => write!(f, "Internal error"),
744///         }
745///     }
746///
747///     fn encode_payload(&self, payload: ErrorPayload<'_>) -> Result<(), ws::Error> {
748///         match self {
749///             HandlerError::Auth(error) => payload.encode(error),
750///             // Not encoding anything sends the message alone.
751///             HandlerError::Internal(..) => Ok(()),
752///         }
753///     }
754/// }
755/// ```
756pub trait ResponseError
757where
758    Self: 'static + Send,
759{
760    /// Write the human readable message of the error.
761    ///
762    /// This is sent for every error, typed or not. The client shows it in the
763    /// [`fmt::Display`] of its error and returns it from
764    /// `web::Error::as_server_error`.
765    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
766
767    /// Encode the typed payload of the error, if it has one, by calling
768    /// [`ErrorPayload::encode`].
769    ///
770    /// Returning without encoding anything, which is what the default
771    /// implementation does, sends the message alone. If this errors the
772    /// message is sent alone as well, since the client is better served by
773    /// the message than by no response at all.
774    #[inline]
775    fn encode_payload(&self, payload: ErrorPayload<'_>) -> Result<(), Error> {
776        _ = payload;
777        Ok(())
778    }
779}
780
781impl<E> ResponseError for E
782where
783    E: 'static + Send + fmt::Display,
784{
785    #[inline]
786    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
787        fmt::Display::fmt(self, f)
788    }
789}
790
791impl<E> ResponseError for TypedError<E>
792where
793    E: 'static + Send + fmt::Display + EncodeBody,
794{
795    #[inline]
796    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
797        fmt::Display::fmt(&self.0, f)
798    }
799
800    #[inline]
801    fn encode_payload(&self, payload: ErrorPayload<'_>) -> Result<(), Error> {
802        payload.encode(&self.0)
803    }
804}
805
806/// Where [`ResponseError::encode_payload`] writes the typed payload of an
807/// error.
808pub struct ErrorPayload<'a> {
809    format: Format,
810    out: &'a mut Vec<u8>,
811    encoded: &'a mut bool,
812}
813
814impl ErrorPayload<'_> {
815    /// The format the payload is encoded with, which is the format of the
816    /// connection.
817    #[inline]
818    pub fn format(&self) -> Format {
819        self.format
820    }
821
822    /// Encode `value` as the typed payload of the error.
823    ///
824    /// The client decodes it with `web::Error::server_error`.
825    ///
826    /// # Errors
827    ///
828    /// Errors if `value` cannot be encoded.
829    pub fn encode<T>(self, value: &T) -> Result<(), Error>
830    where
831        T: ?Sized + EncodeBody,
832    {
833        self.out.clear();
834
835        if let Err(error) = self.format.encode(self.out, value) {
836            self.out.clear();
837            return Err(Error::new(ErrorKind::EncodeErrorPayload { error }));
838        }
839
840        *self.encoded = true;
841        Ok(())
842    }
843}
844
845/// Display adapter for the message of a [`ResponseError`].
846struct ErrorMessageDisplay<'a, E>(&'a E)
847where
848    E: ?Sized;
849
850impl<E> fmt::Display for ErrorMessageDisplay<'_, E>
851where
852    E: ?Sized + ResponseError,
853{
854    #[inline]
855    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
856        self.0.fmt_message(f)
857    }
858}
859
860/// A handler error which reaches the client as a typed value.
861///
862/// The wrapped error is encoded in the body format of the connection, and the
863/// client decodes it back with `web::Error::server_error` (or
864/// `client::Error::server_error`). Its [`fmt::Display`] text is sent along as
865/// the message of the error, which is what a client that does not decode the
866/// payload sees. See [Errors](self#errors) for an example.
867///
868/// If the error cannot be encoded the client receives the message alone, as
869/// if it was a plain text error.
870///
871/// This deliberately does not implement [`fmt::Display`] itself, since that
872/// would make it a text error. Use [`TypedError::get`] or the public field to
873/// get at the error.
874///
875/// # Examples
876///
877/// ```
878/// use musli_web::ws::TypedError;
879///
880/// fn check(value: u32) -> Result<u32, TypedError<String>> {
881///     if value == 0 {
882///         // Converted with `From` by the question mark operator.
883///         Err::<(), _>(String::from("Zero is not allowed"))?;
884///     }
885///
886///     Ok(value)
887/// }
888///
889/// let error = check(0).unwrap_err();
890/// assert_eq!(error.get(), "Zero is not allowed");
891/// ```
892#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
893pub struct TypedError<E>(pub E);
894
895impl<E> TypedError<E> {
896    /// Wrap an error.
897    ///
898    /// # Examples
899    ///
900    /// ```
901    /// use musli_web::ws::TypedError;
902    ///
903    /// let error = TypedError::new(42u32);
904    /// assert_eq!(error.into_inner(), 42);
905    /// ```
906    #[inline]
907    pub const fn new(error: E) -> Self {
908        Self(error)
909    }
910
911    /// Get a reference to the wrapped error.
912    #[inline]
913    pub const fn get(&self) -> &E {
914        &self.0
915    }
916
917    /// Unwrap the error.
918    #[inline]
919    pub fn into_inner(self) -> E {
920        self.0
921    }
922}
923
924impl<E> From<E> for TypedError<E> {
925    #[inline]
926    fn from(error: E) -> Self {
927        Self(error)
928    }
929}
930
931/// Trait governing how something can be converted into a response.
932pub trait IntoResponse
933where
934    Self: 'static + Send,
935{
936    /// The error variant being produced, see [`ResponseError`].
937    type Error: ResponseError;
938
939    /// Convert self into a response.
940    fn into_response(self) -> Result<Response, Self::Error>;
941}
942
943/// Implement [`IntoResponse`] for unit types `()`.
944///
945/// This indicates that the request has been handled.
946impl IntoResponse for () {
947    type Error = Infallible;
948
949    #[inline]
950    fn into_response(self) -> Result<Response, Self::Error> {
951        Ok(Response { handled: true })
952    }
953}
954
955/// Implement [`IntoResponse`] for `bool`.
956///
957/// On `true`, this means that the request was supported `false` means that it
958/// wasn't.
959impl IntoResponse for bool {
960    type Error = Infallible;
961
962    #[inline]
963    fn into_response(self) -> Result<Response, Self::Error> {
964        Ok(Response { handled: self })
965    }
966}
967
968/// Implement [`IntoResponse`] for [`Result`] types.
969///
970/// The [`Err`] variant fails the request, and is sent to the client as
971/// described by [`ResponseError`]: anything which implements [`fmt::Display`]
972/// as a text message, and a [`TypedError`] as a typed error.
973///
974/// [`Result`]: core::result::Result
975impl<T, E> IntoResponse for Result<T, E>
976where
977    T: IntoResponse<Error = Infallible>,
978    E: ResponseError,
979{
980    type Error = E;
981
982    #[inline]
983    fn into_response(self) -> Result<Response, E> {
984        match self {
985            Ok(into_response) => match IntoResponse::into_response(into_response) {
986                Ok(response) => Ok(response),
987                Err(error) => match error {},
988            },
989            Err(error) => Err(error),
990        }
991    }
992}
993
994/// Implement [`IntoResponse`] for [`Option`] types.
995///
996/// This will propagate any responses for the interior value if present. If the
997/// value is [`None`] this will be treated as unhandled. This can be useful when
998/// used in combination with [`Incoming::read`] since it returns an [`Option`].
999impl<T> IntoResponse for Option<T>
1000where
1001    T: IntoResponse,
1002{
1003    type Error = T::Error;
1004
1005    #[inline]
1006    fn into_response(self) -> Result<Response, Self::Error> {
1007        match self {
1008            Some(value) => value.into_response(),
1009            None => Ok(Response { handled: false }),
1010        }
1011    }
1012}
1013
1014/// A handler for incoming requests.
1015///
1016/// See [`server()`] for how to use with `axum`.
1017///
1018/// [`server()`]: crate::axum08::server
1019pub trait Handler
1020where
1021    Self: 'static + Send + Clone,
1022{
1023    /// The type of message id used.
1024    type Id: Id;
1025    /// The response type returned by the handler.
1026    type Response: IntoResponse;
1027
1028    /// Indicates that a `channel` has been opened.
1029    ///
1030    /// This indicates that you are communicating with a client that has opened
1031    /// a channel with [`Handle::channel`].
1032    ///
1033    /// After this has been called, you can expected to receive requests from
1034    /// the [`ChannelId`] corresponding to `channel`. The channel id of incoming
1035    /// requests can be inspected with [`Incoming::channel`].
1036    ///
1037    /// [`Handle::channel`]: crate::web::Handle::channel
1038    fn open_channel<'this>(
1039        &'this self,
1040        channel: ChannelId,
1041    ) -> impl Future<Output = ()> + Send + 'this {
1042        async {
1043            _ = channel;
1044        }
1045    }
1046
1047    /// Indicates that a `channel` has been cleanly closed.
1048    ///
1049    /// This indicates that communicating with a client that has opened a
1050    /// channel with [`Handle::channel`] has been cleanly closed, which occurs
1051    /// when the channel is cleanly closed by dropping the last handle to it.
1052    ///
1053    /// [`Handle::channel`]: crate::web::Handle::channel
1054    fn close_channel<'this>(
1055        &'this self,
1056        channel: ChannelId,
1057    ) -> impl Future<Output = ()> + Send + 'this {
1058        async {
1059            _ = channel;
1060        }
1061    }
1062
1063    /// Handle a request.
1064    ///
1065    /// A response which reports the request as handled (such as `()`, `true`
1066    /// or `Ok(())`) must have written a response with [`Outgoing::write`].
1067    /// If it did not, the client is sent an error stating that the handler
1068    /// wrote no response, rather than being left waiting for one.
1069    fn handle<'this>(
1070        &'this self,
1071        id: Self::Id,
1072        incoming: &'this mut Incoming<'_>,
1073        outgoing: &'this mut Outgoing<'_>,
1074    ) -> impl Future<Output = Self::Response> + Send + 'this;
1075
1076    /// Combine this handler with `other`, routing each request to the
1077    /// handler whose list of ids knows it.
1078    ///
1079    /// See [`Or`] for how requests are routed.
1080    #[inline]
1081    fn or<H>(self, other: H) -> Or<Self, H>
1082    where
1083        H: Handler,
1084    {
1085        Or::new(self, other)
1086    }
1087}
1088
1089/// A [`Handler`] which routes each request to one of two handlers, by the ids
1090/// their [`Handler::Id`] types know. Constructed with [`Handler::or`].
1091///
1092/// This is how a library which ships its own [`define!`] list, and a handler
1093/// for it, is carried on the same connection as an application's own list.
1094///
1095/// A request is handled by:
1096///
1097/// * The first handler if its id is in the [`Id::IDS`] of the first handler.
1098/// * Otherwise the second handler if its id is in the [`Id::IDS`] of the
1099///   second handler.
1100/// * Otherwise the first handler, as an unknown id, such as the `Unknown`
1101///   variant of a `Request` enum generated by [`define!`].
1102///
1103/// Both handlers are told about every channel which is opened and closed,
1104/// the first one first.
1105///
1106/// The [`Handler::Id`] of this handler is an [`Either`] of the two, and so is
1107/// its [`Handler::Response`].
1108///
1109/// # Id collisions
1110///
1111/// The two lists may not share an id. This is checked at compile time where
1112/// the handler is constructed, once the code doing so is built: being generic,
1113/// the check is evaluated when the code is compiled to a binary, so `cargo
1114/// check` does not report it. To check it earlier, assert that the [`Id::IDS`]
1115/// of the two lists are disjoint in a `const` item, see [`IdSet`].
1116///
1117/// A handler whose list [includes] the list of the other handler shares every
1118/// one of its ids, so it fails to compile as well. Such a handler instead
1119/// routes the requests of the included list itself, by matching on the
1120/// variant the list was included as.
1121///
1122/// ```compile_fail
1123/// use musli_web::ws::{self, Handler};
1124///
1125/// mod a {
1126///     # use musli::{Decode, Encode};
1127///     # use musli_web::api;
1128///     # #[derive(Encode, Decode)] pub struct HelloRequest;
1129///     api::define! {
1130///         pub type Hello;
1131///
1132///         impl Endpoint for Hello {
1133///             impl Request for HelloRequest;
1134///             type Response<'de> = ();
1135///         }
1136///     }
1137/// }
1138///
1139/// mod b {
1140///     # use musli::{Decode, Encode};
1141///     # use musli_web::api;
1142///     # #[derive(Encode, Decode)] pub struct LoginRequest;
1143///     // Its id is 1, just like `a::Hello`.
1144///     api::define! {
1145///         pub type Login;
1146///
1147///         impl Endpoint for Login {
1148///             impl Request for LoginRequest;
1149///             type Response<'de> = ();
1150///         }
1151///     }
1152/// }
1153///
1154/// # #[derive(Clone)] struct A;
1155/// # impl ws::Handler for A {
1156/// #     type Id = a::Request;
1157/// #     type Response = bool;
1158/// #     async fn handle(&self, _: Self::Id, _: &mut ws::Incoming<'_>, _: &mut ws::Outgoing<'_>) -> bool { false }
1159/// # }
1160/// # #[derive(Clone)] struct B;
1161/// # impl ws::Handler for B {
1162/// #     type Id = b::Request;
1163/// #     type Response = bool;
1164/// #     async fn handle(&self, _: Self::Id, _: &mut ws::Incoming<'_>, _: &mut ws::Outgoing<'_>) -> bool { false }
1165/// # }
1166/// let handler = A.or(B);
1167/// ```
1168///
1169/// [`define!`]: crate::api::define
1170/// [includes]: crate::api::define#including-other-lists
1171///
1172/// # Examples
1173///
1174/// ```
1175/// use musli_web::ws::{self, Handler};
1176///
1177/// /// A library with its own list, which pins its ids to a band which the
1178/// /// application does not use.
1179/// mod auth {
1180///     use musli::{Decode, Encode};
1181///     use musli_web::{api, ws};
1182///
1183///     #[derive(Encode, Decode)]
1184///     pub struct LoginRequest<'de> {
1185///         pub user: &'de str,
1186///     }
1187///
1188///     #[derive(Encode, Decode)]
1189///     pub struct LoginResponse {
1190///         pub ok: bool,
1191///     }
1192///
1193///     api::define! {
1194///         #[musli(id = 32000)]
1195///         pub type Login;
1196///
1197///         impl Endpoint for Login {
1198///             impl<'de> Request for LoginRequest<'de>;
1199///             type Response<'de> = LoginResponse;
1200///         }
1201///     }
1202///
1203///     /// The handler the library ships for its list.
1204///     #[derive(Clone)]
1205///     pub struct AuthHandler;
1206///
1207///     impl ws::Handler for AuthHandler {
1208///         type Id = Request;
1209///         type Response = Option<()>;
1210///
1211///         async fn handle(
1212///             &self,
1213///             id: Self::Id,
1214///             incoming: &mut ws::Incoming<'_>,
1215///             outgoing: &mut ws::Outgoing<'_>,
1216///         ) -> Self::Response {
1217///             match id {
1218///                 Request::Login => {
1219///                     let request = incoming.read::<LoginRequest<'_>>()?;
1220///                     outgoing.write(LoginResponse { ok: request.user == "admin" });
1221///                     Some(())
1222///                 }
1223///                 Request::Unknown(..) => None,
1224///             }
1225///         }
1226///     }
1227/// }
1228///
1229/// mod api {
1230///     use musli::{Decode, Encode};
1231///     use musli_web::api;
1232///
1233///     #[derive(Encode, Decode)]
1234///     pub struct HelloRequest;
1235///
1236///     api::define! {
1237///         pub type Hello;
1238///
1239///         impl Endpoint for Hello {
1240///             impl Request for HelloRequest;
1241///             type Response<'de> = ();
1242///         }
1243///     }
1244/// }
1245///
1246/// #[derive(Clone)]
1247/// struct AppHandler;
1248///
1249/// impl ws::Handler for AppHandler {
1250///     type Id = api::Request;
1251///     type Response = Result<bool, String>;
1252///
1253///     async fn handle(
1254///         &self,
1255///         id: Self::Id,
1256///         incoming: &mut ws::Incoming<'_>,
1257///         outgoing: &mut ws::Outgoing<'_>,
1258///     ) -> Self::Response {
1259///         match id {
1260///             api::Request::Hello => {
1261///                 outgoing.write(());
1262///                 Ok(true)
1263///             }
1264///             // Ids which neither list knows.
1265///             api::Request::Unknown(..) => Ok(false),
1266///         }
1267///     }
1268/// }
1269///
1270/// let handler = AppHandler.or(auth::AuthHandler);
1271///
1272/// // This is what the server constructs for every request it receives.
1273/// use musli_web::api::Id;
1274///
1275/// assert_eq!(
1276///     <ws::Or<AppHandler, auth::AuthHandler> as Handler>::Id::from_id(auth::Login::ID),
1277///     ws::Either::Second(auth::Request::Login),
1278/// );
1279/// ```
1280///
1281/// With axum, the combined handler is what the server is constructed with:
1282///
1283/// ```no_run
1284/// # mod app {
1285/// #     #[derive(musli::Encode, musli::Decode)] pub struct HelloRequest;
1286/// #     musli_web::api::define! {
1287/// #         pub type Hello;
1288/// #         impl Endpoint for Hello { impl Request for HelloRequest; type Response<'de> = (); }
1289/// #     }
1290/// # }
1291/// # mod auth {
1292/// #     #[derive(musli::Encode, musli::Decode)] pub struct LoginRequest;
1293/// #     musli_web::api::define! {
1294/// #         #[musli(id = 32000)] pub type Login;
1295/// #         impl Endpoint for Login { impl Request for LoginRequest; type Response<'de> = (); }
1296/// #     }
1297/// # }
1298/// # #[derive(Clone)] struct AppHandler;
1299/// # impl ws::Handler for AppHandler {
1300/// #     type Id = app::Request;
1301/// #     type Response = bool;
1302/// #     async fn handle(&self, _: Self::Id, _: &mut ws::Incoming<'_>, _: &mut ws::Outgoing<'_>) -> bool { false }
1303/// # }
1304/// # #[derive(Clone)] struct AuthHandler;
1305/// # impl ws::Handler for AuthHandler {
1306/// #     type Id = auth::Request;
1307/// #     type Response = bool;
1308/// #     async fn handle(&self, _: Self::Id, _: &mut ws::Incoming<'_>, _: &mut ws::Outgoing<'_>) -> bool { false }
1309/// # }
1310/// # extern crate axum08 as axum;
1311/// use axum::extract::ws::WebSocket;
1312/// use musli_web::axum08;
1313/// use musli_web::ws::{self, Handler};
1314///
1315/// async fn run(socket: WebSocket) -> Result<(), ws::Error> {
1316///     let mut server = axum08::server(socket, AppHandler.or(AuthHandler))
1317///         .connect()
1318///         .await?;
1319///
1320///     server.run().await
1321/// }
1322/// ```
1323#[derive(Clone)]
1324pub struct Or<A, B> {
1325    first: A,
1326    second: B,
1327}
1328
1329impl<A, B> Or<A, B>
1330where
1331    A: Handler,
1332    B: Handler,
1333{
1334    /// Combine `first` and `second`, see [`Handler::or`].
1335    ///
1336    /// This fails to build if the ids of the two handlers overlap, see [Id
1337    /// collisions](Or#id-collisions).
1338    #[inline]
1339    pub const fn new(first: A, second: B) -> Self {
1340        const {
1341            assert!(
1342                <A::Id as Id>::IDS.is_disjoint(&<B::Id as Id>::IDS),
1343                "The ids of the handlers combined with `ws::Or` overlap"
1344            );
1345        }
1346
1347        Self { first, second }
1348    }
1349
1350    /// Get the first handler.
1351    #[inline]
1352    pub const fn first(&self) -> &A {
1353        &self.first
1354    }
1355
1356    /// Get the second handler.
1357    #[inline]
1358    pub const fn second(&self) -> &B {
1359        &self.second
1360    }
1361}
1362
1363impl<A, B> Handler for Or<A, B>
1364where
1365    A: Handler,
1366    B: Handler,
1367{
1368    type Id = Either<A::Id, B::Id>;
1369    type Response = Either<A::Response, B::Response>;
1370
1371    // NB: Handlers are not `Sync`, so the futures of the inner handlers are
1372    // constructed up front rather than holding on to `&self` across an await.
1373
1374    #[inline]
1375    fn open_channel<'this>(
1376        &'this self,
1377        channel: ChannelId,
1378    ) -> impl Future<Output = ()> + Send + 'this {
1379        let first = self.first.open_channel(channel);
1380        let second = self.second.open_channel(channel);
1381
1382        async move {
1383            first.await;
1384            second.await;
1385        }
1386    }
1387
1388    #[inline]
1389    fn close_channel<'this>(
1390        &'this self,
1391        channel: ChannelId,
1392    ) -> impl Future<Output = ()> + Send + 'this {
1393        let first = self.first.close_channel(channel);
1394        let second = self.second.close_channel(channel);
1395
1396        async move {
1397            first.await;
1398            second.await;
1399        }
1400    }
1401
1402    #[inline]
1403    fn handle<'this>(
1404        &'this self,
1405        id: Self::Id,
1406        incoming: &'this mut Incoming<'_>,
1407        outgoing: &'this mut Outgoing<'_>,
1408    ) -> impl Future<Output = Self::Response> + Send + 'this {
1409        let future = match id {
1410            Either::First(id) => Either::First(self.first.handle(id, incoming, outgoing)),
1411            Either::Second(id) => Either::Second(self.second.handle(id, incoming, outgoing)),
1412        };
1413
1414        async move {
1415            match future {
1416                Either::First(future) => Either::First(future.await),
1417                Either::Second(future) => Either::Second(future.await),
1418            }
1419        }
1420    }
1421}
1422
1423/// One of two values, used by [`Or`] for its ids, responses and errors.
1424///
1425/// As an [`Id`], an id is [`Either::First`] if the first id type knows it,
1426/// [`Either::Second`] if only the second one does, and an unknown id of the
1427/// first id type otherwise, see [`Or`].
1428///
1429/// As an [`IntoResponse`] and a [`ResponseError`] it is whichever of the two
1430/// it holds.
1431#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1432pub enum Either<A, B> {
1433    /// The first value.
1434    First(A),
1435    /// The second value.
1436    Second(B),
1437}
1438
1439impl<A, B> Id for Either<A, B>
1440where
1441    A: Id,
1442    B: Id,
1443{
1444    const IDS: IdSet = IdSet {
1445        __ids: &[],
1446        __includes: &[&A::IDS, &B::IDS],
1447    };
1448
1449    #[inline]
1450    fn id(&self) -> MessageId {
1451        match self {
1452            Either::First(id) => id.id(),
1453            Either::Second(id) => id.id(),
1454        }
1455    }
1456
1457    #[inline]
1458    fn from_id(id: MessageId) -> Self {
1459        match Self::try_from_id(id) {
1460            Some(id) => id,
1461            None => Either::First(A::from_id(id)),
1462        }
1463    }
1464
1465    #[inline]
1466    fn try_from_id(id: MessageId) -> Option<Self> {
1467        if let Some(id) = A::try_from_id(id) {
1468            return Some(Either::First(id));
1469        }
1470
1471        Some(Either::Second(B::try_from_id(id)?))
1472    }
1473
1474    #[doc(hidden)]
1475    fn __do_not_implement_id() {}
1476}
1477
1478impl<A, B> IntoResponse for Either<A, B>
1479where
1480    A: IntoResponse,
1481    B: IntoResponse,
1482{
1483    type Error = Either<A::Error, B::Error>;
1484
1485    #[inline]
1486    fn into_response(self) -> Result<Response, Self::Error> {
1487        match self {
1488            Either::First(response) => response.into_response().map_err(Either::First),
1489            Either::Second(response) => response.into_response().map_err(Either::Second),
1490        }
1491    }
1492}
1493
1494impl<A, B> ResponseError for Either<A, B>
1495where
1496    A: ResponseError,
1497    B: ResponseError,
1498{
1499    #[inline]
1500    fn fmt_message(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1501        match self {
1502            Either::First(error) => error.fmt_message(f),
1503            Either::Second(error) => error.fmt_message(f),
1504        }
1505    }
1506
1507    #[inline]
1508    fn encode_payload(&self, payload: ErrorPayload<'_>) -> Result<(), Error> {
1509        match self {
1510            Either::First(error) => error.encode_payload(payload),
1511            Either::Second(error) => error.encode_payload(payload),
1512        }
1513    }
1514}
1515
1516struct Pinned<S> {
1517    socket: S,
1518    close_sleep: Sleep,
1519    ping_sleep: Sleep,
1520}
1521
1522impl<S> Pinned<S> {
1523    #[inline]
1524    fn project(self: Pin<&mut Self>) -> (Pin<&mut Sleep>, Pin<&mut Sleep>, Pin<&mut S>) {
1525        unsafe {
1526            let this = self.get_unchecked_mut();
1527            (
1528                Pin::new_unchecked(&mut this.close_sleep),
1529                Pin::new_unchecked(&mut this.ping_sleep),
1530                Pin::new_unchecked(&mut this.socket),
1531            )
1532        }
1533    }
1534}
1535
1536/// The output of a handler task: its result, whether it wrote a response, the
1537/// header of the request it handled, and the buffer it wrote into.
1538type HandlerOutput<H> = (
1539    Result<<H as Handler>::Response, Error>,
1540    bool,
1541    RequestHeader,
1542    Buf,
1543);
1544
1545/// Trait which governs how channel identifiers are allocated with a [`Server`].
1546///
1547/// Every [`Server`] hands the ids it allocates for its client to the
1548/// [`Handler`], and a broadcast names the channel it is sent in. For an id to
1549/// say which connection a channel belongs to it has to be unique among every
1550/// connection the application talks to, so by default every [`Server`] in the
1551/// process allocates from one shared pool, [`Channels::global()`]. Two
1552/// connections never hold the same id at the same time.
1553///
1554/// To scope ids differently, for example to keep the connections of one
1555/// service apart from those of another or to give a test its own ids, pass
1556/// another allocator to [`Connect::with_channel_allocator`]. A
1557/// [`Channels::new()`] is an independent pool which is shared by every clone of
1558/// it.
1559///
1560/// A [`Server`] only frees the ids it allocated itself: when the client closes
1561/// one of its channels, and for every channel still open when the [`Server`]
1562/// is dropped. An id the client names but does not own is ignored, so one
1563/// client cannot release a channel which belongs to another. How many channels
1564/// a client may hold at once is limited by [`Connect::max_channels`].
1565///
1566/// # Examples
1567///
1568/// Giving the connections of one route their own pool of ids:
1569///
1570/// ```
1571/// # extern crate axum08 as axum;
1572/// use axum::extract::ws::WebSocket;
1573/// use musli_web::axum08;
1574/// use musli_web::ws::{self, Channels};
1575///
1576/// # mod api {
1577/// #     use musli::{Decode, Encode};
1578/// #     use musli_web::api;
1579/// #     #[derive(Encode, Decode)]
1580/// #     pub struct HelloRequest;
1581/// #     #[derive(Encode, Decode)]
1582/// #     pub struct HelloResponse;
1583/// #     api::define! {
1584/// #         pub type Hello;
1585/// #         impl Endpoint for Hello {
1586/// #             impl Request for HelloRequest;
1587/// #             type Response<'de> = HelloResponse;
1588/// #         }
1589/// #     }
1590/// # }
1591/// # #[derive(Clone)]
1592/// # struct MyHandler;
1593/// # impl ws::Handler for MyHandler {
1594/// #     type Id = api::Request;
1595/// #     type Response = bool;
1596/// #     async fn handle(
1597/// #         &self,
1598/// #         _: Self::Id,
1599/// #         _: &mut ws::Incoming<'_>,
1600/// #         _: &mut ws::Outgoing<'_>,
1601/// #     ) -> bool {
1602/// #         false
1603/// #     }
1604/// # }
1605/// async fn connection(socket: WebSocket, channels: Channels) -> Result<(), ws::Error> {
1606///     let mut server = axum08::server(socket, MyHandler)
1607///         .with_channel_allocator(channels)
1608///         .connect()
1609///         .await?;
1610///
1611///     server.run().await
1612/// }
1613///
1614/// // Shared by every connection made with a clone of it, but distinct from
1615/// // the ids of connections which use the default pool.
1616/// let channels = Channels::new();
1617/// # let _ = connection;
1618/// ```
1619pub trait ChannelAllocator {
1620    /// Allocate an id which is not currently allocated, or `None` if every id
1621    /// is in use.
1622    ///
1623    /// Using `0` is equivalent to [`ChannelId::NONE`] so the allocator must
1624    /// never hand out an identifier with this value, since it is equivalent
1625    /// to no channel. A [`Server`] which is handed [`ChannelId::NONE`], or an
1626    /// id it already holds, refuses to open the channel.
1627    fn next(&self) -> Option<ChannelId>;
1628
1629    /// Return an id previously handed out by [`ChannelAllocator::next`] so it
1630    /// can be allocated again.
1631    ///
1632    /// A [`Server`] calls this exactly once for every id it allocated, which
1633    /// can happen while it is being dropped.
1634    fn free(&self, channel: ChannelId);
1635}
1636
1637/// A connection which has not yet completed the [negotiation protocol].
1638///
1639/// This is what [`server()`] hands back, and it is the only way to obtain a
1640/// [`Server`]. Configuration lives here rather than on [`Server`], since every
1641/// setting has to be in place before the first byte goes over the wire.
1642///
1643/// Crucially this type cannot send messages. A [`Server`] — which can — only
1644/// exists once [`Connect::connect`] has resolved, which is precisely the point
1645/// at which the [`Format`] for the connection has been settled. Attempting to
1646/// broadcast before that is a compile error rather than a message the client
1647/// cannot read.
1648///
1649/// [`server()`]: crate::axum08::server
1650/// [negotiation protocol]: crate::api#negotiating-the-format
1651///
1652/// # Examples
1653///
1654/// ```
1655/// # extern crate axum08 as axum;
1656/// # use axum::extract::ws::WebSocket;
1657/// use musli_web::api::Format;
1658/// use musli_web::{axum08, ws};
1659///
1660/// mod api {
1661///     use musli::{Decode, Encode};
1662///     use musli_web::api;
1663///
1664///     #[derive(Encode, Decode)]
1665///     pub struct HelloRequest<'de> {
1666///         pub message: &'de str,
1667///     }
1668///
1669///     #[derive(Encode, Decode)]
1670///     pub struct HelloResponse<'de> {
1671///         pub message: &'de str,
1672///     }
1673///
1674///     api::define! {
1675///         pub type Hello;
1676///
1677///         impl Endpoint for Hello {
1678///             impl<'de> Request for HelloRequest<'de>;
1679///             type Response<'de> = HelloResponse<'de>;
1680///         }
1681///     }
1682/// }
1683///
1684/// #[derive(Clone)]
1685/// struct MyHandler;
1686///
1687/// impl ws::Handler for MyHandler {
1688///     type Id = api::Request;
1689///     type Response = bool;
1690///
1691///     async fn handle(
1692///         &self,
1693///         id: Self::Id,
1694///         incoming: &mut ws::Incoming<'_>,
1695///         outgoing: &mut ws::Outgoing<'_>,
1696///     ) -> bool {
1697///         false
1698///     }
1699/// }
1700///
1701/// # async fn example(socket: WebSocket) -> Result<(), ws::Error> {
1702/// let mut server = axum08::server(socket, MyHandler)
1703///     .with_formats(&[Format::Wire, Format::Json])
1704///     .connect()
1705///     .await?;
1706///
1707/// // Only reachable once the client has negotiated a format.
1708/// server.run().await?;
1709/// # Ok(())
1710/// # }
1711/// ```
1712///
1713/// Skipping the connection step does not compile, since a [`Connect`] has
1714/// nothing to broadcast with:
1715///
1716/// ```compile_fail
1717/// # extern crate axum08 as axum;
1718/// # use axum::extract::ws::WebSocket;
1719/// use musli_web::{axum08, ws};
1720///
1721/// mod api {
1722///     use musli::{Decode, Encode};
1723///     use musli_web::api;
1724///
1725///     #[derive(Encode, Decode)]
1726///     pub struct HelloRequest<'de> {
1727///         pub message: &'de str,
1728///     }
1729///
1730///     #[derive(Encode, Decode)]
1731///     pub struct HelloResponse<'de> {
1732///         pub message: &'de str,
1733///     }
1734///
1735///     #[derive(Encode, Decode)]
1736///     pub struct TickEvent {
1737///         pub tick: u32,
1738///     }
1739///
1740///     api::define! {
1741///         pub type Hello;
1742///
1743///         impl Endpoint for Hello {
1744///             impl<'de> Request for HelloRequest<'de>;
1745///             type Response<'de> = HelloResponse<'de>;
1746///         }
1747///
1748///         pub type Tick;
1749///
1750///         impl Broadcast for Tick {
1751///             impl Event for TickEvent;
1752///         }
1753///     }
1754/// }
1755///
1756/// #[derive(Clone)]
1757/// struct MyHandler;
1758///
1759/// impl ws::Handler for MyHandler {
1760///     type Id = api::Request;
1761///     type Response = bool;
1762///
1763///     async fn handle(
1764///         &self,
1765///         id: Self::Id,
1766///         incoming: &mut ws::Incoming<'_>,
1767///         outgoing: &mut ws::Outgoing<'_>,
1768///     ) -> bool {
1769///         false
1770///     }
1771/// }
1772///
1773/// # async fn example(socket: WebSocket) -> Result<(), ws::Error> {
1774/// let mut server = axum08::server(socket, MyHandler);
1775/// // `Connect` has no `broadcast`, only the `Server` that `connect()` hands
1776/// // back does.
1777/// server.broadcast(api::TickEvent { tick: 1 })?;
1778/// # Ok(())
1779/// # }
1780/// ```
1781pub struct Connect<S, H, C = Channels>
1782where
1783    S: ServerImpl,
1784    H: Handler,
1785{
1786    handler: H,
1787    socket: S::Socket,
1788    channels: C,
1789    seed: u64,
1790    max_capacity: usize,
1791    max_in_flight: usize,
1792    max_outbound: usize,
1793    max_channels: usize,
1794    /// Formats this server is willing to negotiate, or `None` to accept every
1795    /// format it was built with support for.
1796    formats: Option<&'static [Format]>,
1797    /// The application version this server states, or zero for none.
1798    app: u32,
1799}
1800
1801impl<S, H> Connect<S, H, Channels>
1802where
1803    S: ServerImpl,
1804    H: Handler,
1805{
1806    /// Construct a new pending connection with the specified handler.
1807    #[inline]
1808    pub(crate) fn new(socket: S::Socket, handler: H) -> Self {
1809        Self {
1810            handler,
1811            socket,
1812            channels: Channels::global(),
1813            seed: DEFAULT_SEED,
1814            max_capacity: MAX_CAPACITY,
1815            max_in_flight: DEFAULT_MAX_IN_FLIGHT,
1816            max_outbound: DEFAULT_MAX_OUTBOUND,
1817            max_channels: DEFAULT_MAX_CHANNELS,
1818            formats: None,
1819            app: 0,
1820        }
1821    }
1822}
1823
1824impl<S, H, C> Connect<S, H, C>
1825where
1826    S: ServerImpl,
1827    H: Handler,
1828{
1829    /// Associate the specified seed with the connection.
1830    ///
1831    /// This affects the random number generation used for ping messages.
1832    ///
1833    /// By default the seed is a constant value.
1834    #[inline]
1835    pub fn seed(mut self, seed: u64) -> Self {
1836        self.seed = seed;
1837        self
1838    }
1839
1840    /// Allocate the channel ids of this connection from `channels`.
1841    ///
1842    /// By default ids come from [`Channels::global()`], which makes them
1843    /// unique across every connection in the process. Use this to scope them
1844    /// differently, see [`ChannelAllocator`].
1845    #[inline]
1846    pub fn with_channel_allocator<U>(self, channels: U) -> Connect<S, H, U>
1847    where
1848        U: ChannelAllocator,
1849    {
1850        Connect {
1851            handler: self.handler,
1852            socket: self.socket,
1853            channels,
1854            seed: self.seed,
1855            max_capacity: self.max_capacity,
1856            max_in_flight: self.max_in_flight,
1857            max_outbound: self.max_outbound,
1858            max_channels: self.max_channels,
1859            formats: self.formats,
1860            app: self.app,
1861        }
1862    }
1863
1864    /// Get a reference to the handler.
1865    #[inline]
1866    pub fn handler(&self) -> &H {
1867        &self.handler
1868    }
1869
1870    /// Restrict the set of [`Format`]s this server is willing to negotiate.
1871    ///
1872    /// By default every format the crate was built with support for is
1873    /// accepted. A client which asks for a format outside of this set is
1874    /// rejected during the [negotiation protocol] and the connection settles on
1875    /// [`Format::DEFAULT`] instead.
1876    ///
1877    /// Note that this cannot widen the set, a format which was not compiled in
1878    /// is never accepted.
1879    ///
1880    /// [negotiation protocol]: crate::api#negotiating-the-format
1881    #[inline]
1882    pub fn with_formats(mut self, formats: &'static [Format]) -> Self {
1883        self.formats = Some(formats);
1884        self
1885    }
1886
1887    /// Test if this server is willing to negotiate `format`.
1888    #[inline]
1889    pub fn accepts(&self, format: Format) -> bool {
1890        accepts(self.formats, format)
1891    }
1892
1893    /// State the version of the application's API this server speaks.
1894    ///
1895    /// This is a version of *your* protocol, the requests and broadcasts
1896    /// defined with [`api::define!`], as opposed to [`VERSION`] which is the
1897    /// version of the envelope this crate puts around them. Bump it whenever
1898    /// the API changes in a way an older client cannot cope with.
1899    ///
1900    /// The server states it in [`MessageId::SERVER_HELLO`], and a client which
1901    /// was given one too through its own `ServiceBuilder::app_version` compares
1902    /// the two before it negotiates. If they differ the client reports the
1903    /// connection as incompatible instead of opening it, which is what lets a
1904    /// page served by an older build learn that it has to reload. A client
1905    /// which states a different version is also refused here: it gets a close
1906    /// frame and [`Connect::connect`] fails with an error for which
1907    /// [`Error::is_incompatible`] holds.
1908    ///
1909    /// Zero, which is the default, states no version. The check only applies
1910    /// when both peers state one, so a server or a client which does not opt
1911    /// in behaves exactly as if this did not exist. See [application
1912    /// versions].
1913    ///
1914    /// [`api::define!`]: crate::api::define
1915    /// [application versions]: crate::api#application-versions
1916    ///
1917    /// # Examples
1918    ///
1919    /// ```
1920    /// # extern crate axum08 as axum;
1921    /// use axum::extract::ws::WebSocket;
1922    /// use musli_web::axum08;
1923    /// use musli_web::ws;
1924    ///
1925    /// # mod api {
1926    /// #     use musli::{Decode, Encode};
1927    /// #     use musli_web::api;
1928    /// #     #[derive(Encode, Decode)]
1929    /// #     pub struct HelloRequest;
1930    /// #     #[derive(Encode, Decode)]
1931    /// #     pub struct HelloResponse;
1932    /// #     api::define! {
1933    /// #         pub type Hello;
1934    /// #         impl Endpoint for Hello {
1935    /// #             impl Request for HelloRequest;
1936    /// #             type Response<'de> = HelloResponse;
1937    /// #         }
1938    /// #     }
1939    /// # }
1940    /// # #[derive(Clone)]
1941    /// # struct MyHandler;
1942    /// # impl ws::Handler for MyHandler {
1943    /// #     type Id = api::Request;
1944    /// #     type Response = bool;
1945    /// #     async fn handle(
1946    /// #         &self,
1947    /// #         _: Self::Id,
1948    /// #         _: &mut ws::Incoming<'_>,
1949    /// #         _: &mut ws::Outgoing<'_>,
1950    /// #     ) -> bool {
1951    /// #         false
1952    /// #     }
1953    /// # }
1954    /// /// Bumped whenever the API changes in a way old pages cannot cope with.
1955    /// const APP_VERSION: u32 = 7;
1956    ///
1957    /// async fn connection(socket: WebSocket) -> Result<(), ws::Error> {
1958    ///     let server = axum08::server(socket, MyHandler).app_version(APP_VERSION);
1959    ///
1960    ///     let mut server = match server.connect().await {
1961    ///         Ok(server) => server,
1962    ///         // A page from another build, which is told to reload.
1963    ///         Err(error) if error.is_incompatible() => return Ok(()),
1964    ///         Err(error) => return Err(error),
1965    ///     };
1966    ///
1967    ///     server.run().await
1968    /// }
1969    /// # let _ = connection;
1970    /// ```
1971    #[inline]
1972    pub fn app_version(mut self, version: u32) -> Self {
1973        self.app = version;
1974        self
1975    }
1976
1977    /// Modify the max allocated capacity of the buffers used for outgoing
1978    /// messages.
1979    ///
1980    /// This is not a hard limit. A message larger than this is still written,
1981    /// but once it has been flushed the allocation is released back down to the
1982    /// specified value rather than being kept for the lifetime of the
1983    /// connection.
1984    ///
1985    /// By default, the capacity is 1 MiB.
1986    #[inline]
1987    pub fn max_capacity(mut self, max_capacity: usize) -> Self {
1988        self.max_capacity = max_capacity;
1989        self
1990    }
1991
1992    /// Modify the max allocated capacity of the outgoing buffers.
1993    ///
1994    /// This is an alias for [`Connect::max_capacity`].
1995    #[inline]
1996    pub fn with_max_capacity(self, max_capacity: usize) -> Self {
1997        self.max_capacity(max_capacity)
1998    }
1999
2000    /// Limit the number of requests which are handled concurrently.
2001    ///
2002    /// Once this many handlers are running, the server stops reading from the
2003    /// socket until one of them has completed. The peer is slowed down rather
2004    /// than disconnected, and nothing it sent is lost.
2005    ///
2006    /// A handler which waits for another request on the same connection to
2007    /// arrive needs this to be large enough for that request to be read.
2008    ///
2009    /// By default, the limit is 128.
2010    ///
2011    /// # Panics
2012    ///
2013    /// Panics if `max_in_flight` is zero, since no request could then ever be
2014    /// handled.
2015    #[inline]
2016    pub fn max_in_flight(mut self, max_in_flight: usize) -> Self {
2017        assert!(max_in_flight > 0, "max_in_flight must be non-zero");
2018        self.max_in_flight = max_in_flight;
2019        self
2020    }
2021
2022    /// Limit the number of bytes queued for the peer before the server stops
2023    /// reading from it.
2024    ///
2025    /// A peer which keeps sending requests but never reads the responses would
2026    /// otherwise make the server buffer an unbounded amount of data. Once this
2027    /// many bytes of responses, errors and broadcasts are waiting to be
2028    /// written, the server stops reading from the socket until the peer has
2029    /// caught up. The peer is slowed down rather than disconnected.
2030    ///
2031    /// This is not a hard limit on memory use. Requests already being handled
2032    /// still queue their responses, and [`Server::broadcast`] is never refused.
2033    ///
2034    /// By default, the limit is 8 MiB.
2035    #[inline]
2036    pub fn max_outbound(mut self, max_outbound: usize) -> Self {
2037        self.max_outbound = max_outbound;
2038        self
2039    }
2040
2041    /// Limit the number of channels the client may hold open at once.
2042    ///
2043    /// Channel ids come from a pool shared with other connections, see
2044    /// [`ChannelAllocator`], so without a limit a single client could take
2045    /// every id there is. A request to open a channel beyond the limit is
2046    /// answered with an error and the connection stays up. Zero refuses every
2047    /// channel.
2048    ///
2049    /// By default, the limit is 1024.
2050    #[inline]
2051    pub fn max_channels(mut self, max_channels: usize) -> Self {
2052        self.max_channels = max_channels;
2053        self
2054    }
2055}
2056
2057impl<S, H, C> Connect<S, H, C>
2058where
2059    S: ServerImpl,
2060    Error: From<S::Error>,
2061    H: Handler,
2062    C: ChannelAllocator,
2063{
2064    /// Perform the [negotiation protocol] and hand back the [`Server`] it
2065    /// produced.
2066    ///
2067    /// This sends [`MessageId::SERVER_HELLO`] and then drives the socket —
2068    /// including keepalive pings — until the client has answered with a
2069    /// [`MessageId::NEGOTIATE`] request and the reply to it has been flushed.
2070    ///
2071    /// Until that has happened the connection has no [`Server`], so there is no
2072    /// way to write a message which the client might not be able to decode.
2073    ///
2074    /// # Errors
2075    ///
2076    /// Errors if the connection goes away before the format has been
2077    /// negotiated, or if the client sends anything other than a negotiation as
2078    /// its first message. Both tear the connection down, since a peer which
2079    /// does not negotiate cannot be talked to safely.
2080    ///
2081    /// [negotiation protocol]: crate::api#negotiating-the-format
2082    pub async fn connect(self) -> Result<Server<S, H, C>, Error> {
2083        let now = Instant::now();
2084
2085        let mut server = Server {
2086            handler: self.handler,
2087            pinned: Box::pin(Pinned {
2088                socket: self.socket,
2089                close_sleep: tokio::time::sleep_until(now + CLOSE_TIMEOUT),
2090                ping_sleep: tokio::time::sleep_until(now + PING_TIMEOUT),
2091            }),
2092            channels: OwnedChannels::new(self.channels, self.max_channels),
2093            closing: false,
2094            pool: BufPool::new(self.max_capacity),
2095            outbound: VecDeque::new(),
2096            outbound_bytes: 0,
2097            max_in_flight: self.max_in_flight,
2098            max_outbound: self.max_outbound,
2099            error: String::new(),
2100            error_payload: Vec::new(),
2101            error_typed: false,
2102            last_ping: None,
2103            rng: SmallRng::seed_from_u64(self.seed),
2104            out: VecDeque::new(),
2105            socket_send: false,
2106            socket_flush: false,
2107            socket_recv: true,
2108            set: JoinSet::new(),
2109            format: Format::DEFAULT,
2110            mode: Mode::DEFAULT,
2111            failure: None,
2112            formats: self.formats,
2113            app: self.app,
2114        };
2115
2116        server.hello()?;
2117        server.negotiate().await?;
2118        Ok(server)
2119    }
2120}
2121
2122/// The error for a peer which went away during negotiation.
2123///
2124/// A failure which was already held explains why better than the peer going
2125/// away does, since it is usually the reason it went away.
2126#[inline]
2127fn gone(failure: Option<Error>) -> Error {
2128    failure.unwrap_or_else(|| Error::new(ErrorKind::NotNegotiated))
2129}
2130
2131/// Test if `formats` is willing to negotiate `format`.
2132#[inline]
2133fn accepts(formats: Option<&'static [Format]>, format: Format) -> bool {
2134    format.is_supported() && formats.is_none_or(|f| f.contains(&format))
2135}
2136
2137/// The server side handle of the websocket protocol.
2138///
2139/// This can only be constructed by completing the [negotiation protocol]
2140/// through [`Connect::connect`], so its mere existence means that the
2141/// [`Format`] used for everything the server originates has been agreed with
2142/// the client.
2143///
2144/// See [`server()`] for how to use with `axum`.
2145///
2146/// [`server()`]: crate::axum08::server
2147/// [negotiation protocol]: crate::api#negotiating-the-format
2148pub struct Server<S, H, C = Channels>
2149where
2150    S: ServerImpl,
2151    H: Handler,
2152    C: ChannelAllocator,
2153{
2154    handler: H,
2155    pinned: Pin<Box<Pinned<S::Socket>>>,
2156    /// The channels the client holds, which are freed when the server is
2157    /// dropped.
2158    channels: OwnedChannels<C>,
2159    closing: bool,
2160    pool: BufPool,
2161    outbound: VecDeque<Buf>,
2162    /// The number of bytes in `outbound` which are yet to be written.
2163    outbound_bytes: usize,
2164    /// Reading stops while this many handlers are running.
2165    max_in_flight: usize,
2166    /// Reading stops while this many bytes are queued in `outbound`.
2167    max_outbound: usize,
2168    /// The message of the error response being sent.
2169    error: String,
2170    /// The typed payload of the error response being sent, which is only
2171    /// valid if `error_typed` is set.
2172    error_payload: Vec<u8>,
2173    /// Whether the error response being sent carries `error_payload`.
2174    error_typed: bool,
2175    last_ping: Option<[u8; 4]>,
2176    rng: SmallRng,
2177    out: VecDeque<S::Message>,
2178    socket_send: bool,
2179    socket_flush: bool,
2180    /// Whether the peer's stream might still produce a message.
2181    ///
2182    /// A stream which has ended reports `Ready(None)` on every poll and
2183    /// registers no waker, so it has to stop being polled once it has ended or
2184    /// it masks every arm of [`Select`] behind it.
2185    socket_recv: bool,
2186    set: JoinSet<HandlerOutput<H>>,
2187    /// The format used for messages the server originates on this connection,
2188    /// as agreed by the [negotiation protocol].
2189    ///
2190    /// [negotiation protocol]: crate::api#negotiating-the-format
2191    format: Format,
2192    /// The mode every frame on this connection is spelled in, as decided by the
2193    /// frame the client negotiated with.
2194    ///
2195    /// [negotiation protocol]: crate::api#negotiating-the-format
2196    mode: Mode,
2197    /// An error which tore the connection down, held until the close frame
2198    /// explaining it has been flushed.
2199    failure: Option<Error>,
2200    /// Formats this server is willing to negotiate, or `None` to accept every
2201    /// format it was built with support for.
2202    formats: Option<&'static [Format]>,
2203    /// The application version this server states, or zero for none.
2204    app: u32,
2205}
2206
2207impl<S, H, C> Server<S, H, C>
2208where
2209    S: ServerImpl,
2210    H: Handler,
2211    C: ChannelAllocator,
2212{
2213    /// Get a reference to the handler.
2214    #[inline]
2215    pub fn handler(&self) -> &H {
2216        &self.handler
2217    }
2218
2219    /// The [`Format`] used for messages this server originates, such as
2220    /// broadcasts.
2221    ///
2222    /// This is fixed for the lifetime of the connection and was agreed with the
2223    /// client by [`Connect::connect`], which is why it is never in doubt here.
2224    #[inline]
2225    pub fn format(&self) -> Format {
2226        self.format
2227    }
2228
2229    /// The [`Mode`] every frame on this connection is spelled in.
2230    ///
2231    /// This is decided by the frame the client negotiated with and is fixed for
2232    /// the lifetime of the connection, see the [wire format].
2233    ///
2234    /// [wire format]: crate::api#wire-format
2235    #[inline]
2236    pub fn mode(&self) -> Mode {
2237        self.mode
2238    }
2239
2240    /// Test if this server is willing to negotiate `format`.
2241    #[inline]
2242    pub fn accepts(&self, format: Format) -> bool {
2243        accepts(self.formats, format)
2244    }
2245}
2246
2247impl<S, H, C> Server<S, H, C>
2248where
2249    S: ServerImpl,
2250    Error: From<S::Error>,
2251    H: Handler,
2252    C: ChannelAllocator,
2253{
2254    /// Drive the socket until the client has negotiated a [`Format`].
2255    ///
2256    /// This is the connection step every peer is forced through, see
2257    /// [`Connect::connect`]. It deliberately understands nothing but
2258    /// [`MessageId::NEGOTIATE`] and the keepalive machinery, so no handler is
2259    /// ever invoked and nothing the user could write is in flight yet.
2260    ///
2261    /// It returns once the format is settled *and* the reply confirming it has
2262    /// been flushed, so the very next thing on the wire can safely use it.
2263    async fn negotiate(&mut self) -> Result<(), Error> {
2264        let mut negotiated = false;
2265        // NB: Held rather than returned immediately so that the close frame
2266        // explaining the violation makes it onto the wire first.
2267        let mut failure = None::<Error>;
2268
2269        loop {
2270            let drained = self.out.is_empty() && !self.socket_flush;
2271
2272            if failure.is_some() && drained {
2273                break;
2274            }
2275
2276            if negotiated && drained && self.outbound.is_empty() {
2277                break;
2278            }
2279
2280            self.handle_send()?;
2281
2282            let result = {
2283                let inner = Select::<S::Socket, H> {
2284                    pinned: self.pinned.as_mut(),
2285                    wants_socket_recv: self.socket_recv,
2286                    wants_socket_send: !self.socket_send,
2287                    wants_socket_flush: self.socket_flush,
2288                    set: &mut self.set,
2289                };
2290
2291                inner.await
2292            };
2293
2294            match result {
2295                Output::Close => {
2296                    return Err(gone(failure));
2297                }
2298                Output::Ping => {
2299                    self.handle_ping()?;
2300                }
2301                Output::Recv(message) => {
2302                    let Some(message) = message else {
2303                        return Err(gone(failure));
2304                    };
2305
2306                    let message = match message {
2307                        Ok(message) => message,
2308                        Err(error) => return Err(failure.unwrap_or_else(|| Error::from(error))),
2309                    };
2310
2311                    match message {
2312                        // NB: The frame type is the mode, so the negotiation is
2313                        // what tells the server which envelope the rest of the
2314                        // connection is spelled in.
2315                        Message::Text(bytes) => match self.handle_negotiate(Mode::Text, bytes) {
2316                            Ok(()) => negotiated = true,
2317                            Err(error) => failure = Some(error),
2318                        },
2319                        Message::Binary(bytes) => {
2320                            match self.handle_negotiate(Mode::Binary, bytes) {
2321                                Ok(()) => negotiated = true,
2322                                Err(error) => failure = Some(error),
2323                            }
2324                        }
2325                        Message::Ping(payload) => {
2326                            self.out.push_back(S::pong(payload));
2327                        }
2328                        Message::Pong(data) => {
2329                            self.handle_pong(data)?;
2330                        }
2331                        Message::Close => {
2332                            return Err(gone(failure));
2333                        }
2334                    }
2335                }
2336                Output::Send(result) => {
2337                    result?;
2338                    self.socket_send = true;
2339                }
2340                Output::Flushed(result) => {
2341                    result?;
2342                    self.socket_flush = false;
2343                }
2344                Output::Handle(..) => {
2345                    // NB: No handler can have been spawned yet, since requests
2346                    // are only dispatched after negotiation.
2347                }
2348            }
2349        }
2350
2351        match failure {
2352            Some(error) => Err(error),
2353            None => Ok(()),
2354        }
2355    }
2356
2357    /// Process the single message which is legal before a format has been
2358    /// negotiated.
2359    ///
2360    /// Anything else closes the connection, since a peer which skips
2361    /// negotiation cannot be sent broadcasts safely.
2362    fn handle_negotiate(&mut self, mode: Mode, bytes: Bytes) -> Result<(), Error> {
2363        let mut at = 0;
2364
2365        let header: RequestHeader = match format::decode_envelope(mode, &bytes, &mut at) {
2366            Ok(header) => header,
2367            // NB: The version is what says which headers may appear, so a peer
2368            // which does not agree on it is refused before anything else about
2369            // the message is looked at.
2370            Err(error) if error.unsupported_version().is_some() => {
2371                self.out.push_back(S::close(
2372                    CLOSE_PROTOCOL_ERROR,
2373                    "Unsupported protocol version",
2374                ));
2375                return Err(Error::new(ErrorKind::UnsupportedVersion { error }));
2376            }
2377            Err(error) if error.is_unknown_header() => {
2378                self.out
2379                    .push_back(S::close(CLOSE_PROTOCOL_ERROR, "Unknown header"));
2380                return Err(Error::new(ErrorKind::UnknownHeader { error }));
2381            }
2382            Err(error) => {
2383                self.out
2384                    .push_back(S::close(CLOSE_PROTOCOL_ERROR, "Invalid request header"));
2385                return Err(Error::new(ErrorKind::NegotiateHeader { error }));
2386            }
2387        };
2388
2389        if MessageId::new(header.id) != Some(MessageId::NEGOTIATE) {
2390            self.out.push_back(S::close(
2391                CLOSE_PROTOCOL_ERROR,
2392                "Expected a negotiation as the first message",
2393            ));
2394
2395            return Err(Error::new(ErrorKind::ExpectedNegotiate { id: header.id }));
2396        }
2397
2398        // NB: Only refused when both sides state a version, so that a peer
2399        // which has not opted in behaves as it always has. A client which
2400        // states a different one was built against another API, and nothing it
2401        // sends can be trusted to mean what this server thinks it does.
2402        if self.app != 0 && header.app != 0 && header.app != self.app {
2403            tracing::debug!(
2404                server = self.app,
2405                client = header.app,
2406                "Incompatible client"
2407            );
2408
2409            self.out.push_back(S::close(
2410                CLOSE_POLICY_VIOLATION,
2411                "Incompatible application version",
2412            ));
2413
2414            return Err(Error::new(ErrorKind::Incompatible {
2415                server: self.app,
2416                client: header.app,
2417            }));
2418        }
2419
2420        // NB: The connection stays up on a rejected format and settles on the
2421        // default instead, which is what the client falls back to. The error
2422        // tells it which formats it could have asked for.
2423        let Some(format) = Format::from_u8(header.format) else {
2424            self.format_error_message(format_args!(
2425                "Unknown format id {}, supported: {}",
2426                header.format,
2427                SupportedFormats(self.formats)
2428            ))?;
2429
2430            self.format = Format::DEFAULT;
2431            return self.send_error(&header);
2432        };
2433
2434        if !self.accepts(format) {
2435            self.format_error_message(format_args!(
2436                "Unsupported format `{format}`, supported: {}",
2437                SupportedFormats(self.formats)
2438            ))?;
2439
2440            tracing::debug!(?format, "Rejected format");
2441            self.format = Format::DEFAULT;
2442            return self.send_error(&header);
2443        }
2444
2445        // NB: A text frame has to be valid UTF-8 in its entirety, so a format
2446        // which is not human readable cannot be carried in one. The connection
2447        // settles on the defaults for both, and the reply which says so goes
2448        // out in the default mode, which is what tells the client.
2449        if !mode.accepts(format) {
2450            self.format_error_message(format_args!(
2451                "Mode `{mode}` cannot carry the `{format}` format"
2452            ))?;
2453
2454            tracing::debug!(?mode, ?format, "Rejected mode");
2455            self.format = Format::DEFAULT;
2456            return self.send_error(&header);
2457        }
2458
2459        tracing::debug!(?mode, ?format, "Negotiated format");
2460        self.format = format;
2461        self.mode = mode;
2462        self.send_negotiated(&header, format)
2463    }
2464
2465    /// Acknowledge a negotiation by echoing the format that was accepted.
2466    fn send_negotiated(&mut self, header: &RequestHeader, format: Format) -> Result<(), Error> {
2467        let mode = self.mode;
2468
2469        let buf = self.pool.with(|buf| {
2470            let mut writer = buf.writer();
2471
2472            let result = writer.envelope(
2473                mode,
2474                &ResponseHeader {
2475                    version: VERSION,
2476                    serial: header.serial,
2477                    broadcast: 0,
2478                    error: 0,
2479                    format: format.to_u8(),
2480                    channel: header.channel,
2481                    app: 0,
2482                },
2483            );
2484
2485            result.map_err(Error::encode_connect_header)?;
2486            writer.flush();
2487            Ok::<_, Error>(())
2488        })?;
2489
2490        self.push_outbound(buf);
2491        Ok(())
2492    }
2493
2494    /// Run the server.
2495    ///
2496    /// This must be called to handle buffered outgoing and incoming messages.
2497    pub async fn run(&mut self) -> Result<(), Error> {
2498        loop {
2499            // NB: `socket_flush` is part of this because `start_send` only
2500            // hands a message to the sink. Breaking as soon as the queues are
2501            // empty leaves the close frame in the sink's buffer, never on the
2502            // wire. Waiting is bounded by the deadline `begin_closing` arms.
2503            if self.closing && self.out.is_empty() && self.outbound.is_empty() && !self.socket_flush
2504            {
2505                break;
2506            }
2507
2508            self.handle_send()?;
2509
2510            // NB: Not reading is what pushes back on a peer which sends faster
2511            // than it is answered, or which never reads what it is sent. The
2512            // deadlines, the handlers and the write side are still driven, so
2513            // the connection keeps making progress towards reading again.
2514            let wants_socket_recv = self.socket_recv && !self.is_saturated();
2515
2516            let result = {
2517                let inner = Select::<S::Socket, H> {
2518                    pinned: self.pinned.as_mut(),
2519                    wants_socket_recv,
2520                    wants_socket_send: !self.socket_send,
2521                    wants_socket_flush: self.socket_flush,
2522                    set: &mut self.set,
2523                };
2524
2525                inner.await
2526            };
2527
2528            match result {
2529                Output::Close => {
2530                    // The deadline re-armed by `begin_closing` elapsed, so the
2531                    // peer never picked up the close frame which was queued for
2532                    // it. Drop the connection rather than queue another one.
2533                    if self.closing {
2534                        break;
2535                    }
2536
2537                    self.out
2538                        .push_back(S::close(CLOSE_NORMAL, "connection timed out"));
2539                    self.begin_closing();
2540                }
2541                Output::Ping => {
2542                    self.handle_ping()?;
2543                }
2544                Output::Recv(message) => {
2545                    let Some(message) = message else {
2546                        // NB: An ended stream is `Ready(None)` on every poll,
2547                        // so it has to be fused here or it masks the send and
2548                        // flush arms and nothing can ever drain.
2549                        self.socket_recv = false;
2550                        self.begin_closing();
2551                        continue;
2552                    };
2553
2554                    match message? {
2555                        // NB: The mode is fixed by the negotiation, so a frame
2556                        // of the other type carries an envelope this connection
2557                        // has no way to read.
2558                        Message::Text(bytes) => {
2559                            if self.mode.is_text() {
2560                                self.handle_message(bytes).await?;
2561                            } else {
2562                                self.out.push_back(S::close(
2563                                    CLOSE_PROTOCOL_ERROR,
2564                                    "Unexpected text message",
2565                                ));
2566                                self.begin_closing();
2567                            }
2568                        }
2569                        Message::Binary(bytes) => {
2570                            if self.mode.is_text() {
2571                                self.out.push_back(S::close(
2572                                    CLOSE_PROTOCOL_ERROR,
2573                                    "Unexpected binary message",
2574                                ));
2575                                self.begin_closing();
2576                            } else {
2577                                self.handle_message(bytes).await?;
2578                            }
2579                        }
2580                        Message::Ping(payload) => {
2581                            self.out.push_back(S::pong(payload));
2582                        }
2583                        Message::Pong(data) => {
2584                            self.handle_pong(data)?;
2585                        }
2586                        Message::Close => {
2587                            self.begin_closing();
2588                        }
2589                    }
2590                }
2591                Output::Send(result) => {
2592                    if let Err(err) = result {
2593                        return Err(Error::from(err));
2594                    };
2595
2596                    self.socket_send = true;
2597                }
2598                Output::Flushed(result) => {
2599                    if let Err(err) = result {
2600                        return Err(Error::from(err));
2601                    };
2602
2603                    self.socket_flush = false;
2604                }
2605                Output::Handle(result, written, header, buf) => {
2606                    let err = 'err: {
2607                        let res = match result {
2608                            Ok(res) => res,
2609                            Err(error) => {
2610                                self.format_error(error)?;
2611                                break 'err true;
2612                            }
2613                        };
2614
2615                        let res = match res.into_response() {
2616                            Ok(res) => res,
2617                            Err(error) => {
2618                                self.format_response_error(&error)?;
2619                                break 'err true;
2620                            }
2621                        };
2622
2623                        if !res.handled {
2624                            self.format_error_message(format_args!(
2625                                "No support for request {}",
2626                                header.id
2627                            ))?;
2628                            break 'err true;
2629                        }
2630
2631                        // NB: A handled request must be answered, otherwise
2632                        // the client waits for a response forever.
2633                        if !written {
2634                            self.format_error_message(format_args!(
2635                                "Handler for request {} wrote no response",
2636                                header.id
2637                            ))?;
2638                            break 'err true;
2639                        }
2640
2641                        self.push_outbound(buf);
2642                        false
2643                    };
2644
2645                    if err {
2646                        self.send_error(&header)?;
2647                    }
2648                }
2649            }
2650        }
2651
2652        // NB: Reported only now, so that the close frame explaining it made it
2653        // onto the wire first.
2654        match self.failure.take() {
2655            Some(error) => Err(error),
2656            None => Ok(()),
2657        }
2658    }
2659
2660    /// Write a broadcast message which no channel is credited with.
2661    ///
2662    /// The client sees it with a channel of [`ChannelId::NONE`]. Use
2663    /// [`Server::broadcast_from`] when the broadcast is the result of something
2664    /// a client did over a channel, so that client can tell it apart.
2665    ///
2666    /// Note that the written message is buffered, and will be sent when
2667    /// [`Server::run`] is called.
2668    pub fn broadcast<T>(&mut self, message: T) -> Result<(), Error>
2669    where
2670        T: Event,
2671    {
2672        self.broadcast_from(message, ChannelId::NONE)
2673    }
2674
2675    /// Write a broadcast message which originated from `origin`.
2676    ///
2677    /// The broadcast still reaches every listener of its kind on the client.
2678    /// `origin` only says which channel caused it: it is carried in the
2679    /// broadcast header, and the client reads it back as the channel of the
2680    /// packet, such as `web::Packet::channel`, or tests it with
2681    /// `web::Packet::is_from`. Passing [`ChannelId::NONE`] is the same as
2682    /// [`Server::broadcast`].
2683    ///
2684    /// The typical origin is the [`Incoming::channel`] of the request which
2685    /// made the change being broadcast, so that the page which made it can
2686    /// skip its own echo. The broadcast is usually written by the [`Server`]
2687    /// of every connection, not only the one the request came in over, which
2688    /// works because channel ids are unique across connections by default,
2689    /// see [`ChannelAllocator`]. See [Broadcast origin] for an example.
2690    ///
2691    /// Note that the written message is buffered, and will be sent when
2692    /// [`Server::run`] is called.
2693    ///
2694    /// [Broadcast origin]: self#broadcast-origin
2695    pub fn broadcast_from<T>(&mut self, message: T, origin: ChannelId) -> Result<(), Error>
2696    where
2697        T: Event,
2698    {
2699        tracing::debug!(id = ?<T::Broadcast as Broadcast>::ID, "Broadcast");
2700
2701        let format = self.format;
2702        let mode = self.mode;
2703
2704        let buf = self.pool.with(|buf| {
2705            let mut writer = buf.writer();
2706
2707            writer
2708                .envelope(
2709                    mode,
2710                    &ResponseHeader {
2711                        version: VERSION,
2712                        serial: 0,
2713                        broadcast: <T::Broadcast as Broadcast>::ID.get(),
2714                        error: 0,
2715                        format: format.to_u8(),
2716                        channel: origin,
2717                        app: 0,
2718                    },
2719                )
2720                .map_err(Error::encode_broadcast_header)?;
2721
2722            writer
2723                .body(format, &message)
2724                .map_err(Error::encode_broadcast)?;
2725            writer.flush();
2726            Ok::<_, Error>(())
2727        })?;
2728
2729        self.push_outbound(buf);
2730        Ok(())
2731    }
2732
2733    /// Write a broadcast message over a specific connection.
2734    ///
2735    /// Note that the written message is buffered, and will be sent when
2736    /// [`Server::run`] is called.
2737    fn hello(&mut self) -> Result<(), Error> {
2738        tracing::debug!("Hello");
2739
2740        let mut buf = self.pool.get();
2741
2742        let result = (|| {
2743            let mut writer = buf.writer();
2744
2745            writer
2746                // NB: Nothing has been heard from the client yet, so this is
2747                // the one message which cannot be spelled in a negotiated mode.
2748                .envelope(
2749                    Mode::DEFAULT,
2750                    &ResponseHeader {
2751                        version: VERSION,
2752                        serial: 0,
2753                        broadcast: MessageId::SERVER_HELLO.get(),
2754                        error: 0,
2755                        // NB: Carries no body, so no format applies.
2756                        format: 0,
2757                        channel: ChannelId::NONE,
2758                        // NB: Stated here, ahead of negotiation, so that a
2759                        // client from another build can tell before it has
2760                        // agreed to anything.
2761                        app: self.app,
2762                    },
2763                )
2764                .map_err(Error::encode_broadcast_header)?;
2765
2766            writer.flush();
2767            Ok::<_, Error>(())
2768        })();
2769
2770        if result.is_err() {
2771            self.pool.put(buf);
2772        } else {
2773            self.push_outbound(buf);
2774        }
2775
2776        Ok(())
2777    }
2778
2779    /// Prepare the error response for an error returned by a handler.
2780    fn format_response_error<E>(&mut self, error: &E) -> Result<(), Error>
2781    where
2782        E: ResponseError,
2783    {
2784        self.format_error_message(ErrorMessageDisplay(error))?;
2785
2786        let mut encoded = false;
2787
2788        // NB: Encoded with the connection format, since that is what
2789        // `send_error` writes the rest of the error with.
2790        let payload = ErrorPayload {
2791            format: self.format,
2792            out: &mut self.error_payload,
2793            encoded: &mut encoded,
2794        };
2795
2796        match error.encode_payload(payload) {
2797            Ok(()) => {
2798                self.error_typed = encoded;
2799            }
2800            Err(error) => {
2801                // NB: The message still reaches the client, which is better
2802                // than failing the connection over an error it could not see.
2803                tracing::warn!(
2804                    ?error,
2805                    "Failed to encode typed error, sending its message only"
2806                );
2807            }
2808        }
2809
2810        Ok(())
2811    }
2812
2813    fn format_error_message(&mut self, error: impl fmt::Display) -> Result<(), Error> {
2814        self.error.clear();
2815        self.error_typed = false;
2816
2817        if write!(self.error, "{error}").is_err() {
2818            self.error.clear();
2819            return Err(Error::new(ErrorKind::FormatError));
2820        }
2821
2822        Ok(())
2823    }
2824
2825    fn format_error(&mut self, error: impl core::error::Error) -> Result<(), Error> {
2826        self.error.clear();
2827        self.error_typed = false;
2828
2829        if write!(self.error, "{error:#}").is_err() {
2830            self.error.clear();
2831            return Err(Error::new(ErrorKind::FormatError));
2832        }
2833
2834        Ok(())
2835    }
2836
2837    #[tracing::instrument(skip(self, bytes))]
2838    async fn handle_message(&mut self, bytes: Bytes) -> Result<(), Error> {
2839        let mut at = 0;
2840
2841        let header: RequestHeader = match format::decode_envelope(self.mode, &bytes, &mut at) {
2842            Ok(header) => header,
2843            // NB: A header this build does not know about means the peer is
2844            // speaking a protocol this one does not have, so the rest of the
2845            // message cannot be acted on even though it parsed. The failure is
2846            // held so the close frame explaining it still reaches the peer.
2847            Err(error) if error.unsupported_version().is_some() => {
2848                tracing::debug!(?error, "Unsupported protocol version");
2849                self.out.push_back(S::close(
2850                    CLOSE_PROTOCOL_ERROR,
2851                    "Unsupported protocol version",
2852                ));
2853                self.begin_closing();
2854                self.failure
2855                    .get_or_insert_with(|| Error::new(ErrorKind::UnsupportedVersion { error }));
2856                return Ok(());
2857            }
2858            Err(error) if error.is_unknown_header() => {
2859                tracing::debug!(?error, "Unknown header");
2860                self.out
2861                    .push_back(S::close(CLOSE_PROTOCOL_ERROR, "Unknown header"));
2862                self.begin_closing();
2863                self.failure
2864                    .get_or_insert_with(|| Error::new(ErrorKind::UnknownHeader { error }));
2865                return Ok(());
2866            }
2867            Err(error) => {
2868                tracing::debug!(?error, "Invalid request header");
2869                self.out
2870                    .push_back(S::close(CLOSE_PROTOCOL_ERROR, "Invalid request header"));
2871                self.begin_closing();
2872                return Ok(());
2873            }
2874        };
2875
2876        let err = 'err: {
2877            let Some(id) = MessageId::new(header.id) else {
2878                self.format_error_message(format_args!("Unsupported message id {}", header.id))?;
2879                break 'err true;
2880            };
2881
2882            match id {
2883                MessageId::CONNECT => {
2884                    let channel = match self.channels.open() {
2885                        Ok(channel) => channel,
2886                        Err(error) => {
2887                            self.format_error_message(format_args!("{error}"))?;
2888                            break 'err true;
2889                        }
2890                    };
2891
2892                    self.handler.open_channel(channel).await;
2893
2894                    let mut buf = self.pool.get();
2895                    let mode = self.mode;
2896
2897                    let result = (|| {
2898                        let mut writer = buf.writer();
2899
2900                        let result = writer.envelope(
2901                            mode,
2902                            &ResponseHeader {
2903                                version: VERSION,
2904                                serial: header.serial,
2905                                broadcast: 0,
2906                                error: 0,
2907                                format: 0,
2908                                channel,
2909                                app: 0,
2910                            },
2911                        );
2912
2913                        result.map_err(Error::encode_connect_header)?;
2914                        writer.flush();
2915                        Ok::<_, Error>(())
2916                    })();
2917
2918                    if result.is_err() {
2919                        self.pool.put(buf);
2920                    } else {
2921                        self.push_outbound(buf);
2922                    }
2923
2924                    result?;
2925                    break 'err false;
2926                }
2927                MessageId::DISCONNECT => {
2928                    // NB: Only a channel this connection opened is closed. An
2929                    // id which belongs to some other connection, or to none,
2930                    // must not go back into a pool other connections draw
2931                    // from.
2932                    if self.channels.close(header.channel) {
2933                        self.handler.close_channel(header.channel).await;
2934                    } else {
2935                        tracing::debug!(channel = ?header.channel, "Ignoring close of a channel which is not open");
2936                    }
2937
2938                    break 'err false;
2939                }
2940                MessageId::NEGOTIATE => {
2941                    // NB: The format is settled once and for all by the
2942                    // connection step, see `Connect::connect`. Letting it move
2943                    // afterwards would mean messages already queued for the old
2944                    // format go out under the new one.
2945                    let format = self.format;
2946
2947                    self.format_error_message(format_args!(
2948                        "Format `{format}` has already been negotiated"
2949                    ))?;
2950
2951                    break 'err true;
2952                }
2953                _ => {
2954                    let Some(format) = Format::from_u8(header.format) else {
2955                        self.format_error_message(format_args!(
2956                            "Unknown format id {}",
2957                            header.format
2958                        ))?;
2959
2960                        break 'err true;
2961                    };
2962
2963                    if !self.accepts(format) {
2964                        self.format_error_message(format_args!(
2965                            "Unsupported format `{format}`, supported: {}",
2966                            SupportedFormats(self.formats)
2967                        ))?;
2968
2969                        break 'err true;
2970                    }
2971
2972                    // NB: The response goes back in the same frame type the
2973                    // request arrived in, so a format which cannot be spelled
2974                    // that way has nowhere to go.
2975                    if !self.mode.accepts(format) {
2976                        let mode = self.mode;
2977
2978                        self.format_error_message(format_args!(
2979                            "Mode `{mode}` cannot carry the `{format}` format"
2980                        ))?;
2981
2982                        break 'err true;
2983                    }
2984
2985                    let id = <H::Id as Id>::from_id(id);
2986                    self.handle_request(bytes, at, header, id, format);
2987                    return Ok(());
2988                }
2989            }
2990        };
2991
2992        if err {
2993            self.send_error(&header)?;
2994        }
2995
2996        Ok(())
2997    }
2998
2999    fn send_error(&mut self, header: &RequestHeader) -> Result<(), Error> {
3000        // NB: Errors are encoded with the connection format rather than the
3001        // format the request asked for, since the request might have failed
3002        // precisely because that format is not supported. The client reads the
3003        // format back out of the response envelope either way.
3004        let format = self.format;
3005        let mode = self.mode;
3006
3007        // NB: Taken so that a later error is never sent with this payload.
3008        let typed = mem::take(&mut self.error_typed);
3009
3010        let error = if typed {
3011            MessageId::TYPED_ERROR_MESSAGE
3012        } else {
3013            MessageId::ERROR_MESSAGE
3014        };
3015
3016        let buf = self.pool.with(|buf| {
3017            // Reset the buffer to the previous start point.
3018            let mut writer = buf.writer();
3019
3020            let result = writer.envelope(
3021                mode,
3022                &ResponseHeader {
3023                    version: VERSION,
3024                    serial: header.serial,
3025                    broadcast: 0,
3026                    error: error.get(),
3027                    format: format.to_u8(),
3028                    channel: header.channel,
3029                    app: 0,
3030                },
3031            );
3032
3033            result.map_err(Error::encode_error_message_header)?;
3034
3035            let result = writer.body(
3036                format,
3037                &ErrorMessage {
3038                    message: &self.error,
3039                },
3040            );
3041
3042            result.map_err(Error::encode_error_message)?;
3043
3044            // NB: The payload was already encoded with `format`, see
3045            // `format_response_error`.
3046            if typed {
3047                writer.raw(&self.error_payload);
3048            }
3049
3050            writer.flush();
3051            Ok::<_, Error>(())
3052        })?;
3053
3054        self.push_outbound(buf);
3055        Ok(())
3056    }
3057
3058    /// Queue a buffer to be written to the peer.
3059    fn push_outbound(&mut self, buf: Buf) {
3060        self.outbound_bytes = self.outbound_bytes.saturating_add(buf.remaining());
3061        self.outbound.push_back(buf);
3062    }
3063
3064    /// Test if the connection has as much work queued as it is allowed, in
3065    /// which case nothing more is read from the peer until it has drained.
3066    fn is_saturated(&self) -> bool {
3067        self.set.len() >= self.max_in_flight || self.outbound_bytes >= self.max_outbound
3068    }
3069
3070    /// Begin winding the connection down.
3071    ///
3072    /// This re-arms the close deadline so that draining whatever is left to
3073    /// send is bounded too. Re-arming is also what keeps [`Server::run`] from
3074    /// spinning: an elapsed [`Sleep`] reports `Ready` every time it is polled,
3075    /// so leaving it elapsed would make [`Select`] hand back [`Output::Close`]
3076    /// over and over without the loop ever making progress.
3077    fn begin_closing(&mut self) {
3078        if self.closing {
3079            return;
3080        }
3081
3082        self.closing = true;
3083
3084        let (close_sleep, _, _) = self.pinned.as_mut().project();
3085        close_sleep.reset(Instant::now() + CLOSE_TIMEOUT);
3086    }
3087
3088    #[tracing::instrument(skip(self))]
3089    fn handle_ping(&mut self) -> Result<(), Error> {
3090        let (_, mut ping_sleep, _) = self.pinned.as_mut().project();
3091
3092        let payload = self.rng.random::<u32>();
3093        let payload = payload.to_ne_bytes();
3094
3095        self.last_ping = Some(payload);
3096
3097        tracing::debug!(data = ?&payload[..], "Sending ping");
3098
3099        self.out
3100            .push_back(S::ping(Bytes::from_owner(Vec::from(payload))));
3101
3102        let now = Instant::now();
3103        ping_sleep.as_mut().reset(now + PING_TIMEOUT);
3104        Ok(())
3105    }
3106
3107    #[tracing::instrument(skip(self, payload))]
3108    fn handle_pong(&mut self, payload: Bytes) -> Result<(), Error> {
3109        let (close_sleep, ping_sleep, _) = self.pinned.as_mut().project();
3110
3111        tracing::debug!(payload = ?&payload[..], "Pong");
3112
3113        let Some(expected) = self.last_ping else {
3114            tracing::debug!("No ping sent");
3115            return Ok(());
3116        };
3117
3118        if expected[..] != payload[..] {
3119            tracing::debug!(?expected, ?payload, "Pong doesn't match");
3120            return Ok(());
3121        }
3122
3123        let now = Instant::now();
3124
3125        close_sleep.reset(now + CLOSE_TIMEOUT);
3126        ping_sleep.reset(now + PING_TIMEOUT);
3127        self.last_ping = None;
3128        Ok(())
3129    }
3130
3131    #[tracing::instrument(skip(self))]
3132    fn handle_send(&mut self) -> Result<(), Error> {
3133        let (_, _, mut socket) = self.pinned.as_mut().project();
3134
3135        if self.socket_send {
3136            if let Some(message) = self.out.pop_front() {
3137                socket.as_mut().start_send(message)?;
3138                self.socket_flush = true;
3139                self.socket_send = false;
3140            }
3141        }
3142
3143        while self.socket_send {
3144            let Some(buf) = self.outbound.front_mut() else {
3145                break;
3146            };
3147
3148            let Some(frame) = buf.read()? else {
3149                if let Some(buf) = self.outbound.pop_front() {
3150                    self.pool.put(buf);
3151                }
3152
3153                // NB: Keeps the count from drifting if anything ever bypasses
3154                // `push_outbound`.
3155                if self.outbound.is_empty() {
3156                    self.outbound_bytes = 0;
3157                }
3158
3159                continue;
3160            };
3161
3162            self.outbound_bytes = self
3163                .outbound_bytes
3164                .saturating_sub(frame.len().saturating_add(mem::size_of::<u32>()));
3165
3166            let message = match self.mode {
3167                Mode::Binary => S::binary(frame),
3168                Mode::Text => S::text(frame),
3169            };
3170
3171            socket.as_mut().start_send(message)?;
3172
3173            self.socket_flush = true;
3174            self.socket_send = false;
3175            break;
3176        }
3177
3178        Ok(())
3179    }
3180
3181    fn handle_request(
3182        &mut self,
3183        bytes: Bytes,
3184        offset: usize,
3185        header: RequestHeader,
3186        id: H::Id,
3187        format: Format,
3188    ) {
3189        tracing::debug!(header.serial, ?id, ?format, "Got request");
3190
3191        let mut buf = self.pool.get();
3192        let handler = self.handler.clone();
3193        let mode = self.mode;
3194
3195        self.set.spawn(async move {
3196            if offset > bytes.len() {
3197                let kind = ErrorKind::OutOfBounds {
3198                    offset,
3199                    len: bytes.len(),
3200                };
3201
3202                return (Err(Error::new(kind)), false, header, buf);
3203            }
3204
3205            let mut incoming = Incoming {
3206                error: None,
3207                buf: &bytes,
3208                at: offset,
3209                format,
3210                channel: header.channel,
3211            };
3212
3213            let mut outgoing = Outgoing {
3214                serial: Some(header.serial),
3215                error: None,
3216                buf: &mut buf,
3217                format,
3218                mode,
3219                channel: header.channel,
3220            };
3221
3222            let response = handler.handle(id, &mut incoming, &mut outgoing).await;
3223            let written = outgoing.serial.is_none();
3224
3225            if let Some(error) = incoming.error.take() {
3226                return (Err(Error::incoming(error)), written, header, buf);
3227            }
3228
3229            if let Some(error) = outgoing.error.take() {
3230                return (Err(Error::outgoing(error)), written, header, buf);
3231            }
3232
3233            (Ok(response), written, header, buf)
3234        });
3235    }
3236}
3237
3238enum Output<E, R> {
3239    /// The connection should be closed.
3240    Close,
3241    /// A ping message was received.
3242    Ping,
3243    /// A message was received.
3244    Recv(Option<Result<Message, E>>),
3245    /// A message is ready to be sent.
3246    Send(Result<(), E>),
3247    /// Outgoing messages have been successfully flushed.
3248    Flushed(Result<(), E>),
3249    /// Handle output, and whether the handler wrote a response.
3250    Handle(Result<R, Error>, bool, RequestHeader, Buf),
3251}
3252
3253struct Select<'a, S, H>
3254where
3255    H: Handler,
3256{
3257    pinned: Pin<&'a mut Pinned<S>>,
3258    wants_socket_recv: bool,
3259    wants_socket_send: bool,
3260    wants_socket_flush: bool,
3261    set: &'a mut JoinSet<HandlerOutput<H>>,
3262}
3263
3264impl<S, H> Future for Select<'_, S, H>
3265where
3266    S: SocketImpl,
3267    H: Handler,
3268{
3269    type Output = Output<S::Error, H::Response>;
3270
3271    #[inline]
3272    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
3273        // NB: Every field is `Unpin`, the pinned state is behind a `Pin` of
3274        // its own.
3275        let this = Pin::get_mut(self);
3276        let (close, ping, mut socket) = this.pinned.as_mut().project();
3277        let wants_socket_recv = this.wants_socket_recv;
3278        let wants_socket_send = this.wants_socket_send;
3279        let wants_socket_flush = this.wants_socket_flush;
3280        let set = &mut this.set;
3281
3282        if close.poll(cx).is_ready() {
3283            return Poll::Ready(Output::Close);
3284        }
3285
3286        if ping.poll(cx).is_ready() {
3287            return Poll::Ready(Output::Ping);
3288        }
3289
3290        if wants_socket_recv {
3291            if let Poll::Ready(output) = socket.as_mut().poll_next(cx) {
3292                return Poll::Ready(Output::Recv(output));
3293            }
3294        }
3295
3296        if wants_socket_send {
3297            if let Poll::Ready(result) = socket.as_mut().poll_ready(cx) {
3298                return Poll::Ready(Output::Send(result));
3299            }
3300        }
3301
3302        if wants_socket_flush {
3303            if let Poll::Ready(result) = socket.as_mut().poll_flush(cx) {
3304                return Poll::Ready(Output::Flushed(result));
3305            }
3306        }
3307
3308        // NB: An empty `JoinSet` is `Ready(None)` and registers no waker, so
3309        // this drops through to `Pending` having registered nothing of its
3310        // own. That is only safe because the two deadlines above are polled
3311        // unconditionally and have registered theirs.
3312        if let Poll::Ready(Some(output)) = set.poll_join_next(cx) {
3313            let output = match output {
3314                Ok(output) => output,
3315                Err(error) => {
3316                    tracing::debug!(?error, "Join error in handler task");
3317                    return Poll::Ready(Output::Close);
3318                }
3319            };
3320
3321            let (result, written, header, buf) = output;
3322            return Poll::Ready(Output::Handle(result, written, header, buf));
3323        }
3324
3325        Poll::Pending
3326    }
3327}
3328
3329/// The buffer for incoming requests.
3330///
3331/// See [`server()`] for how to use with `axum`.
3332///
3333/// [`server()`]: crate::axum08::server
3334pub struct Incoming<'de> {
3335    error: Option<format::Error>,
3336    buf: &'de [u8],
3337    at: usize,
3338    format: Format,
3339    channel: ChannelId,
3340}
3341
3342impl<'de> Incoming<'de> {
3343    /// The channel over which the incoming request was received.
3344    ///
3345    /// This is [`ChannelId::NONE`] unless the client sent the request over a
3346    /// channel, such as one opened with [`Handle::channel`]. Pass it to
3347    /// [`Server::broadcast_from`] to credit a broadcast to the channel whose
3348    /// request caused it.
3349    ///
3350    /// [`Handle::channel`]: crate::web::Handle::channel
3351    pub fn channel(&self) -> ChannelId {
3352        self.channel
3353    }
3354
3355    /// The [`Format`] the incoming request body is encoded with.
3356    ///
3357    /// This is the format the client declared for this particular request, and
3358    /// is also the format the response will be written with.
3359    #[inline]
3360    pub fn format(&self) -> Format {
3361        self.format
3362    }
3363
3364    /// Read a request and return `Some(T)` if the request was successfully
3365    /// decoded.
3366    ///
3367    /// Note that any failure to decode will be propagated as an error
3368    /// automatically, the user does not have to deal with it themselves.
3369    /// Instead, failure to decode should be treated as if the request was
3370    /// unhandled by returning for example `false` or `Option::None`.
3371    #[inline]
3372    pub fn read<T>(&mut self) -> Option<T>
3373    where
3374        T: DecodeBody<'de>,
3375    {
3376        match self.format.decode(self.buf, &mut self.at) {
3377            Ok(value) => Some(value),
3378            Err(error) => {
3379                self.error = Some(error);
3380                None
3381            }
3382        }
3383    }
3384}
3385
3386/// The buffer for outgoing responses.
3387///
3388/// See [`server()`] for how to use with `axum`.
3389///
3390/// [`server()`]: crate::axum08::server
3391pub struct Outgoing<'a> {
3392    serial: Option<u32>,
3393    error: Option<format::Error>,
3394    buf: &'a mut Buf,
3395    format: Format,
3396    mode: Mode,
3397    channel: ChannelId,
3398}
3399
3400impl Outgoing<'_> {
3401    /// The [`Format`] the response will be encoded with, which is the format
3402    /// the corresponding request declared.
3403    #[inline]
3404    pub fn format(&self) -> Format {
3405        self.format
3406    }
3407
3408    /// The [`Mode`] the response will be spelled in, which is the mode the
3409    /// corresponding request arrived in.
3410    #[inline]
3411    pub fn mode(&self) -> Mode {
3412        self.mode
3413    }
3414
3415    /// Write a response.
3416    ///
3417    /// This can only be called once. Calling this multiple times has no effect.
3418    ///
3419    /// A handler which reports a request as handled must call this, otherwise
3420    /// the client receives an error instead of a response. See
3421    /// [`Handler::handle`].
3422    ///
3423    /// See [`server()`] for how to use with `axum`.
3424    ///
3425    /// [`server()`]: crate::axum08::server
3426    pub fn write<T>(&mut self, value: T)
3427    where
3428        T: EncodeBody,
3429    {
3430        let Some(serial) = self.serial.take() else {
3431            return;
3432        };
3433
3434        let mut writer = self.buf.writer();
3435
3436        let result = writer.envelope(
3437            self.mode,
3438            &ResponseHeader {
3439                version: VERSION,
3440                serial,
3441                broadcast: 0,
3442                error: 0,
3443                format: self.format.to_u8(),
3444                channel: self.channel,
3445                app: 0,
3446            },
3447        );
3448
3449        if let Err(error) = result {
3450            self.error = Some(error);
3451            return;
3452        }
3453
3454        if let Err(error) = writer.body(self.format, &value) {
3455            self.error = Some(error);
3456        }
3457
3458        writer.flush();
3459    }
3460}
3461
3462/// Scramble a sequential channel id into a value that looks random to clients.
3463///
3464/// Uses an odd multiply followed by an XOR-shift (bijective over u16, preserves
3465/// 0, self-inverse).
3466#[inline]
3467fn scramble_channel(x: u16) -> u16 {
3468    let x = x.wrapping_mul(0x9285);
3469    x ^ (x >> 8)
3470}
3471
3472/// Inverse of [`scramble_channel`].
3473#[inline]
3474#[cfg(test)]
3475fn unscramble_channel(x: u16) -> u16 {
3476    let x = x ^ (x >> 8);
3477    x.wrapping_mul(0x964d)
3478}
3479
3480#[test]
3481fn test_scramble() {
3482    assert_eq!(scramble_channel(0), 0);
3483    assert_eq!(unscramble_channel(0), 0);
3484
3485    for i in 1..=u16::MAX {
3486        let scrambled = scramble_channel(i);
3487        let unscrambled = unscramble_channel(scrambled);
3488        assert_eq!(i, unscrambled, "Failed to unscramble channel id");
3489    }
3490}
3491
3492#[derive(Default)]
3493struct ChannelsInner {
3494    last: u16,
3495    free: VecDeque<NonZeroU16>,
3496}
3497
3498/// The pool behind [`Channels::global()`].
3499static GLOBAL_CHANNELS: LazyLock<Channels> = LazyLock::new(Channels::new);
3500
3501/// The default [`ChannelAllocator`], a pool of channel ids.
3502///
3503/// Every clone of a `Channels` allocates from the same pool, so the ids it
3504/// hands out are distinct from one another for as long as they are held. Ids
3505/// are reused once freed.
3506///
3507/// [`Channels::global()`] is the pool every [`Server`] uses unless told
3508/// otherwise, which makes channel ids unique across every connection in the
3509/// process. [`Channels::new()`] is a pool of its own, for when ids should be
3510/// scoped more narrowly, see [`ChannelAllocator`].
3511///
3512/// A pool holds at most [`u16::MAX`] ids at once.
3513#[derive(Clone)]
3514pub struct Channels {
3515    inner: Arc<Mutex<ChannelsInner>>,
3516}
3517
3518impl Channels {
3519    /// Construct a new pool of channel ids which is independent of every other
3520    /// pool, including [`Channels::global()`].
3521    ///
3522    /// # Examples
3523    ///
3524    /// ```
3525    /// use musli_web::ws::{ChannelAllocator, Channels};
3526    ///
3527    /// let channels = Channels::new();
3528    /// let a = channels.next().unwrap();
3529    /// let b = channels.clone().next().unwrap();
3530    /// assert_ne!(a, b);
3531    /// ```
3532    #[inline]
3533    pub fn new() -> Self {
3534        Self {
3535            inner: Arc::new(Mutex::new(ChannelsInner::default())),
3536        }
3537    }
3538
3539    /// The process-wide pool of channel ids, which every [`Server`] allocates
3540    /// from by default.
3541    ///
3542    /// # Examples
3543    ///
3544    /// ```
3545    /// use musli_web::ws::{ChannelAllocator, Channels};
3546    ///
3547    /// let a = Channels::global().next().unwrap();
3548    /// let b = Channels::global().next().unwrap();
3549    /// assert_ne!(a, b);
3550    /// ```
3551    #[inline]
3552    pub fn global() -> Self {
3553        GLOBAL_CHANNELS.clone()
3554    }
3555
3556    #[inline]
3557    fn lock(&self) -> MutexGuard<'_, ChannelsInner> {
3558        // NB: Nothing panics while the lock is held, and the state is valid
3559        // between every statement anyway.
3560        self.inner.lock().unwrap_or_else(PoisonError::into_inner)
3561    }
3562}
3563
3564impl Default for Channels {
3565    /// Same as [`Channels::new()`].
3566    #[inline]
3567    fn default() -> Self {
3568        Self::new()
3569    }
3570}
3571
3572impl ChannelAllocator for Channels {
3573    #[inline]
3574    fn next(&self) -> Option<ChannelId> {
3575        let mut inner = self.lock();
3576
3577        if let Some(id) = inner.free.pop_front() {
3578            return Some(ChannelId::from_u16(id.get()));
3579        }
3580
3581        let id = NonZeroU16::new(inner.last.wrapping_add(1))?;
3582        inner.last = id.get();
3583
3584        tracing::debug!(?id, "Allocated channel id");
3585        Some(ChannelId::from_u16(scramble_channel(id.get())))
3586    }
3587
3588    #[inline]
3589    fn free(&self, id: ChannelId) {
3590        tracing::debug!(?id, "Freeing channel id");
3591
3592        if let Some(id) = NonZeroU16::new(id.raw()) {
3593            self.lock().free.push_back(id);
3594        }
3595    }
3596}
3597
3598/// Why a channel could not be opened.
3599#[derive(Debug, PartialEq, Eq)]
3600enum OpenChannelError {
3601    /// The client already holds as many channels as it may.
3602    Limit(usize),
3603    /// The allocator has no id to hand out.
3604    Exhausted,
3605}
3606
3607impl fmt::Display for OpenChannelError {
3608    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3609        match self {
3610            Self::Limit(limit) => write!(f, "Too many open channels, at most {limit} are allowed"),
3611            Self::Exhausted => f.write_str("No channel id is available"),
3612        }
3613    }
3614}
3615
3616/// The channels one client holds, allocated from `C`.
3617///
3618/// This is what keeps a connection to the ids it was handed: only those are
3619/// ever freed, and every one still held is freed on drop.
3620struct OwnedChannels<C>
3621where
3622    C: ChannelAllocator,
3623{
3624    allocator: C,
3625    open: BTreeSet<ChannelId>,
3626    max: usize,
3627}
3628
3629impl<C> OwnedChannels<C>
3630where
3631    C: ChannelAllocator,
3632{
3633    #[inline]
3634    fn new(allocator: C, max: usize) -> Self {
3635        Self {
3636            allocator,
3637            open: BTreeSet::new(),
3638            max,
3639        }
3640    }
3641
3642    /// Allocate and take hold of a new channel.
3643    fn open(&mut self) -> Result<ChannelId, OpenChannelError> {
3644        if self.open.len() >= self.max {
3645            return Err(OpenChannelError::Limit(self.max));
3646        }
3647
3648        let id = self.allocator.next().ok_or(OpenChannelError::Exhausted)?;
3649
3650        // NB: An allocator which breaks its contract by handing out no
3651        // channel, or one this connection already holds, is refused. Neither
3652        // is freed here: the first was never allocated and the second is
3653        // freed once, when the channel it already names closes.
3654        if id == ChannelId::NONE || !self.open.insert(id) {
3655            return Err(OpenChannelError::Exhausted);
3656        }
3657
3658        Ok(id)
3659    }
3660
3661    /// Release a channel, returning `false` if it is not held.
3662    fn close(&mut self, id: ChannelId) -> bool {
3663        if !self.open.remove(&id) {
3664            return false;
3665        }
3666
3667        self.allocator.free(id);
3668        true
3669    }
3670}
3671
3672impl<C> Drop for OwnedChannels<C>
3673where
3674    C: ChannelAllocator,
3675{
3676    fn drop(&mut self) {
3677        for id in mem::take(&mut self.open) {
3678            self.allocator.free(id);
3679        }
3680    }
3681}
3682
3683/// Renders the formats a server is willing to negotiate, for error messages.
3684struct SupportedFormats(Option<&'static [Format]>);
3685
3686impl fmt::Display for SupportedFormats {
3687    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3688        let mut first = true;
3689
3690        for format in Format::supported() {
3691            if self.0.is_some_and(|formats| !formats.contains(&format)) {
3692                continue;
3693            }
3694
3695            if !first {
3696                f.write_str(", ")?;
3697            }
3698
3699            write!(f, "`{format}`")?;
3700            first = false;
3701        }
3702
3703        if first {
3704            f.write_str("none")?;
3705        }
3706
3707        Ok(())
3708    }
3709}
3710
3711#[cfg(test)]
3712mod tests {
3713    use core::cell::Cell;
3714
3715    use std::thread_local;
3716
3717    use super::*;
3718
3719    /// How many close frames the loop is allowed to manufacture before the test
3720    /// concludes that it is spinning.
3721    ///
3722    /// A close frame is the only observable thing the wind-down path produces,
3723    /// so this is what bounds the test. Without it a regression makes
3724    /// [`Server::run`] loop forever inside a single poll and the test hangs
3725    /// rather than fails.
3726    const CLOSE_BUDGET: usize = 4;
3727
3728    /// How many times a stream which has ended is allowed to be polled before
3729    /// the test concludes that [`Server::run`] is spinning on it.
3730    ///
3731    /// Such a stream reports `Ready(None)` on every poll, so a regression makes
3732    /// the loop poll it forever inside a single task poll and the test hangs
3733    /// rather than fails.
3734    const RECV_BUDGET: usize = 4;
3735
3736    thread_local! {
3737        /// The number of close frames [`TestServerImpl::close`] has handed out
3738        /// on this thread, which is one test.
3739        static CLOSE_FRAMES: Cell<usize> = const { Cell::new(0) };
3740    }
3741
3742    #[derive(Debug)]
3743    enum TestError {}
3744
3745    impl From<TestError> for Error {
3746        #[inline]
3747        fn from(error: TestError) -> Self {
3748            match error {}
3749        }
3750    }
3751
3752    #[derive(Debug, PartialEq, Eq)]
3753    enum TestMessage {
3754        Ping(Bytes),
3755        Pong(Bytes),
3756        Binary(Vec<u8>),
3757        Text(Vec<u8>),
3758        Close(u16),
3759    }
3760
3761    /// A socket which never hears anything from its peer, which is the state a
3762    /// connection is in when its close deadline elapses.
3763    #[derive(Default)]
3764    struct TestSocket {
3765        sent: Vec<TestMessage>,
3766        /// Whether the peer has gone away, which makes the stream report
3767        /// `Ready(None)` on every poll for the rest of its life.
3768        ended: bool,
3769        polls_after_end: usize,
3770        /// Whether the write side has backpressure, which is what a real sink
3771        /// does while the socket buffer it is writing into has not drained.
3772        write_blocked: bool,
3773        /// Messages the peer has sent which are yet to be read.
3774        incoming: VecDeque<Message>,
3775    }
3776
3777    impl socket_sealed::Sealed for TestSocket {}
3778
3779    impl SocketImpl for TestSocket {
3780        type Message = TestMessage;
3781        type Error = TestError;
3782
3783        fn poll_next(
3784            self: Pin<&mut Self>,
3785            _: &mut Context<'_>,
3786        ) -> Poll<Option<Result<Message, Self::Error>>> {
3787            // SAFETY: Nothing in this socket is structurally pinned.
3788            let this = unsafe { Pin::get_unchecked_mut(self) };
3789
3790            if let Some(message) = this.incoming.pop_front() {
3791                return Poll::Ready(Some(Ok(message)));
3792            }
3793
3794            if !this.ended {
3795                return Poll::Pending;
3796            }
3797
3798            this.polls_after_end += 1;
3799
3800            assert!(
3801                this.polls_after_end <= RECV_BUDGET,
3802                "`Server::run` is spinning: an ended stream was polled {} times without any progress",
3803                this.polls_after_end
3804            );
3805
3806            Poll::Ready(None)
3807        }
3808
3809        fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
3810            // SAFETY: Nothing in this socket is structurally pinned.
3811            if unsafe { Pin::get_unchecked_mut(self) }.write_blocked {
3812                return Poll::Pending;
3813            }
3814
3815            Poll::Ready(Ok(()))
3816        }
3817
3818        fn start_send(self: Pin<&mut Self>, item: Self::Message) -> Result<(), Self::Error> {
3819            // SAFETY: Nothing in this socket is structurally pinned.
3820            unsafe { Pin::get_unchecked_mut(self).sent.push(item) };
3821            Ok(())
3822        }
3823
3824        fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
3825            // SAFETY: Nothing in this socket is structurally pinned.
3826            if unsafe { Pin::get_unchecked_mut(self) }.write_blocked {
3827                return Poll::Pending;
3828            }
3829
3830            Poll::Ready(Ok(()))
3831        }
3832    }
3833
3834    struct TestServerImpl;
3835
3836    impl server_sealed::Sealed for TestServerImpl {}
3837
3838    impl ServerImpl for TestServerImpl {
3839        type Error = TestError;
3840        type Message = TestMessage;
3841        type Socket = TestSocket;
3842
3843        fn ping(data: Bytes) -> Self::Message {
3844            TestMessage::Ping(data)
3845        }
3846
3847        fn pong(data: Bytes) -> Self::Message {
3848            TestMessage::Pong(data)
3849        }
3850
3851        fn binary(data: &[u8]) -> Self::Message {
3852            TestMessage::Binary(data.to_vec())
3853        }
3854
3855        fn text(data: &[u8]) -> Self::Message {
3856            TestMessage::Text(data.to_vec())
3857        }
3858
3859        fn close(code: u16, _: &str) -> Self::Message {
3860            let frames = CLOSE_FRAMES.with(|frames| {
3861                let count = frames.get() + 1;
3862                frames.set(count);
3863                count
3864            });
3865
3866            assert!(
3867                frames <= CLOSE_BUDGET,
3868                "`Server::run` is spinning: {frames} close frames without any progress"
3869            );
3870
3871            TestMessage::Close(code)
3872        }
3873    }
3874
3875    #[derive(Debug)]
3876    struct TestId;
3877
3878    impl Id for TestId {
3879        const IDS: IdSet = IdSet::EMPTY;
3880
3881        fn id(&self) -> MessageId {
3882            MessageId::NEGOTIATE
3883        }
3884
3885        fn from_id(_: MessageId) -> Self {
3886            Self
3887        }
3888
3889        fn try_from_id(_: MessageId) -> Option<Self> {
3890            None
3891        }
3892
3893        fn __do_not_implement_id() {}
3894    }
3895
3896    #[derive(Clone, Default)]
3897    struct TestHandler {
3898        /// Whether requests are never answered, which keeps every handler
3899        /// in flight.
3900        block: bool,
3901    }
3902
3903    impl Handler for TestHandler {
3904        type Id = TestId;
3905        type Response = bool;
3906
3907        async fn handle(&self, _: Self::Id, _: &mut Incoming<'_>, _: &mut Outgoing<'_>) -> bool {
3908            if self.block {
3909                core::future::pending::<()>().await;
3910            }
3911
3912            false
3913        }
3914    }
3915
3916    /// Build a negotiated server whose close deadline elapsed `elapsed` ago.
3917    fn timed_out_server(elapsed: Duration) -> Server<TestServerImpl, TestHandler, Channels> {
3918        server_with(Instant::now() - elapsed)
3919    }
3920
3921    /// The test socket behind the server's pinned state.
3922    fn socket(server: &mut Server<TestServerImpl, TestHandler, Channels>) -> &mut TestSocket {
3923        let (_, _, socket) = server.pinned.as_mut().project();
3924        // SAFETY: Nothing in this socket is structurally pinned.
3925        unsafe { Pin::get_unchecked_mut(socket) }
3926    }
3927
3928    /// A response buffer of the shape a handler leaves behind in `outbound`.
3929    fn response(server: &Server<TestServerImpl, TestHandler, Channels>) -> Buf {
3930        server
3931            .pool
3932            .with(|buf| {
3933                let mut writer = buf.writer();
3934
3935                writer
3936                    .envelope(
3937                        Mode::DEFAULT,
3938                        &ResponseHeader {
3939                            version: VERSION,
3940                            serial: 1,
3941                            broadcast: 0,
3942                            error: 0,
3943                            format: Format::DEFAULT.to_u8(),
3944                            channel: ChannelId::NONE,
3945                            app: 0,
3946                        },
3947                    )
3948                    .map_err(Error::encode_connect_header)?;
3949
3950                writer.flush();
3951                Ok::<_, Error>(())
3952            })
3953            .unwrap()
3954    }
3955
3956    /// Build a negotiated server which winds down at `close_deadline`.
3957    fn server_with(close_deadline: Instant) -> Server<TestServerImpl, TestHandler, Channels> {
3958        let now = Instant::now();
3959
3960        Server {
3961            handler: TestHandler::default(),
3962            pinned: Box::pin(Pinned {
3963                socket: TestSocket::default(),
3964                close_sleep: tokio::time::sleep_until(close_deadline),
3965                ping_sleep: tokio::time::sleep_until(now + PING_TIMEOUT),
3966            }),
3967            channels: OwnedChannels::new(Channels::new(), DEFAULT_MAX_CHANNELS),
3968            closing: false,
3969            pool: BufPool::new(MAX_CAPACITY),
3970            outbound: VecDeque::new(),
3971            outbound_bytes: 0,
3972            max_in_flight: DEFAULT_MAX_IN_FLIGHT,
3973            max_outbound: DEFAULT_MAX_OUTBOUND,
3974            error: String::new(),
3975            error_payload: Vec::new(),
3976            error_typed: false,
3977            last_ping: None,
3978            rng: SmallRng::seed_from_u64(DEFAULT_SEED),
3979            out: VecDeque::new(),
3980            socket_send: false,
3981            socket_flush: false,
3982            socket_recv: true,
3983            set: JoinSet::new(),
3984            format: Format::DEFAULT,
3985            mode: Mode::DEFAULT,
3986            failure: None,
3987            formats: None,
3988            app: 0,
3989        }
3990    }
3991
3992    /// An elapsed close deadline must wind the connection down once, rather
3993    /// than being reported by [`Select`] over and over.
3994    ///
3995    /// A [`Sleep`] which has elapsed is `Ready` on every poll, so a close
3996    /// deadline which is left elapsed turns [`Server::run`] into a busy loop
3997    /// which queues an unbounded number of close frames and never returns.
3998    #[tokio::test]
3999    async fn close_deadline_winds_down_once() {
4000        let mut server = timed_out_server(Duration::from_secs(1));
4001
4002        server.run().await.unwrap();
4003
4004        assert_eq!(socket(&mut server).sent, [TestMessage::Close(CLOSE_NORMAL)]);
4005        assert!(server.out.is_empty());
4006        assert!(server.closing);
4007        // The close frame has to reach the wire, not just the sink's buffer.
4008        assert!(!server.socket_flush);
4009    }
4010
4011    /// The close deadline elapsing while the connection is already winding
4012    /// down must tear it down instead of queueing yet another close frame.
4013    #[tokio::test]
4014    async fn close_deadline_while_closing_gives_up() {
4015        let mut server = timed_out_server(Duration::from_secs(1));
4016
4017        // The state left behind by a close frame which the socket has not been
4018        // able to take yet, with the wind-down deadline elapsed on top of it.
4019        server.closing = true;
4020        server.out.push_back(TestMessage::Close(CLOSE_NORMAL));
4021
4022        server.run().await.unwrap();
4023
4024        assert!(socket(&mut server).sent.is_empty());
4025        assert_eq!(server.out.len(), 1);
4026    }
4027
4028    /// A peer which disconnects with a response still queued must not pin the
4029    /// connection task forever.
4030    ///
4031    /// A stream which has ended reports `Ready(None)` on every poll, which sits
4032    /// ahead of the send and flush arms in [`Select`] and used to mask them, so
4033    /// `outbound` could never drain and [`Server::run`] could never reach its
4034    /// break.
4035    ///
4036    /// Nothing here may lean on the close deadline: a loop which never yields
4037    /// is exactly the condition under which the runtime cannot deliver a timer,
4038    /// so the deadline is left a full [`CLOSE_TIMEOUT`] out and this test would
4039    /// hang rather than pass if the wind-down needed it.
4040    #[tokio::test]
4041    async fn ended_stream_drains_outbound() {
4042        let mut server = server_with(Instant::now() + CLOSE_TIMEOUT);
4043
4044        // The state a connection is left in when the peer goes away after its
4045        // request has been handled but before the response reached the socket.
4046        server.closing = true;
4047        server.socket_flush = true;
4048        server.outbound.push_back(response(&server));
4049        socket(&mut server).ended = true;
4050
4051        server.run().await.unwrap();
4052
4053        let sent = socket(&mut server).sent.as_slice();
4054        assert!(matches!(sent, [TestMessage::Binary(..)]));
4055        assert!(server.outbound.is_empty());
4056        assert!(!server.socket_flush);
4057        assert!(!server.socket_recv);
4058    }
4059
4060    /// A peer which is gone while the write side still has backpressure must
4061    /// wind down on the close deadline rather than spin.
4062    ///
4063    /// This is the case which separates fusing the stream from merely polling
4064    /// the send and flush arms ahead of it. Reordering the arms would rescue
4065    /// [`ended_stream_drains_outbound`], where the sink takes the write
4066    /// immediately, but not this: with the write side `Pending` there is no arm
4067    /// left to reach, so a stream which is still polled after it ended hands
4068    /// back `Ready(None)` forever and [`Server::run`] never yields.
4069    ///
4070    /// Fused, [`Select`] returns `Pending`, the task parks, and the deadline
4071    /// gets the chance to fire which the spin used to deny it. Leaning on it
4072    /// here is the point, so the deadline is short.
4073    #[tokio::test]
4074    async fn blocked_write_winds_down_on_deadline() {
4075        let mut server = server_with(Instant::now() + Duration::from_millis(50));
4076
4077        server.closing = true;
4078        server.socket_flush = true;
4079        server.outbound.push_back(response(&server));
4080
4081        {
4082            let socket = socket(&mut server);
4083            socket.ended = true;
4084            socket.write_blocked = true;
4085        }
4086
4087        server.run().await.unwrap();
4088
4089        // Nothing could be delivered, which is the honest outcome against a
4090        // socket which never took the write. Ending at all is what matters.
4091        assert!(socket(&mut server).sent.is_empty());
4092        assert_eq!(server.outbound.len(), 1);
4093        assert!(!server.socket_recv);
4094    }
4095
4096    /// A request as a peer would send it.
4097    fn request(mode: Mode, serial: u32) -> Message {
4098        let mut out = Vec::new();
4099
4100        let header = RequestHeader {
4101            version: VERSION,
4102            serial,
4103            id: 1,
4104            format: Format::DEFAULT.to_u8(),
4105            channel: ChannelId::NONE,
4106            app: 0,
4107        };
4108
4109        format::encode_envelope(mode, &mut out, &header).unwrap();
4110
4111        match mode {
4112            Mode::Binary => Message::Binary(Bytes::from(out)),
4113            Mode::Text => Message::Text(Bytes::from(out)),
4114        }
4115    }
4116
4117    /// A server with `count` requests waiting to be read.
4118    fn flooded_server(count: u32) -> Server<TestServerImpl, TestHandler, Channels> {
4119        let mut server = server_with(Instant::now() + CLOSE_TIMEOUT);
4120        let mode = server.mode;
4121
4122        socket(&mut server)
4123            .incoming
4124            .extend((1..=count).map(|serial| request(mode, serial)));
4125
4126        server
4127    }
4128
4129    /// Run the server until it has nothing left to do short of a deadline.
4130    async fn run_until_idle(server: &mut Server<TestServerImpl, TestHandler, Channels>) {
4131        let result = tokio::time::timeout(Duration::from_millis(100), server.run()).await;
4132        assert!(result.is_err(), "The connection should still be up");
4133    }
4134
4135    /// Requests which are never answered must stop the server from reading
4136    /// more of them, or a peer can make it spawn handlers without bound.
4137    #[tokio::test]
4138    async fn in_flight_handlers_stop_reading() {
4139        let mut server = flooded_server(10);
4140        server.handler = TestHandler { block: true };
4141        server.max_in_flight = 3;
4142
4143        run_until_idle(&mut server).await;
4144
4145        assert_eq!(server.set.len(), 3);
4146        assert_eq!(socket(&mut server).incoming.len(), 7);
4147    }
4148
4149    /// A peer which sends requests but never reads the responses must stop
4150    /// being read from once enough output is queued for it, or it grows the
4151    /// server's memory without bound.
4152    #[tokio::test]
4153    async fn queued_output_stops_reading() {
4154        let mut server = flooded_server(10);
4155        // NB: One request at a time, so that it is the queued output and not
4156        // the number of handlers which holds the rest back.
4157        server.max_in_flight = 1;
4158        server.max_outbound = 1;
4159        socket(&mut server).write_blocked = true;
4160
4161        run_until_idle(&mut server).await;
4162
4163        assert!(server.set.is_empty());
4164        assert_eq!(server.outbound.len(), 1);
4165        assert!(server.outbound_bytes > 0);
4166        assert_eq!(socket(&mut server).incoming.len(), 9);
4167        assert!(socket(&mut server).sent.is_empty());
4168    }
4169
4170    /// Reading resumes once the queued output has been written, so a peer
4171    /// which keeps up is never stalled by the limits.
4172    #[tokio::test]
4173    async fn reading_resumes_once_drained() {
4174        let mut server = flooded_server(10);
4175        server.max_in_flight = 1;
4176        server.max_outbound = 1;
4177
4178        run_until_idle(&mut server).await;
4179
4180        assert!(server.set.is_empty());
4181        assert!(server.outbound.is_empty());
4182        assert_eq!(server.outbound_bytes, 0);
4183        assert!(socket(&mut server).incoming.is_empty());
4184
4185        let sent = &socket(&mut server).sent;
4186        assert_eq!(sent.len(), 10);
4187
4188        assert!(
4189            sent.iter()
4190                .all(|m| matches!(m, TestMessage::Binary(..) | TestMessage::Text(..)))
4191        );
4192    }
4193
4194    /// The ids handed out by every clone of one pool are distinct while held,
4195    /// and a pool of its own is independent of the global one.
4196    #[test]
4197    fn channels_are_distinct_within_a_pool() {
4198        let pool = Channels::new();
4199        let other = pool.clone();
4200
4201        let ids = (0..64)
4202            .map(|n| if n % 2 == 0 { &pool } else { &other })
4203            .map(|pool| pool.next().unwrap())
4204            .collect::<BTreeSet<_>>();
4205
4206        assert_eq!(ids.len(), 64);
4207        assert!(!ids.contains(&ChannelId::NONE));
4208
4209        // NB: The global pool is shared with every test in the binary, so all
4210        // this can rely on is that its clones agree with one another.
4211        let a = Channels::global().next().unwrap();
4212        let b = Channels::global().next().unwrap();
4213        assert_ne!(a, b);
4214        Channels::global().free(a);
4215        Channels::global().free(b);
4216    }
4217
4218    /// A connection only frees the ids it holds, so one client cannot put the
4219    /// live channel of another back into the pool.
4220    #[test]
4221    fn owned_channels_only_close_their_own() {
4222        let pool = Channels::new();
4223        let mut first = OwnedChannels::new(pool.clone(), DEFAULT_MAX_CHANNELS);
4224        let mut second = OwnedChannels::new(pool.clone(), DEFAULT_MAX_CHANNELS);
4225
4226        let a = first.open().unwrap();
4227
4228        assert!(!second.close(a));
4229        assert!(!second.close(ChannelId::NONE));
4230        assert!(!second.close(ChannelId::from_u16(0x1234)));
4231        assert!(pool.lock().free.is_empty());
4232
4233        let b = second.open().unwrap();
4234        assert_ne!(a, b);
4235
4236        // Closing twice frees once.
4237        assert!(first.close(a));
4238        assert!(!first.close(a));
4239        assert_eq!(pool.lock().free.len(), 1);
4240    }
4241
4242    /// Dropping a connection returns every id it still holds, and nothing
4243    /// else.
4244    #[test]
4245    fn owned_channels_free_on_drop() {
4246        let pool = Channels::new();
4247        let mut first = OwnedChannels::new(pool.clone(), DEFAULT_MAX_CHANNELS);
4248        let mut second = OwnedChannels::new(pool.clone(), DEFAULT_MAX_CHANNELS);
4249
4250        let held = [first.open().unwrap(), first.open().unwrap()];
4251        let other = second.open().unwrap();
4252
4253        drop(first);
4254
4255        let freed = pool
4256            .lock()
4257            .free
4258            .iter()
4259            .map(|id| ChannelId::from_u16(id.get()))
4260            .collect::<BTreeSet<_>>();
4261
4262        assert_eq!(freed, BTreeSet::from(held));
4263
4264        // The ids are reused, but never the one the other connection holds.
4265        let reused = [second.open().unwrap(), second.open().unwrap()];
4266        assert_eq!(BTreeSet::from(reused), BTreeSet::from(held));
4267        assert!(!reused.contains(&other));
4268    }
4269
4270    /// A client which holds as many channels as it may is refused another
4271    /// until it closes one, which keeps one client from draining a pool
4272    /// shared with others.
4273    #[test]
4274    fn owned_channels_limit() {
4275        let mut channels = OwnedChannels::new(Channels::new(), 2);
4276
4277        let a = channels.open().unwrap();
4278        channels.open().unwrap();
4279        assert_eq!(channels.open(), Err(OpenChannelError::Limit(2)));
4280
4281        assert!(channels.close(a));
4282        channels.open().unwrap();
4283
4284        let mut none = OwnedChannels::new(Channels::new(), 0);
4285        assert_eq!(none.open(), Err(OpenChannelError::Limit(0)));
4286    }
4287
4288    /// An allocator which hands out no channel, or one already held, is
4289    /// refused, and neither id is freed on its behalf.
4290    #[test]
4291    fn owned_channels_refuse_a_broken_allocator() {
4292        #[derive(Default)]
4293        struct Broken {
4294            next: std::sync::Mutex<Vec<ChannelId>>,
4295            freed: std::sync::Mutex<Vec<ChannelId>>,
4296        }
4297
4298        impl ChannelAllocator for &Broken {
4299            fn next(&self) -> Option<ChannelId> {
4300                self.next.lock().unwrap().pop()
4301            }
4302
4303            fn free(&self, channel: ChannelId) {
4304                self.freed.lock().unwrap().push(channel);
4305            }
4306        }
4307
4308        let one = ChannelId::from_u16(1);
4309        let broken = Broken::default();
4310        broken
4311            .next
4312            .lock()
4313            .unwrap()
4314            .extend([one, ChannelId::NONE, one]);
4315
4316        let mut channels = OwnedChannels::new(&broken, DEFAULT_MAX_CHANNELS);
4317
4318        assert_eq!(channels.open(), Ok(one));
4319        assert_eq!(channels.open(), Err(OpenChannelError::Exhausted));
4320        assert_eq!(channels.open(), Err(OpenChannelError::Exhausted));
4321        assert_eq!(channels.open(), Err(OpenChannelError::Exhausted));
4322
4323        drop(channels);
4324        assert_eq!(*broken.freed.lock().unwrap(), [one]);
4325    }
4326}