|
DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
|
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. | |
| WsConn * | ws_alloc (uint8_t slot_id) |
| Allocate a WsConn slot and bind it to a TCP slot. | |
| WsConn * | ws_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. | |
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
Definition in file websocket.cpp.
| 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().
| 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.
| 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.
| WsConn * ws_alloc | ( | uint8_t | slot_id | ) |
Allocate a WsConn slot and bind it to a TCP slot.
| slot_id | TCP connection slot that just completed an upgrade. |
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.
| WsConn * ws_find | ( | uint8_t | slot_id | ) |
Find the WsConn for a given TCP slot, or nullptr if none.
| slot_id | TCP 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().
| void ws_free | ( | uint8_t | slot_id | ) |
Free the WsConn associated with a TCP slot.
| slot_id | TCP 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().
| 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.
| ws | WebSocket 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().
| 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.
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()).
| ws | WebSocket connection. |
| opcode | Frame opcode (WsOpcode::WS_OP_TEXT, WsOpcode::WS_OP_BINARY, WsOpcode::WS_OP_PONG, etc.). |
| payload | Payload bytes (may be nullptr for zero-length frames). |
| len | Payload length in bytes. |
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().
| void ws_close | ( | WsConn * | ws, |
| WsCloseCode | code | ||
| ) |
Send a Close frame and mark the slot WsParseState::WS_CLOSED.
| ws | WebSocket connection. |
| code | Close 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().
| 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).
| ws | WebSocket 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().
| 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.
| ws | WebSocket connection. |
| byte | Next 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().
| 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().