DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
websocket.cpp File Reference

WebSocket frame parser and connection pool implementation. More...

#include "websocket.h"
#include "network_drivers/transport/tcp.h"
#include "shared_primitives/utf8.h"
#include <string.h>

Go to the source code of this file.

Classes

struct  WsCtx
 

Functions

void ws_init ()
 Initialize all WebSocket pool slots to inactive.
 
bool ws_active (uint8_t ws_id)
 True if ws_id is a valid, in-use WebSocket slot. Use this instead of reaching into ws_pool[ws_id].active from another module.
 
const char * ws_payload (uint8_t ws_id)
 The NUL-terminated reassembled message payload for ws_id, or nullptr if the slot is out of range / inactive. Use this instead of reaching into ws_pool[ws_id].buf.
 
WsConnws_alloc (uint8_t slot_id)
 Allocate a WsConn slot and bind it to a TCP slot.
 
WsConnws_find (uint8_t slot_id)
 Find the WsConn for a given TCP slot, or nullptr if none.
 
void ws_free (uint8_t slot_id)
 Free the WsConn associated with a TCP slot.
 
void ws_reset_frame (WsConn *ws)
 Reset the frame parser back to WsParseState::WS_HEADER1, ready for the next frame.
 
void ws_set_frag_size (uint16_t bytes)
 Set the outbound fragmentation size (RFC 6455 sec 5.4), in payload bytes; 0 = off.
 
bool ws_send_frame (WsConn *ws, WsOpcode opcode, const uint8_t *payload, uint16_t len)
 Send a WebSocket frame to the client.
 
void ws_close (WsConn *ws, WsCloseCode code)
 Send a Close frame and mark the slot WsParseState::WS_CLOSED.
 
void ws_parse (WsConn *ws)
 Drain the ring buffer for slot_id and feed bytes to the WS parser.
 
void ws_feed_byte (WsConn *ws, uint8_t byte)
 Feed one already-plaintext byte through the WS frame state machine.
 

Variables

WsConn ws_pool [MAX_WS_CONNS]
 Pool of WebSocket connection state, one per MAX_WS_CONNS.
 

Detailed Description

WebSocket frame parser and connection pool implementation.

Handles RFC 6455 framing. Control frames (ping/pong/close) are handled automatically here; data frames (text/binary) are surfaced to the application layer via WsParseState::WS_FRAME_READY.

Automatic control frame handling

  • Ping -> sends Pong with the same payload immediately.
  • Close -> sends echoed Close frame, marks slot WsParseState::WS_CLOSED.
  • Pong -> silently discarded (keepalive response, no action needed).

Definition in file websocket.cpp.

Function Documentation

◆ ws_init()

void ws_init ( )

Initialize all WebSocket pool slots to inactive.

Called once from DetWebServer::begin().

Definition at line 31 of file websocket.cpp.

References MAX_WS_CONNS, WsConn::ws_id, and ws_pool.

Referenced by DetWebServer::begin(), and DetWebServer::stop().

◆ ws_active()

bool ws_active ( uint8_t  ws_id)

True if ws_id is a valid, in-use WebSocket slot. Use this instead of reaching into ws_pool[ws_id].active from another module.

Definition at line 40 of file websocket.cpp.

References WsConn::active, MAX_WS_CONNS, and ws_pool.

◆ ws_payload()

const char * ws_payload ( uint8_t  ws_id)

The NUL-terminated reassembled message payload for ws_id, or nullptr if the slot is out of range / inactive. Use this instead of reaching into ws_pool[ws_id].buf.

Definition at line 45 of file websocket.cpp.

References MAX_WS_CONNS, and ws_pool.

◆ ws_alloc()

WsConn * ws_alloc ( uint8_t  slot_id)

Allocate a WsConn slot and bind it to a TCP slot.

Parameters
slot_idTCP connection slot that just completed an upgrade.
Returns
Pointer to the allocated WsConn, or nullptr if the pool is full.

Definition at line 50 of file websocket.cpp.

References WsConn::active, MAX_WS_CONNS, WsConn::parse_state, WsConn::slot_id, WS_HEADER1, WsConn::ws_id, and ws_pool.

◆ ws_find()

WsConn * ws_find ( uint8_t  slot_id)

Find the WsConn for a given TCP slot, or nullptr if none.

Parameters
slot_idTCP connection slot index.

Definition at line 67 of file websocket.cpp.

References MAX_WS_CONNS, and ws_pool.

Referenced by http_parse(), and DetWebServer::http_poll_slot().

◆ ws_free()

void ws_free ( uint8_t  slot_id)

Free the WsConn associated with a TCP slot.

Parameters
slot_idTCP connection slot index.

Definition at line 77 of file websocket.cpp.

References MAX_WS_CONNS, WsConn::ws_id, and ws_pool.

Referenced by DetWebServer::http_poll_slot().

◆ ws_reset_frame()

void ws_reset_frame ( WsConn ws)

Reset the frame parser back to WsParseState::WS_HEADER1, ready for the next frame.

