Skip to main content

rama_ws/protocol/
error.rs

1use crate::protocol::{frame::coding::OpCodeData, message::Message};
2use rama_core::error::{BoxError, ErrorExt};
3use rama_net::conn::is_connection_error;
4use rama_utils::str::utf8;
5use std::{error, fmt, io};
6
7/// Indicates the specific type/cause of a protocol error.
8#[derive(Debug)]
9pub enum ProtocolError {
10    /// a utf-8 decode error
11    Utf8(BoxError),
12    /// Input-output error.
13    ///
14    /// These are generally errors with the
15    /// underlying connection and you should probably consider them fatal.
16    Io(io::Error),
17    /// Encountered an invalid opcode.
18    InvalidOpcode(u8),
19    /// The payload for the closing frame is invalid.
20    InvalidCloseSequence,
21    /// Received header is too long.
22    ///
23    /// Message is bigger than the maximum allowed size.
24    MessageTooLong {
25        /// The size of the message.
26        ///
27        /// For permessage-deflate messages rejected mid-inflation this is a
28        /// lower-bound sentinel (`max_size + 1`) rather than the exact decoded
29        /// length: inflation is aborted once the cap is exceeded, so the true
30        /// size is never computed.
31        size: usize,
32        /// The maximum allowed message size.
33        max_size: usize,
34    },
35    /// The server must close the connection when an unmasked frame is received.
36    UnmaskedFrameFromClient,
37    /// Message write buffer is full.
38    WriteBufferFull(Message),
39    /// Not allowed to send after having sent a closing frame.
40    SendAfterClosing,
41    /// Remote sent data after sending a closing frame.
42    ReceivedAfterClosing,
43    /// Reserved bits in frame header are non-zero.
44    NonZeroReservedBits,
45    /// The client must close the connection when a masked frame is received.
46    MaskedFrameFromServer,
47    /// Control frames must not be fragmented.
48    FragmentedControlFrame,
49    /// Control frames must have a payload of 125 bytes or less.
50    ControlFrameTooBig,
51    /// Type of control frame not recognised.
52    UnknownControlFrameType(u8),
53    /// Connection closed without performing the closing handshake.
54    ResetWithoutClosingHandshake,
55    /// Received a continue frame despite there being nothing to continue.
56    UnexpectedContinueFrame,
57    /// Received data while waiting for more fragments.
58    ExpectedFragment(OpCodeData),
59    /// Type of data frame not recognised.
60    UnknownDataFrameType(u8),
61    /// Error while applying the deflate extension
62    DeflateError(BoxError),
63}
64
65impl ProtocolError {
66    /// Check if the error is a connection error,
67    /// in which case the error can be ignored.
68    pub fn is_connection_error(&self) -> bool {
69        if let Self::Io(err) = self {
70            is_connection_error(err)
71        } else {
72            false
73        }
74    }
75}
76
77impl From<utf8::DecodeError<'_>> for ProtocolError {
78    fn from(value: utf8::DecodeError<'_>) -> Self {
79        Self::Utf8(BoxError::from(value.to_string()))
80    }
81}
82
83impl From<std::str::Utf8Error> for ProtocolError {
84    fn from(value: std::str::Utf8Error) -> Self {
85        Self::Utf8(value.into_box_error())
86    }
87}
88
89impl From<io::Error> for ProtocolError {
90    fn from(value: io::Error) -> Self {
91        Self::Io(value)
92    }
93}
94
95impl fmt::Display for ProtocolError {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        match self {
98            Self::Utf8(err) => write!(f, "UTF-8 error: {err:?}"),
99            Self::Io(err) => write!(f, "I/O error: {err:?}"),
100            Self::InvalidOpcode(code) => write!(f, "Encountered invalid opcode: {code}"),
101            Self::InvalidCloseSequence => write!(f, "Invalid close sequence"),
102            Self::MessageTooLong { size, max_size } => {
103                write!(f, "Message too long: {size} > {max_size}")
104            }
105            Self::UnmaskedFrameFromClient => {
106                write!(f, "Received an unmasked frame from client")
107            }
108            Self::WriteBufferFull(_) => write!(f, "Write buffer is full"),
109            Self::SendAfterClosing => {
110                write!(f, "Sending after closing is not allowed")
111            }
112            Self::ReceivedAfterClosing => {
113                write!(f, "Remote sent after having closed")
114            }
115            Self::NonZeroReservedBits => {
116                write!(f, "Reserved bits are non-zero")
117            }
118            Self::MaskedFrameFromServer => {
119                write!(f, "Received a masked frame from server")
120            }
121            Self::FragmentedControlFrame => {
122                write!(f, "Fragmented control frame")
123            }
124            Self::ControlFrameTooBig => {
125                write!(
126                    f,
127                    "Control frame too big (payload must be 125 bytes or less)"
128                )
129            }
130            Self::UnknownControlFrameType(t) => {
131                write!(f, "Unknown control frame type: {t}")
132            }
133            Self::ResetWithoutClosingHandshake => {
134                write!(f, "Connection reset without closing handshake")
135            }
136            Self::UnexpectedContinueFrame => {
137                write!(f, "Continue frame but nothing to continue")
138            }
139            Self::ExpectedFragment(data) => {
140                write!(f, "While waiting for more fragments received: {data}")
141            }
142            Self::UnknownDataFrameType(t) => {
143                write!(f, "Unknown data frame type: {t}")
144            }
145            Self::DeflateError(err) => write!(f, "Deflate error: {err:?}"),
146        }
147    }
148}
149
150impl error::Error for ProtocolError {
151    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
152        match self {
153            Self::Utf8(err) | Self::DeflateError(err) => Some(err.as_ref()),
154            Self::Io(err) => Some(err as &(dyn std::error::Error + 'static)),
155            Self::InvalidOpcode(_)
156            | Self::InvalidCloseSequence
157            | Self::MessageTooLong { .. }
158            | Self::UnmaskedFrameFromClient
159            | Self::WriteBufferFull(_)
160            | Self::SendAfterClosing
161            | Self::ReceivedAfterClosing
162            | Self::NonZeroReservedBits
163            | Self::MaskedFrameFromServer
164            | Self::FragmentedControlFrame
165            | Self::ControlFrameTooBig
166            | Self::UnknownControlFrameType(_)
167            | Self::ResetWithoutClosingHandshake
168            | Self::UnexpectedContinueFrame
169            | Self::ExpectedFragment(_)
170            | Self::UnknownDataFrameType(_) => None,
171        }
172    }
173}