rama_ws/protocol/
error.rs

1use crate::protocol::{frame::coding::OpCodeData, message::Message};
2use rama_core::error::OpaqueError;
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(OpaqueError),
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        size: usize,
27        /// The maximum allowed message size.
28        max_size: usize,
29    },
30    /// The server must close the connection when an unmasked frame is received.
31    UnmaskedFrameFromClient,
32    /// Message write buffer is full.
33    WriteBufferFull(Message),
34    /// Not allowed to send after having sent a closing frame.
35    SendAfterClosing,
36    /// Remote sent data after sending a closing frame.
37    ReceivedAfterClosing,
38    /// Reserved bits in frame header are non-zero.
39    NonZeroReservedBits,
40    /// The client must close the connection when a masked frame is received.
41    MaskedFrameFromServer,
42    /// Control frames must not be fragmented.
43    FragmentedControlFrame,
44    /// Control frames must have a payload of 125 bytes or less.
45    ControlFrameTooBig,
46    /// Type of control frame not recognised.
47    UnknownControlFrameType(u8),
48    /// Connection closed without performing the closing handshake.
49    ResetWithoutClosingHandshake,
50    /// Received a continue frame despite there being nothing to continue.
51    UnexpectedContinueFrame,
52    /// Received data while waiting for more fragments.
53    ExpectedFragment(OpCodeData),
54    /// Type of data frame not recognised.
55    UnknownDataFrameType(u8),
56    /// Error while applying the deflate extension
57    DeflateError(OpaqueError),
58}
59
60impl ProtocolError {
61    /// Check if the error is a connection error,
62    /// in which case the error can be ignored.
63    pub fn is_connection_error(&self) -> bool {
64        if let Self::Io(err) = self {
65            is_connection_error(err)
66        } else {
67            false
68        }
69    }
70}
71
72impl From<utf8::DecodeError<'_>> for ProtocolError {
73    fn from(value: utf8::DecodeError<'_>) -> Self {
74        Self::Utf8(OpaqueError::from_display(value.to_string()))
75    }
76}
77
78impl From<std::str::Utf8Error> for ProtocolError {
79    fn from(value: std::str::Utf8Error) -> Self {
80        Self::Utf8(OpaqueError::from_std(value))
81    }
82}
83
84impl From<io::Error> for ProtocolError {
85    fn from(value: io::Error) -> Self {
86        Self::Io(value)
87    }
88}
89
90impl fmt::Display for ProtocolError {
91    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92        match self {
93            Self::Utf8(err) => write!(f, "UTF-8 error: {err:?}"),
94            Self::Io(err) => write!(f, "I/O error: {err:?}"),
95            Self::InvalidOpcode(code) => write!(f, "Encountered invalid opcode: {code}"),
96            Self::InvalidCloseSequence => write!(f, "Invalid close sequence"),
97            Self::MessageTooLong { size, max_size } => {
98                write!(f, "Message too long: {size} > {max_size}")
99            }
100            Self::UnmaskedFrameFromClient => {
101                write!(f, "Received an unmasked frame from client")
102            }
103            Self::WriteBufferFull(_) => write!(f, "Write buffer is full"),
104            Self::SendAfterClosing => {
105                write!(f, "Sending after closing is not allowed")
106            }
107            Self::ReceivedAfterClosing => {
108                write!(f, "Remote sent after having closed")
109            }
110            Self::NonZeroReservedBits => {
111                write!(f, "Reserved bits are non-zero")
112            }
113            Self::MaskedFrameFromServer => {
114                write!(f, "Received a masked frame from server")
115            }
116            Self::FragmentedControlFrame => {
117                write!(f, "Fragmented control frame")
118            }
119            Self::ControlFrameTooBig => {
120                write!(
121                    f,
122                    "Control frame too big (payload must be 125 bytes or less)"
123                )
124            }
125            Self::UnknownControlFrameType(t) => {
126                write!(f, "Unknown control frame type: {t}")
127            }
128            Self::ResetWithoutClosingHandshake => {
129                write!(f, "Connection reset without closing handshake")
130            }
131            Self::UnexpectedContinueFrame => {
132                write!(f, "Continue frame but nothing to continue")
133            }
134            Self::ExpectedFragment(data) => {
135                write!(f, "While waiting for more fragments received: {data}")
136            }
137            Self::UnknownDataFrameType(t) => {
138                write!(f, "Unknown data frame type: {t}")
139            }
140            Self::DeflateError(err) => write!(f, "Deflate error: {err:?}"),
141        }
142    }
143}
144
145impl error::Error for ProtocolError {
146    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
147        match self {
148            Self::Utf8(err) => Some(err as &(dyn error::Error + 'static)),
149            Self::Io(err) => Some(err as &(dyn std::error::Error + 'static)),
150            Self::InvalidOpcode(_)
151            | Self::InvalidCloseSequence
152            | Self::MessageTooLong { .. }
153            | Self::UnmaskedFrameFromClient
154            | Self::WriteBufferFull(_)
155            | Self::SendAfterClosing
156            | Self::ReceivedAfterClosing
157            | Self::NonZeroReservedBits
158            | Self::MaskedFrameFromServer
159            | Self::FragmentedControlFrame
160            | Self::ControlFrameTooBig
161            | Self::UnknownControlFrameType(_)
162            | Self::ResetWithoutClosingHandshake
163            | Self::UnexpectedContinueFrame
164            | Self::ExpectedFragment(_)
165            | Self::UnknownDataFrameType(_) => None,
166            Self::DeflateError(err) => Some(err as &(dyn std::error::Error + 'static)),
167        }
168    }
169}