Does not change ws->active or ws->slot_id.

Parameters
wsWebSocket connection to reset.

Definition at line 105 of file websocket.cpp.

References WsConn::buf, WsConn::ctl_buf, WsConn::fragmenting, WsConn::msg_len, WsConn::msg_opcode, and WS_OP_TEXT.

Referenced by DetWebServer::http_poll_slot().

◆ ws_set_frag_size()

void ws_set_frag_size ( uint16_t  bytes)

Set the outbound fragmentation size (RFC 6455 sec 5.4), in payload bytes; 0 = off.

A runtime override of DETWS_WS_FRAG_SIZE. When >0, a data message longer than bytes is split into that-sized frames by ws_send_frame() (see DETWS_WS_FRAG_SIZE). Applies to all connections.

Definition at line 128 of file websocket.cpp.

References WsCtx::frag_size.

◆ ws_send_frame()

bool ws_send_frame ( WsConn ws,
WsOpcode  opcode,
const uint8_t *  payload,
uint16_t  len 
)

Send a WebSocket frame to the client.

Builds the header (no masking – server-to-client frames are never masked) and hands both to the transport layer (det_conn_send()). The caller is responsible for flushing afterwards (det_conn_flush()).

Parameters
wsWebSocket connection.
opcodeFrame opcode (WsOpcode::WS_OP_TEXT, WsOpcode::WS_OP_BINARY, WsOpcode::WS_OP_PONG, etc.).
payloadPayload bytes (may be nullptr for zero-length frames).
lenPayload length in bytes.
Returns
true on success, false if the TCP slot is not active.

Definition at line 159 of file websocket.cpp.

References conn_pool, WsCtx::frag_size, scratch_alloc(), WsConn::slot_id, WS_OP_BINARY, WS_OP_CONTINUATION, and WS_OP_TEXT.

Referenced by ws_close().

◆ ws_close()

void ws_close ( WsConn ws,
WsCloseCode  code 
)

Send a Close frame and mark the slot WsParseState::WS_CLOSED.

Parameters
wsWebSocket connection.
codeClose status code (e.g. WsCloseCode::WS_CLOSE_NORMAL).

Definition at line 221 of file websocket.cpp.

References det_conn_flush(), WsConn::parse_state, WsConn::slot_id, WS_CLOSED, WS_OP_CLOSE, and ws_send_frame().

Referenced by ws_feed_byte().

◆ ws_parse()

void ws_parse ( WsConn ws)

Drain the ring buffer for slot_id and feed bytes to the WS parser.

Stops when the ring buffer is empty or the parser reaches a terminal state (WsParseState::WS_FRAME_READY, WsParseState::WS_CLOSED, WsParseState::WS_ERROR).

Parameters
wsWebSocket connection to drain into.

Definition at line 345 of file websocket.cpp.

References WsConn::parse_state, WsConn::slot_id, WS_CLOSED, WS_ERROR, ws_feed_byte(), and WS_FRAME_READY.

Referenced by DetWebServer::http_poll_slot().

◆ ws_feed_byte()

void ws_feed_byte ( WsConn ws,
uint8_t  byte 
)

Feed one already-plaintext byte through the WS frame state machine.

The per-byte core shared by ws_parse() (which reads the plaintext rx ring) and the TLS receive path (which decrypts ciphertext and feeds the plaintext here). Callers must stop feeding once parse_state reaches a terminal state (WsParseState::WS_FRAME_READY / WsParseState::WS_CLOSED / WsParseState::WS_ERROR) and dispatch/reset before continuing.

Parameters
wsWebSocket connection.
byteNext plaintext byte of the client frame stream.

Definition at line 364 of file websocket.cpp.

References WsConn::buf, conn_pool, WsConn::ctl_buf, WsConn::fin, WsConn::fragmenting, WsConn::len64_count, WsConn::mask_key, WsConn::masked, WsConn::msg_len, WsConn::msg_opcode, WsConn::opcode, WsConn::parse_state, WsConn::payload_idx, WsConn::payload_len, WsConn::slot_id, ws_close(), WS_CLOSE_PROTOCOL, WS_CLOSE_TOO_BIG, WS_ERROR, WS_FRAME_SIZE, WS_HEADER1, WS_HEADER2, WS_LEN16_HI, WS_LEN16_LO, WS_LEN64, WS_MASK0, WS_MASK1, WS_MASK2, WS_MASK3, WS_OP_BINARY, WS_OP_CLOSE, WS_OP_CONTINUATION, WS_OP_PING, WS_OP_PONG, WS_OP_TEXT, and WS_PAYLOAD.

Referenced by DetWebServer::http_poll_slot(), and ws_parse().

Variable Documentation

◆ ws_pool

WsConn ws_pool[MAX_WS_CONNS]

Pool of WebSocket connection state, one per MAX_WS_CONNS.

Definition at line 29 of file websocket.cpp.

Referenced by ws_active(), ws_alloc(), ws_find(), ws_free(), ws_init(), and ws_payload().