Skip to main content

tungstenite/protocol/
mod.rs

1//! Generic WebSocket message stream.
2
3pub mod frame;
4
5mod message;
6
7pub use self::{frame::CloseFrame, message::Message};
8
9use self::{
10    frame::{
11        coding::{CloseCode, Control as OpCtl, Data as OpData, OpCode},
12        Frame, FrameCodec,
13    },
14    message::{IncompleteMessage, MessageType},
15};
16use crate::{
17    error::{CapacityError, Error, ProtocolError, Result},
18    extensions::{compression::DecompressionError, Extensions, ExtensionsConfig},
19    protocol::frame::Utf8Bytes,
20};
21use log::*;
22use std::{
23    io::{self, Read, Write},
24    mem::replace,
25    usize,
26};
27
28/// Indicates a Client or Server role of the websocket
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub enum Role {
31    /// This socket is a server
32    Server,
33    /// This socket is a client
34    Client,
35}
36
37/// The configuration for WebSocket connection.
38///
39/// # Example
40/// ```
41/// # use tungstenite::protocol::WebSocketConfig;;
42/// let conf = WebSocketConfig::default()
43///     .read_buffer_size(256 * 1024)
44///     .write_buffer_size(256 * 1024);
45/// ```
46#[derive(Debug, Clone, Copy)]
47#[non_exhaustive]
48pub struct WebSocketConfig {
49    /// Read buffer capacity. This buffer is eagerly allocated and used for receiving
50    /// messages.
51    ///
52    /// For high read load scenarios a larger buffer, e.g. 128 KiB, improves performance.
53    ///
54    /// For scenarios where you expect a lot of connections and don't need high read load
55    /// performance a smaller buffer, e.g. 4 KiB, would be appropriate to lower total
56    /// memory usage.
57    ///
58    /// The default value is 128 KiB.
59    pub read_buffer_size: usize,
60    /// The target minimum size of the write buffer to reach before writing the data
61    /// to the underlying stream.
62    /// The default value is 128 KiB.
63    ///
64    /// If set to `0` each message will be eagerly written to the underlying stream.
65    /// It is often more optimal to allow them to buffer a little, hence the default value.
66    ///
67    /// Note: [`flush`](WebSocket::flush) will always fully write the buffer regardless.
68    pub write_buffer_size: usize,
69    /// The max size of the write buffer in bytes. Setting this can provide backpressure
70    /// in the case the write buffer is filling up due to write errors.
71    /// The default value is unlimited.
72    ///
73    /// Note: The write buffer only builds up past [`write_buffer_size`](Self::write_buffer_size)
74    /// when writes to the underlying stream are failing. So the **write buffer can not
75    /// fill up if you are not observing write errors even if not flushing**.
76    ///
77    /// Note: Should always be at least [`write_buffer_size + 1 message`](Self::write_buffer_size)
78    /// and probably a little more depending on error handling strategy.
79    pub max_write_buffer_size: usize,
80    /// The maximum size of an incoming message. `None` means no size limit. The default value is 64 MiB
81    /// which should be reasonably big for all normal use-cases but small enough to prevent
82    /// memory eating by a malicious user.
83    pub max_message_size: Option<usize>,
84    /// The maximum size of a single incoming message frame. `None` means no size limit. The limit is for
85    /// frame payload NOT including the frame header. The default value is 16 MiB which should
86    /// be reasonably big for all normal use-cases but small enough to prevent memory eating
87    /// by a malicious user.
88    pub max_frame_size: Option<usize>,
89    /// When set to `true`, the server will accept and handle unmasked frames
90    /// from the client. According to the RFC 6455, the server must close the
91    /// connection to the client in such cases, however it seems like there are
92    /// some popular libraries that are sending unmasked frames, ignoring the RFC.
93    /// By default this option is set to `false`, i.e. according to RFC 6455.
94    pub accept_unmasked_frames: bool,
95    /// Configuration for optional extensions to the base websocket protocol.
96    ///
97    /// Some extensions may require optional features to be enabled at build
98    /// time to be supported.
99    pub extensions: ExtensionsConfig,
100}
101
102impl Default for WebSocketConfig {
103    fn default() -> Self {
104        Self {
105            read_buffer_size: 128 * 1024,
106            write_buffer_size: 128 * 1024,
107            max_write_buffer_size: usize::MAX,
108            max_message_size: Some(64 << 20),
109            max_frame_size: Some(16 << 20),
110            accept_unmasked_frames: false,
111            extensions: ExtensionsConfig::default(),
112        }
113    }
114}
115
116impl WebSocketConfig {
117    /// Set [`Self::read_buffer_size`].
118    pub fn read_buffer_size(mut self, read_buffer_size: usize) -> Self {
119        self.read_buffer_size = read_buffer_size;
120        self
121    }
122
123    /// Set [`Self::write_buffer_size`].
124    pub fn write_buffer_size(mut self, write_buffer_size: usize) -> Self {
125        self.write_buffer_size = write_buffer_size;
126        self
127    }
128
129    /// Set [`Self::max_write_buffer_size`].
130    pub fn max_write_buffer_size(mut self, max_write_buffer_size: usize) -> Self {
131        self.max_write_buffer_size = max_write_buffer_size;
132        self
133    }
134
135    /// Set [`Self::max_message_size`].
136    pub fn max_message_size(mut self, max_message_size: Option<usize>) -> Self {
137        self.max_message_size = max_message_size;
138        self
139    }
140
141    /// Set [`Self::max_frame_size`].
142    pub fn max_frame_size(mut self, max_frame_size: Option<usize>) -> Self {
143        self.max_frame_size = max_frame_size;
144        self
145    }
146
147    /// Set [`Self::accept_unmasked_frames`].
148    pub fn accept_unmasked_frames(mut self, accept_unmasked_frames: bool) -> Self {
149        self.accept_unmasked_frames = accept_unmasked_frames;
150        self
151    }
152
153    /// Panic if values are invalid.
154    pub(crate) fn assert_valid(&self) {
155        assert!(
156            self.max_write_buffer_size > self.write_buffer_size,
157            "WebSocketConfig::max_write_buffer_size must be greater than write_buffer_size, \
158            see WebSocketConfig docs`"
159        );
160    }
161}
162
163/// WebSocket input-output stream.
164///
165/// This is THE structure you want to create to be able to speak the WebSocket protocol.
166/// It may be created by calling `connect`, `accept` or `client` functions.
167///
168/// Use [`WebSocket::read`], [`WebSocket::send`] to received and send messages.
169#[derive(Debug)]
170pub struct WebSocket<Stream> {
171    /// The underlying socket.
172    socket: Stream,
173    /// The context for managing a WebSocket.
174    context: WebSocketContext,
175}
176
177impl<Stream> WebSocket<Stream> {
178    /// Convert a raw socket into a WebSocket without performing a handshake.
179    ///
180    /// Call this function if you're using Tungstenite as a part of a web framework
181    /// or together with an existing one. If you need an initial handshake, use
182    /// `connect()` or `accept()` functions of the crate to construct a websocket.
183    ///
184    /// # Panics
185    /// Panics if config is invalid e.g. `max_write_buffer_size <= write_buffer_size`.
186    pub fn from_raw_socket(stream: Stream, role: Role, config: Option<WebSocketConfig>) -> Self {
187        WebSocket { socket: stream, context: WebSocketContext::new(role, config) }
188    }
189
190    /// Convert a raw socket into a WebSocket without performing a handshake.
191    pub fn from_raw_socket_with_extensions(
192        stream: Stream,
193        role: Role,
194        config: Option<WebSocketConfig>,
195        extensions: Extensions,
196    ) -> Self {
197        let mut context = WebSocketContext::new(role, config);
198        context.extensions = extensions;
199        WebSocket { socket: stream, context }
200    }
201
202    /// Convert a raw socket into a WebSocket without performing a handshake.
203    ///
204    /// Call this function if you're using Tungstenite as a part of a web framework
205    /// or together with an existing one. If you need an initial handshake, use
206    /// `connect()` or `accept()` functions of the crate to construct a websocket.
207    ///
208    /// # Panics
209    /// Panics if config is invalid e.g. `max_write_buffer_size <= write_buffer_size`.
210    pub fn from_partially_read(
211        stream: Stream,
212        part: Vec<u8>,
213        role: Role,
214        config: Option<WebSocketConfig>,
215    ) -> Self {
216        Self::from_partially_read_with_extensions(stream, part, role, config, Extensions::default())
217    }
218
219    pub(crate) fn from_partially_read_with_extensions(
220        stream: Stream,
221        part: Vec<u8>,
222        role: Role,
223        config: Option<WebSocketConfig>,
224        extensions: Extensions,
225    ) -> Self {
226        WebSocket {
227            socket: stream,
228            context: WebSocketContext::from_partially_read_with_extensions(
229                part, role, config, extensions,
230            ),
231        }
232    }
233
234    /// Consumes the `WebSocket` and returns the underlying stream.
235    pub fn into_inner(self) -> Stream {
236        self.socket
237    }
238
239    /// Returns a shared reference to the inner stream.
240    pub fn get_ref(&self) -> &Stream {
241        &self.socket
242    }
243    /// Returns a mutable reference to the inner stream.
244    pub fn get_mut(&mut self) -> &mut Stream {
245        &mut self.socket
246    }
247
248    /// Change the configuration.
249    ///
250    /// # Panics
251    /// Panics if config is invalid e.g. `max_write_buffer_size <= write_buffer_size`.
252    pub fn set_config(&mut self, set_func: impl FnOnce(&mut WebSocketConfig)) {
253        self.context.set_config(set_func);
254    }
255
256    /// Read the configuration.
257    pub fn get_config(&self) -> &WebSocketConfig {
258        self.context.get_config()
259    }
260
261    /// Check if it is possible to read messages.
262    ///
263    /// Reading is impossible after receiving `Message::Close`. It is still possible after
264    /// sending close frame since the peer still may send some data before confirming close.
265    pub fn can_read(&self) -> bool {
266        self.context.can_read()
267    }
268
269    /// Check if it is possible to write messages.
270    ///
271    /// Writing gets impossible immediately after sending or receiving `Message::Close`.
272    pub fn can_write(&self) -> bool {
273        self.context.can_write()
274    }
275}
276
277impl<Stream: Read + Write> WebSocket<Stream> {
278    /// Read a message from stream, if possible.
279    ///
280    /// This will also queue responses to ping and close messages. These responses
281    /// will be written and flushed on the next call to [`read`](Self::read),
282    /// [`write`](Self::write) or [`flush`](Self::flush).
283    ///
284    /// # Closing the connection
285    /// When the remote endpoint decides to close the connection this will return
286    /// the close message with an optional close frame.
287    ///
288    /// You should continue calling [`read`](Self::read), [`write`](Self::write) or
289    /// [`flush`](Self::flush) to drive the reply to the close frame until [`Error::ConnectionClosed`]
290    /// is returned. Once that happens it is safe to drop the underlying connection.
291    pub fn read(&mut self) -> Result<Message> {
292        self.context.read(&mut self.socket)
293    }
294
295    /// Writes and immediately flushes a message.
296    /// Equivalent to calling [`write`](Self::write) then [`flush`](Self::flush).
297    pub fn send(&mut self, message: Message) -> Result<()> {
298        self.write(message)?;
299        self.flush()
300    }
301
302    /// Write a message to the provided stream, if possible.
303    ///
304    /// A subsequent call should be made to [`flush`](Self::flush) to flush writes.
305    ///
306    /// In the event of stream write failure the message frame will be stored
307    /// in the write buffer and will try again on the next call to [`write`](Self::write)
308    /// or [`flush`](Self::flush).
309    ///
310    /// If the write buffer would exceed the configured [`WebSocketConfig::max_write_buffer_size`]
311    /// [`Err(WriteBufferFull(msg_frame))`](Error::WriteBufferFull) is returned.
312    ///
313    /// This call will generally not flush. However, if there are queued automatic messages
314    /// they will be written and eagerly flushed.
315    ///
316    /// For example, upon receiving ping messages tungstenite queues pong replies automatically.
317    /// The next call to [`read`](Self::read), [`write`](Self::write) or [`flush`](Self::flush)
318    /// will write & flush the pong reply. This means you should not respond to ping frames manually.
319    ///
320    /// You can however send pong frames manually in order to indicate a unidirectional heartbeat
321    /// as described in [RFC 6455](https://tools.ietf.org/html/rfc6455#section-5.5.3). Note that
322    /// if [`read`](Self::read) returns a ping, you should [`flush`](Self::flush) before passing
323    /// a custom pong to [`write`](Self::write), otherwise the automatic queued response to the
324    /// ping will not be sent as it will be replaced by your custom pong message.
325    ///
326    /// # Errors
327    /// - If the WebSocket's write buffer is full, [`Error::WriteBufferFull`] will be returned
328    ///   along with the equivalent passed message frame.
329    /// - If the connection is closed and should be dropped, this will return [`Error::ConnectionClosed`].
330    /// - If you try again after [`Error::ConnectionClosed`] was returned either from here or from
331    ///   [`read`](Self::read), [`Error::AlreadyClosed`] will be returned. This indicates a program
332    ///   error on your part.
333    /// - [`Error::Io`] is returned if the underlying connection returns an error
334    ///   (consider these fatal except for WouldBlock).
335    /// - [`Error::Capacity`] if your message size is bigger than the configured max message size.
336    pub fn write(&mut self, message: Message) -> Result<()> {
337        self.context.write(&mut self.socket, message)
338    }
339
340    /// Flush writes.
341    ///
342    /// Ensures all messages previously passed to [`write`](Self::write) and automatic
343    /// queued pong responses are written & flushed into the underlying stream.
344    pub fn flush(&mut self) -> Result<()> {
345        self.context.flush(&mut self.socket)
346    }
347
348    /// Close the connection.
349    ///
350    /// This function guarantees that the close frame will be queued.
351    /// There is no need to call it again. Calling this function is
352    /// the same as calling `write(Message::Close(..))`.
353    ///
354    /// After queuing the close frame you should continue calling [`read`](Self::read) or
355    /// [`flush`](Self::flush) to drive the close handshake to completion.
356    ///
357    /// The websocket RFC defines that the underlying connection should be closed
358    /// by the server. Tungstenite takes care of this asymmetry for you.
359    ///
360    /// When the close handshake is finished (we have both sent and received
361    /// a close message), [`read`](Self::read) or [`flush`](Self::flush) will return
362    /// [Error::ConnectionClosed] if this endpoint is the server.
363    ///
364    /// If this endpoint is a client, [Error::ConnectionClosed] will only be
365    /// returned after the server has closed the underlying connection.
366    ///
367    /// It is thus safe to drop the underlying connection as soon as [Error::ConnectionClosed]
368    /// is returned from [`read`](Self::read) or [`flush`](Self::flush).
369    pub fn close(&mut self, code: Option<CloseFrame>) -> Result<()> {
370        self.context.close(&mut self.socket, code)
371    }
372
373    /// Old name for [`read`](Self::read).
374    #[deprecated(note = "Use `read`")]
375    pub fn read_message(&mut self) -> Result<Message> {
376        self.read()
377    }
378
379    /// Old name for [`send`](Self::send).
380    #[deprecated(note = "Use `send`")]
381    pub fn write_message(&mut self, message: Message) -> Result<()> {
382        self.send(message)
383    }
384
385    /// Old name for [`flush`](Self::flush).
386    #[deprecated(note = "Use `flush`")]
387    pub fn write_pending(&mut self) -> Result<()> {
388        self.flush()
389    }
390}
391
392/// A context for managing WebSocket stream.
393#[derive(Debug)]
394pub struct WebSocketContext {
395    /// Server or client?
396    role: Role,
397    /// encoder/decoder of frame.
398    frame: FrameCodec,
399    /// The state of processing, either "active" or "closing".
400    state: WebSocketState,
401    /// Receive: an incomplete message being processed.
402    incomplete: Option<IncompleteMessage>,
403    /// Send in addition to regular messages E.g. "pong" or "close".
404    additional_send: Option<Frame>,
405    /// True indicates there is an additional message (like a pong)
406    /// that failed to flush previously and we should try again.
407    unflushed_additional: bool,
408    /// The configuration for the websocket session.
409    config: WebSocketConfig,
410    // Container for extensions.
411    extensions: Extensions,
412}
413
414impl WebSocketContext {
415    /// Create a WebSocket context that manages a post-handshake stream.
416    ///
417    /// # Panics
418    /// Panics if config is invalid e.g. `max_write_buffer_size <= write_buffer_size`.
419    pub fn new(role: Role, config: Option<WebSocketConfig>) -> Self {
420        let conf = config.unwrap_or_default();
421        Self::_new(
422            role,
423            FrameCodec::new(conf.read_buffer_size),
424            conf,
425            conf.extensions.into_unnegotiated_context(role),
426        )
427    }
428
429    /// Create a WebSocket context that manages an post-handshake stream.
430    ///
431    /// # Panics
432    /// Panics if config is invalid e.g. `max_write_buffer_size <= write_buffer_size`.
433    pub fn from_partially_read(part: Vec<u8>, role: Role, config: Option<WebSocketConfig>) -> Self {
434        let conf = config.unwrap_or_default();
435        let extensions = conf.extensions.into_unnegotiated_context(role);
436        Self::_new(
437            role,
438            FrameCodec::from_partially_read(part, conf.read_buffer_size),
439            conf,
440            extensions,
441        )
442    }
443
444    /// Create a WebSocket context for a post-handshake stream with the enabled extensions.
445    ///
446    /// Where [`WebSocketContext::from_partially_read`] infers the enabled
447    /// extensions from the [`WebSocketConfig`], this allows the caller to
448    /// explicitly sets the extensions in use for the connection.
449    pub(crate) fn from_partially_read_with_extensions(
450        part: Vec<u8>,
451        role: Role,
452        config: Option<WebSocketConfig>,
453        extensions: Extensions,
454    ) -> Self {
455        let conf = config.unwrap_or_default();
456        Self::_new(
457            role,
458            FrameCodec::from_partially_read(part, conf.read_buffer_size),
459            conf,
460            extensions,
461        )
462    }
463
464    fn _new(
465        role: Role,
466        mut frame: FrameCodec,
467        config: WebSocketConfig,
468        extensions: Extensions,
469    ) -> Self {
470        config.assert_valid();
471        frame.set_max_out_buffer_len(config.max_write_buffer_size);
472        frame.set_out_buffer_write_len(config.write_buffer_size);
473        Self {
474            role,
475            frame,
476            state: WebSocketState::Active,
477            incomplete: None,
478            additional_send: None,
479            unflushed_additional: false,
480            config,
481            extensions,
482        }
483    }
484
485    /// Change the configuration.
486    ///
487    /// # Panics
488    /// Panics if config is invalid e.g. `max_write_buffer_size <= write_buffer_size`.
489    pub fn set_config(&mut self, set_func: impl FnOnce(&mut WebSocketConfig)) {
490        set_func(&mut self.config);
491        self.config.assert_valid();
492        self.frame.set_max_out_buffer_len(self.config.max_write_buffer_size);
493        self.frame.set_out_buffer_write_len(self.config.write_buffer_size);
494    }
495
496    /// Read the configuration.
497    pub fn get_config(&self) -> &WebSocketConfig {
498        &self.config
499    }
500
501    /// Check if it is possible to read messages.
502    ///
503    /// Reading is impossible after receiving `Message::Close`. It is still possible after
504    /// sending close frame since the peer still may send some data before confirming close.
505    pub fn can_read(&self) -> bool {
506        self.state.can_read()
507    }
508
509    /// Check if it is possible to write messages.
510    ///
511    /// Writing gets impossible immediately after sending or receiving `Message::Close`.
512    pub fn can_write(&self) -> bool {
513        self.state.is_active()
514    }
515
516    /// Read a message from the provided stream, if possible.
517    ///
518    /// This function sends pong and close responses automatically.
519    /// However, it never blocks on write.
520    pub fn read<Stream>(&mut self, stream: &mut Stream) -> Result<Message>
521    where
522        Stream: Read + Write,
523    {
524        // Do not read from already closed connections.
525        self.state.check_not_terminated()?;
526
527        loop {
528            if self.additional_send.is_some() || self.unflushed_additional {
529                // Since we may get ping or close, we need to reply to the messages even during read.
530                match self.flush(stream) {
531                    Ok(_) => {}
532                    Err(Error::Io(err)) if err.kind() == io::ErrorKind::WouldBlock => {
533                        // If blocked continue reading, but try again later
534                        self.unflushed_additional = true;
535                    }
536                    Err(err) => return Err(err),
537                }
538            } else if self.role == Role::Server && !self.state.can_read() {
539                self.state = WebSocketState::Terminated;
540                return Err(Error::ConnectionClosed);
541            }
542
543            // If we get here, either write blocks or we have nothing to write.
544            // Thus if read blocks, just let it return WouldBlock.
545            if let Some(message) = self.read_message_frame(stream)? {
546                trace!("Received message {message}");
547                return Ok(message);
548            }
549        }
550    }
551
552    /// Write a message to the provided stream.
553    ///
554    /// A subsequent call should be made to [`flush`](Self::flush) to flush writes.
555    ///
556    /// In the event of stream write failure the message frame will be stored
557    /// in the write buffer and will try again on the next call to [`write`](Self::write)
558    /// or [`flush`](Self::flush).
559    ///
560    /// If the write buffer would exceed the configured [`WebSocketConfig::max_write_buffer_size`]
561    /// [`Err(WriteBufferFull(msg_frame))`](Error::WriteBufferFull) is returned.
562    pub fn write<Stream>(&mut self, stream: &mut Stream, message: Message) -> Result<()>
563    where
564        Stream: Read + Write,
565    {
566        // When terminated, return AlreadyClosed.
567        self.state.check_not_terminated()?;
568
569        // Do not write after sending a close frame.
570        if !self.state.is_active() {
571            return Err(Error::Protocol(ProtocolError::SendAfterClosing));
572        }
573
574        let mut prepare_data_frame = |data, opdata| -> Result<Frame, ProtocolError> {
575            const IS_FINAL: bool = true;
576            if let Some(compressor) = self.extensions.per_message_compressor() {
577                let compressed = compressor(&data)?;
578                return Ok(Frame::compressed_message(compressed, opdata, IS_FINAL));
579            }
580            Ok(Frame::message(data, OpCode::Data(opdata), IS_FINAL))
581        };
582
583        let frame = match message {
584            Message::Text(data) => prepare_data_frame(data.into(), OpData::Text)?,
585            Message::Binary(data) => prepare_data_frame(data, OpData::Binary)?,
586            Message::Ping(data) => Frame::ping(data),
587            Message::Pong(data) => {
588                self.set_additional(Frame::pong(data));
589                // Note: user pongs can be user flushed so no need to flush here
590                return self._write(stream, None).map(|_| ());
591            }
592            Message::Close(code) => return self.close(stream, code),
593            Message::Frame(f) => f,
594        };
595
596        let should_flush = self._write(stream, Some(frame))?;
597        if should_flush {
598            self.flush(stream)?;
599        }
600        Ok(())
601    }
602
603    /// Flush writes.
604    ///
605    /// Ensures all messages previously passed to [`write`](Self::write) and automatically
606    /// queued pong responses are written & flushed into the `stream`.
607    #[inline]
608    pub fn flush<Stream>(&mut self, stream: &mut Stream) -> Result<()>
609    where
610        Stream: Read + Write,
611    {
612        self._write(stream, None)?;
613        self.frame.write_out_buffer(stream)?;
614        stream.flush()?;
615        self.unflushed_additional = false;
616        Ok(())
617    }
618
619    /// Writes any data in the out_buffer, `additional_send` and given `data`.
620    ///
621    /// Does **not** flush.
622    ///
623    /// Returns true if the write contents indicate we should flush immediately.
624    fn _write<Stream>(&mut self, stream: &mut Stream, data: Option<Frame>) -> Result<bool>
625    where
626        Stream: Read + Write,
627    {
628        if let Some(data) = data {
629            self.buffer_frame(stream, data)?;
630        }
631
632        // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in
633        // response, unless it already received a Close frame. It SHOULD
634        // respond with Pong frame as soon as is practical. (RFC 6455)
635        let should_flush = if let Some(msg) = self.additional_send.take() {
636            trace!("Sending pong/close");
637            match self.buffer_frame(stream, msg) {
638                Err(Error::WriteBufferFull(msg)) => {
639                    // if an system message would exceed the buffer put it back in
640                    // `additional_send` for retry. Otherwise returning this error
641                    // may not make sense to the user, e.g. calling `flush`.
642                    if let Message::Frame(msg) = *msg {
643                        self.set_additional(msg);
644                        false
645                    } else {
646                        unreachable!()
647                    }
648                }
649                Err(err) => return Err(err),
650                Ok(_) => true,
651            }
652        } else {
653            self.unflushed_additional
654        };
655
656        // If we're closing and there is nothing to send anymore, we should close the connection.
657        if self.role == Role::Server && !self.state.can_read() {
658            // The underlying TCP connection, in most normal cases, SHOULD be closed
659            // first by the server, so that it holds the TIME_WAIT state and not the
660            // client (as this would prevent it from re-opening the connection for 2
661            // maximum segment lifetimes (2MSL), while there is no corresponding
662            // server impact as a TIME_WAIT connection is immediately reopened upon
663            // a new SYN with a higher seq number). (RFC 6455)
664            self.frame.write_out_buffer(stream)?;
665            self.state = WebSocketState::Terminated;
666            Err(Error::ConnectionClosed)
667        } else {
668            Ok(should_flush)
669        }
670    }
671
672    /// Close the connection.
673    ///
674    /// This function guarantees that the close frame will be queued.
675    /// There is no need to call it again. Calling this function is
676    /// the same as calling `send(Message::Close(..))`.
677    pub fn close<Stream>(&mut self, stream: &mut Stream, code: Option<CloseFrame>) -> Result<()>
678    where
679        Stream: Read + Write,
680    {
681        if let WebSocketState::Active = self.state {
682            self.state = WebSocketState::ClosedByUs;
683            let frame = Frame::close(code);
684            self._write(stream, Some(frame))?;
685        }
686        self.flush(stream)
687    }
688
689    /// Try to decode one message frame. May return None.
690    fn read_message_frame(&mut self, stream: &mut impl Read) -> Result<Option<Message>> {
691        let frame = match self
692            .frame
693            .read_frame(
694                stream,
695                self.config.max_frame_size,
696                matches!(self.role, Role::Server),
697                self.config.accept_unmasked_frames,
698            )
699            .check_connection_reset(self.state)?
700        {
701            None => {
702                // Connection closed by peer
703                return match replace(&mut self.state, WebSocketState::Terminated) {
704                    WebSocketState::ClosedByPeer | WebSocketState::CloseAcknowledged => {
705                        Err(Error::ConnectionClosed)
706                    }
707                    _ => Err(Error::Protocol(ProtocolError::ResetWithoutClosingHandshake)),
708                };
709            }
710            Some(frame) => frame,
711        };
712
713        if !self.state.can_read() {
714            return Err(Error::Protocol(ProtocolError::ReceivedAfterClosing));
715        }
716
717        let (is_compressed, decompressor) = {
718            let decompressor = self.extensions.per_message_decompressor();
719            let hdr = frame.header();
720            // Per RFC 6455, the RSV1, RSV2, and RSV3 bits
721            //
722            //   MUST be 0 unless an extension is negotiated that defines
723            //   meanings for non-zero values.  If a nonzero value is
724            //   received and none of the negotiated extensions defines the
725            //   meaning of such a nonzero value, the receiving endpoint
726            //   MUST _Fail the WebSocket Connection_.
727            //
728            // Per RFC 7692:
729            //
730            //   This document allocates the RSV1 bit of the WebSocket
731            //   header for PMCEs and calls the bit the "Per-Message
732            //   Compressed" bit.  On a WebSocket connection where a PMCE is
733            //   in use, this bit indicates whether a message is compressed
734            //   or not.
735            if (hdr.rsv1 && decompressor.is_none()) || hdr.rsv2 || hdr.rsv3 {
736                return Err(Error::Protocol(ProtocolError::NonZeroReservedBits));
737            }
738
739            let decompressor_with_size_limit = decompressor.map(|mut f| {
740                let incomplete_len =
741                    self.incomplete.as_ref().map(IncompleteMessage::len).unwrap_or(0);
742                let message_max = self.config.max_message_size.unwrap_or(usize::MAX);
743
744                move |bytes, is_final| {
745                    let decompress_limit = message_max.saturating_sub(incomplete_len);
746
747                    f(bytes, is_final, decompress_limit).map_err(|e| match e {
748                        DecompressionError::SizeLimitReached => {
749                            Error::Capacity(CapacityError::MessageTooLong {
750                                size: incomplete_len.saturating_add(decompress_limit),
751                                max_size: message_max,
752                            })
753                        }
754                        DecompressionError::Decompression(e) => {
755                            Error::Protocol(ProtocolError::CompressionFailure(e))
756                        }
757                    })
758                }
759            });
760
761            (hdr.rsv1, decompressor_with_size_limit)
762        };
763
764        if self.role == Role::Client && frame.is_masked() {
765            // A client MUST close a connection if it detects a masked frame. (RFC 6455)
766            return Err(Error::Protocol(ProtocolError::MaskedFrameFromServer));
767        }
768
769        match frame.header().opcode {
770            OpCode::Control(ctl) => {
771                drop(decompressor);
772                match ctl {
773                    // All control frames MUST have a payload length of 125 bytes or less
774                    // and MUST NOT be fragmented. (RFC 6455)
775                    _ if !frame.header().is_final => {
776                        Err(Error::Protocol(ProtocolError::FragmentedControlFrame))
777                    }
778                    _ if frame.payload().len() > 125 => {
779                        Err(Error::Protocol(ProtocolError::ControlFrameTooBig))
780                    }
781                    // Per RFC 7692:
782                    //
783                    //   An endpoint MUST NOT set the "Per-Message
784                    //   Compressed" bit of control frames and non-first
785                    //   fragments of a data message.  An endpoint receiving
786                    //   such a frame MUST _Fail the WebSocket Connection_.
787                    _ if is_compressed => {
788                        Err(Error::Protocol(ProtocolError::CompressedControlFrame))
789                    }
790                    OpCtl::Close => Ok(self.do_close(frame.into_close()?).map(Message::Close)),
791                    OpCtl::Reserved(i) => {
792                        Err(Error::Protocol(ProtocolError::UnknownControlFrameType(i)))
793                    }
794                    OpCtl::Ping => {
795                        let data = frame.into_payload();
796                        // No ping processing after we sent a close frame.
797                        if self.state.is_active() {
798                            self.set_additional(Frame::pong(data.clone()));
799                        }
800                        Ok(Some(Message::Ping(data)))
801                    }
802                    OpCtl::Pong => Ok(Some(Message::Pong(frame.into_payload()))),
803                }
804            }
805
806            OpCode::Data(data) => {
807                let fin = frame.header().is_final;
808                let payload = frame.into_payload();
809
810                let decompressor = match data {
811                    OpData::Continue => {
812                        // Per RFC 7692:
813                        //
814                        //   An endpoint MUST NOT set the "Per-Message
815                        //   Compressed" bit of control frames and non-first
816                        //   fragments of a data message.  An endpoint receiving
817                        //   such a frame MUST _Fail the WebSocket Connection_.
818                        if is_compressed {
819                            return Err(Error::Protocol(ProtocolError::CompressedContinueFrame));
820                        }
821
822                        let incomplete_compressed =
823                            self.incomplete.as_ref().map_or(false, IncompleteMessage::compressed);
824                        match (incomplete_compressed, &decompressor) {
825                            (false, _) => None,
826                            (true, Some(_)) => decompressor,
827                            (true, None) => {
828                                // This is a continuation frame that was
829                                // received with compression disabled, but the
830                                // initial frame of the message was received
831                                // with compression *enabled* and RSV1 set.
832                                //
833                                // The only way to get here is to manually
834                                // disable compression for a stream after it's
835                                // been established, which is arguably operator
836                                // error.  This is incorrect enough that it's
837                                // not worth spending a lot of code on, but it's
838                                // better to return an error here than crash.
839                                log::debug!("compression was disabled between receiving frames");
840                                return Err(Error::Protocol(
841                                    ProtocolError::CompressedContinueFrame,
842                                ));
843                            }
844                        }
845                    }
846                    OpData::Text | OpData::Binary => decompressor.filter(|_| is_compressed),
847                    OpData::Reserved(_) => None,
848                };
849                let payload = decompressor
850                    .map(|mut decompressor| decompressor(&payload, fin))
851                    .transpose()?
852                    .unwrap_or(payload);
853
854                let payload = match (data, self.incomplete.as_mut()) {
855                    (OpData::Continue, None) => Err(ProtocolError::UnexpectedContinueFrame),
856                    (OpData::Continue, Some(incomplete)) => {
857                        incomplete.extend(payload, self.config.max_message_size)?;
858                        Ok(None)
859                    }
860                    (_, Some(_)) => Err(ProtocolError::ExpectedFragment(data)),
861                    (OpData::Text, _) => Ok(Some((payload, MessageType::Text))),
862                    (OpData::Binary, _) => Ok(Some((payload, MessageType::Binary))),
863                    (OpData::Reserved(i), _) => Err(ProtocolError::UnknownDataFrameType(i)),
864                }?;
865
866                match (payload, fin) {
867                    (None, true) => Ok(Some(self.incomplete.take().unwrap().complete()?)),
868                    (None, false) => Ok(None),
869                    (Some((payload, t)), true) => {
870                        check_max_size(payload.len(), self.config.max_message_size)?;
871                        match t {
872                            MessageType::Text => Ok(Some(Message::Text(payload.try_into()?))),
873                            MessageType::Binary => Ok(Some(Message::Binary(payload))),
874                        }
875                    }
876                    (Some((payload, t)), false) => {
877                        let mut incomplete = match is_compressed {
878                            #[cfg(feature = "deflate")]
879                            true => IncompleteMessage::new_compressed(t),
880                            _ => IncompleteMessage::new(t),
881                        };
882                        incomplete.extend(payload, self.config.max_message_size)?;
883                        self.incomplete = Some(incomplete);
884                        Ok(None)
885                    }
886                }
887            }
888        } // match opcode
889    }
890
891    /// Received a close frame. Tells if we need to return a close frame to the user.
892    #[allow(clippy::option_option)]
893    fn do_close(&mut self, close: Option<CloseFrame>) -> Option<Option<CloseFrame>> {
894        debug!("Received close frame: {close:?}");
895        match self.state {
896            WebSocketState::Active => {
897                self.state = WebSocketState::ClosedByPeer;
898
899                let close = close.map(|frame| {
900                    if !frame.code.is_allowed() {
901                        CloseFrame {
902                            code: CloseCode::Protocol,
903                            reason: Utf8Bytes::from_static("Protocol violation"),
904                        }
905                    } else {
906                        frame
907                    }
908                });
909
910                let reply = Frame::close(close.clone());
911                debug!("Replying to close with {reply:?}");
912                self.set_additional(reply);
913
914                Some(close)
915            }
916            WebSocketState::ClosedByPeer | WebSocketState::CloseAcknowledged => {
917                // It is already closed, just ignore.
918                None
919            }
920            WebSocketState::ClosedByUs => {
921                // We received a reply.
922                self.state = WebSocketState::CloseAcknowledged;
923                Some(close)
924            }
925            WebSocketState::Terminated => unreachable!(),
926        }
927    }
928
929    /// Write a single frame into the write-buffer.
930    fn buffer_frame<Stream>(&mut self, stream: &mut Stream, mut frame: Frame) -> Result<()>
931    where
932        Stream: Read + Write,
933    {
934        match self.role {
935            Role::Server => {}
936            Role::Client => {
937                // 5.  If the data is being sent by the client, the frame(s) MUST be
938                // masked as defined in Section 5.3. (RFC 6455)
939                frame.set_random_mask();
940            }
941        }
942
943        trace!("Sending frame: {frame:?}");
944        self.frame.buffer_frame(stream, frame).check_connection_reset(self.state)
945    }
946
947    /// Replace `additional_send` if it is currently a `Pong` message.
948    fn set_additional(&mut self, add: Frame) {
949        let empty_or_pong = self
950            .additional_send
951            .as_ref()
952            .map_or(true, |f| f.header().opcode == OpCode::Control(OpCtl::Pong));
953        if empty_or_pong {
954            self.additional_send.replace(add);
955        }
956    }
957}
958
959fn check_max_size(size: usize, max_size: Option<usize>) -> crate::Result<()> {
960    if let Some(max_size) = max_size {
961        if size > max_size {
962            return Err(Error::Capacity(CapacityError::MessageTooLong { size, max_size }));
963        }
964    }
965    Ok(())
966}
967
968/// The current connection state.
969#[derive(Debug, PartialEq, Eq, Clone, Copy)]
970enum WebSocketState {
971    /// The connection is active.
972    Active,
973    /// We initiated a close handshake.
974    ClosedByUs,
975    /// The peer initiated a close handshake.
976    ClosedByPeer,
977    /// The peer replied to our close handshake.
978    CloseAcknowledged,
979    /// The connection does not exist anymore.
980    Terminated,
981}
982
983impl WebSocketState {
984    /// Tell if we're allowed to process normal messages.
985    fn is_active(self) -> bool {
986        matches!(self, WebSocketState::Active)
987    }
988
989    /// Tell if we should process incoming data. Note that if we send a close frame
990    /// but the remote hasn't confirmed, they might have sent data before they receive our
991    /// close frame, so we should still pass those to client code, hence ClosedByUs is valid.
992    fn can_read(self) -> bool {
993        matches!(self, WebSocketState::Active | WebSocketState::ClosedByUs)
994    }
995
996    /// Check if the state is active, return error if not.
997    fn check_not_terminated(self) -> Result<()> {
998        match self {
999            WebSocketState::Terminated => Err(Error::AlreadyClosed),
1000            _ => Ok(()),
1001        }
1002    }
1003}
1004
1005/// Translate "Connection reset by peer" into `ConnectionClosed` if appropriate.
1006trait CheckConnectionReset {
1007    fn check_connection_reset(self, state: WebSocketState) -> Self;
1008}
1009
1010impl<T> CheckConnectionReset for Result<T> {
1011    fn check_connection_reset(self, state: WebSocketState) -> Self {
1012        match self {
1013            Err(Error::Io(io_error)) => Err({
1014                if !state.can_read() && io_error.kind() == io::ErrorKind::ConnectionReset {
1015                    Error::ConnectionClosed
1016                } else {
1017                    Error::Io(io_error)
1018                }
1019            }),
1020            x => x,
1021        }
1022    }
1023}
1024
1025#[cfg(test)]
1026mod tests {
1027    use super::{Message, Role, WebSocket, WebSocketConfig};
1028    use crate::error::{CapacityError, Error};
1029    use crate::extensions::ExtensionsConfig;
1030
1031    use std::{io, io::Cursor};
1032
1033    struct WriteMoc<Stream>(Stream);
1034
1035    impl<Stream> io::Write for WriteMoc<Stream> {
1036        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1037            Ok(buf.len())
1038        }
1039        fn flush(&mut self) -> io::Result<()> {
1040            Ok(())
1041        }
1042    }
1043
1044    impl<Stream: io::Read> io::Read for WriteMoc<Stream> {
1045        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1046            self.0.read(buf)
1047        }
1048    }
1049
1050    #[test]
1051    fn receive_messages() {
1052        let incoming = Cursor::new(vec![
1053            0x89, 0x02, 0x01, 0x02, 0x8a, 0x01, 0x03, 0x01, 0x07, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
1054            0x2c, 0x20, 0x80, 0x06, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x82, 0x03, 0x01, 0x02,
1055            0x03,
1056        ]);
1057        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client, None);
1058        assert_eq!(socket.read().unwrap(), Message::Ping(vec![1, 2].into()));
1059        assert_eq!(socket.read().unwrap(), Message::Pong(vec![3].into()));
1060        assert_eq!(socket.read().unwrap(), Message::Text("Hello, World!".into()));
1061        assert_eq!(socket.read().unwrap(), Message::Binary(vec![0x01, 0x02, 0x03].into()));
1062    }
1063
1064    #[test]
1065    fn size_limiting_text_fragmented() {
1066        let incoming = Cursor::new(vec![
1067            0x01, 0x07, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x80, 0x06, 0x57, 0x6f, 0x72,
1068            0x6c, 0x64, 0x21,
1069        ]);
1070        let limit = WebSocketConfig { max_message_size: Some(10), ..WebSocketConfig::default() };
1071        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client, Some(limit));
1072
1073        assert!(matches!(
1074            socket.read(),
1075            Err(Error::Capacity(CapacityError::MessageTooLong { size: 13, max_size: 10 }))
1076        ));
1077    }
1078
1079    #[test]
1080    fn size_limiting_binary() {
1081        let incoming = Cursor::new(vec![0x82, 0x03, 0x01, 0x02, 0x03]);
1082        let limit = WebSocketConfig { max_message_size: Some(2), ..WebSocketConfig::default() };
1083        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client, Some(limit));
1084
1085        assert!(matches!(
1086            socket.read(),
1087            Err(Error::Capacity(CapacityError::MessageTooLong { size: 3, max_size: 2 }))
1088        ));
1089    }
1090
1091    #[cfg(feature = "deflate")]
1092    #[test]
1093    fn per_message_deflate_compression() {
1094        // Example frames from RFC 7692 Section 7.2.3.2
1095
1096        use crate::{extensions::compression, protocol::FrameCodec};
1097
1098        let mut stream = Cursor::new(Vec::new());
1099
1100        let config = WebSocketConfig {
1101            extensions: ExtensionsConfig {
1102                permessage_deflate: Some(compression::deflate::DeflateConfig::default()),
1103            },
1104            ..Default::default()
1105        };
1106        let mut socket = WebSocket::from_raw_socket(&mut stream, Role::Client, Some(config));
1107
1108        // The same message sent twice should compress better the second time
1109        // because context takeover is enabled.
1110        socket.write(Message::Text("Hello".into())).unwrap();
1111        socket.write(Message::Text("Hello".into())).unwrap();
1112        socket.flush().unwrap();
1113
1114        let written = stream.into_inner();
1115        let mut codec = FrameCodec::new(written.len());
1116
1117        let mut stream = Cursor::new(written);
1118        let first_frame = codec.read_frame(&mut stream, None, true, false).unwrap().unwrap();
1119        let second_frame = codec.read_frame(&mut stream, None, true, false).unwrap().unwrap();
1120
1121        assert_eq!(
1122            first_frame.payload(),
1123            // First frame payload, from the RFC
1124            &[0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00]
1125        );
1126
1127        assert_eq!(
1128            second_frame.payload(),
1129            // Second frame payload, from the RFC
1130            &[0xf2, 0x00, 0x11, 0x00, 0x00]
1131        );
1132    }
1133
1134    #[cfg(feature = "deflate")]
1135    #[test]
1136    fn per_message_deflate_decompression() {
1137        // Example frames from RFC 7692 Section 7.2.3.2
1138
1139        use crate::extensions::compression::deflate::DeflateConfig;
1140
1141        let incoming =
1142            Cursor::new(&[0x41, 0x03, 0xf2, 0x48, 0xcd, 0x80, 0x04, 0xc9, 0xc9, 0x07, 0x00]);
1143        let config = WebSocketConfig {
1144            extensions: ExtensionsConfig { permessage_deflate: Some(DeflateConfig::default()) },
1145            ..Default::default()
1146        };
1147        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client, Some(config));
1148
1149        assert_eq!(socket.read().unwrap(), Message::Text("Hello".into()));
1150    }
1151
1152    #[test]
1153    fn per_message_compression_not_recognized() {
1154        // Without the extension configuration, frames with the RSV1 bit set are rejected.
1155
1156        let incoming =
1157            Cursor::new(&[0x41, 0x03, 0xf2, 0x48, 0xcd, 0x80, 0x04, 0xc9, 0xc9, 0x07, 0x00]);
1158        let config =
1159            WebSocketConfig { extensions: ExtensionsConfig::default(), ..Default::default() };
1160        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client, Some(config));
1161
1162        assert!(matches!(
1163            socket.read().unwrap_err(),
1164            Error::Protocol(crate::error::ProtocolError::NonZeroReservedBits)
1165        ));
1166    }
1167
1168    #[cfg(feature = "deflate")]
1169    #[test]
1170    fn per_message_compression_decompress_respects_message_size_limit() {
1171        use crate::extensions::compression::deflate::test::very_compressed;
1172        use crate::extensions::compression::deflate::DeflateConfig;
1173        use crate::protocol::frame::{
1174            coding::{Data, OpCode},
1175            FrameHeader,
1176        };
1177
1178        let _ = env_logger::try_init();
1179
1180        let base_config = WebSocketConfig {
1181            extensions: ExtensionsConfig {
1182                permessage_deflate: Some(DeflateConfig::default()),
1183                ..Default::default()
1184            },
1185            ..Default::default()
1186        };
1187
1188        fn make_message(frame_count: usize) -> Vec<u8> {
1189            let mut is_first = true;
1190            let mut output = Vec::new();
1191
1192            for (frame, is_final) in very_compressed::make_frames(frame_count) {
1193                let is_first = std::mem::replace(&mut is_first, false);
1194                let header = FrameHeader {
1195                    opcode: OpCode::Data(if is_first { Data::Binary } else { Data::Continue }),
1196                    rsv1: is_first,
1197                    is_final,
1198                    ..Default::default()
1199                };
1200                header.format(frame.len() as u64, &mut output).unwrap();
1201                output.extend_from_slice(&frame);
1202            }
1203            output
1204        }
1205
1206        // With the default configuration, a short message of these frames is fine.
1207        {
1208            let input = Cursor::new(make_message(4));
1209            let mut socket =
1210                WebSocket::from_raw_socket(input, Role::Client, Some(base_config.clone()));
1211
1212            let message = socket.read().unwrap();
1213            assert_eq!(
1214                message,
1215                Message::Binary(
1216                    bytes::BytesMut::zeroed(4 * very_compressed::DECOMPRESSED_LEN).into()
1217                )
1218            );
1219        }
1220
1221        // The maximum frame size limits on-the-wire frame size, not
1222        // decompressed size, so this still decompresses.
1223        {
1224            let input = Cursor::new(make_message(2));
1225            const MAX_FRAME_SIZE: usize = very_compressed::DECOMPRESSED_LEN - 1;
1226
1227            let mut socket = WebSocket::from_raw_socket(
1228                input,
1229                Role::Client,
1230                Some(base_config.clone().max_frame_size(Some(MAX_FRAME_SIZE))),
1231            );
1232
1233            let message = socket.read().unwrap();
1234            assert_eq!(
1235                message,
1236                Message::Binary(
1237                    bytes::BytesMut::zeroed(2 * very_compressed::DECOMPRESSED_LEN).into()
1238                )
1239            );
1240        }
1241
1242        // With a reduced maximum message size, decompressing the whole message
1243        // fails.
1244        {
1245            let input = Cursor::new(make_message(5));
1246            const MAX_MESSAGE_SIZE: usize = 3 * very_compressed::DECOMPRESSED_LEN;
1247
1248            let mut socket = WebSocket::from_raw_socket(
1249                input,
1250                Role::Client,
1251                Some(base_config.clone().max_message_size(Some(MAX_MESSAGE_SIZE))),
1252            );
1253
1254            let error = socket.read().unwrap_err();
1255            assert!(matches!(
1256                error,
1257                Error::Capacity(CapacityError::MessageTooLong {
1258                    size: _,
1259                    max_size: MAX_MESSAGE_SIZE
1260                })
1261            ));
1262        }
1263    }
1264}