cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
websocket.h File Reference

WebSocket upgrade and frame handling. More...

#include <cwist/net/http/http.h>
#include <stdint.h>
#include <stdbool.h>
Include dependency graph for websocket.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  cwist_websocket
 
struct  cwist_ws_frame
 

Typedefs

typedef struct cwist_websocket cwist_websocket
 
typedef struct cwist_ws_frame cwist_ws_frame
 

Enumerations

enum  cwist_ws_opcode_t {
  CWIST_WS_FRAME_CONTINUATION = 0x0 , CWIST_WS_FRAME_TEXT = 0x1 , CWIST_WS_FRAME_BINARY = 0x2 , CWIST_WS_FRAME_CLOSE = 0x8 ,
  CWIST_WS_FRAME_PING = 0x9 , CWIST_WS_FRAME_PONG = 0xA
}
 

Functions

bool cwist_websocket_upgrade_response (cwist_http_request *req, cwist_http_response *res)
 Validate the upgrade request and fill a 101 Switching Protocols response.
 
cwist_websocket * cwist_websocket_upgrade (cwist_http_request *req, int client_fd)
 Upgrade a standard HTTP request to a WebSocket connection.
 
cwist_ws_frame * cwist_websocket_receive (cwist_websocket *ws)
 Receive a frame, blocking until data arrives or the socket closes.
 
int cwist_websocket_send (cwist_websocket *ws, cwist_ws_opcode_t opcode, const uint8_t *data, size_t len)
 Send a frame with the specified opcode and payload.
 
int cwist_websocket_send_sequenced (cwist_websocket *ws, const uint8_t *data, size_t len, uint16_t chunk_payload_size)
 Send a large payload as sequenced binary frames.
 
uint8_t * cwist_websocket_receive_sequenced (cwist_websocket *ws, size_t *out_len)
 Receive and reassemble a sequenced binary message.
 
void cwist_websocket_frame_destroy (cwist_ws_frame *frame)
 Destroy a frame.
 
void cwist_websocket_close (cwist_websocket *ws)
 Close the WebSocket connection.
 
void cwist_websocket_destroy (cwist_websocket *ws)
 Destroy the WebSocket context.
 

Detailed Description

WebSocket upgrade and frame handling.

Definition in file websocket.h.

Typedef Documentation

◆ cwist_websocket

◆ cwist_ws_frame

Enumeration Type Documentation

◆ cwist_ws_opcode_t

Enumerator
CWIST_WS_FRAME_CONTINUATION 
CWIST_WS_FRAME_TEXT 
CWIST_WS_FRAME_BINARY 
CWIST_WS_FRAME_CLOSE 
CWIST_WS_FRAME_PING 
CWIST_WS_FRAME_PONG 

Definition at line 13 of file websocket.h.

Function Documentation

◆ cwist_websocket_close()

void cwist_websocket_close ( cwist_websocket *  ws)

Close the WebSocket connection.

Close the WebSocket connection.

Parameters
wsConnection to close. NULL is ignored.

Definition at line 512 of file websocket.c.

References cap, cwist_websocket_send(), CWIST_WS_FRAME_CLOSE, and cwist_websocket::is_closed.

◆ cwist_websocket_destroy()

void cwist_websocket_destroy ( cwist_websocket *  ws)

Destroy the WebSocket context.

Destroy the WebSocket context.

Parameters
wsWrapper to release. NULL is ignored.

Definition at line 523 of file websocket.c.

References cwist_free(), and cwist_websocket::frag_buf.

◆ cwist_websocket_frame_destroy()

void cwist_websocket_frame_destroy ( cwist_ws_frame *  frame)

Destroy a frame.

Destroy a frame.

Parameters
frameFrame object to destroy. NULL is ignored.

Definition at line 436 of file websocket.c.

References cap, and cwist_free().

◆ cwist_websocket_receive()

cwist_ws_frame * cwist_websocket_receive ( cwist_websocket *  ws)

Receive a frame, blocking until data arrives or the socket closes.

Returns
NULL on error or if the connection was closed.

Receive a frame, blocking until data arrives or the socket closes.

Transparently reassembles fragmented messages (RFC 6455 section 5.4): frames with FIN=0 are buffered internally and the function blocks until the final FIN=1 frame arrives, at which point the fully-assembled payload is returned as a single frame. Control frames (CLOSE, PING, PONG) are always FIN=1 and are delivered immediately even when a fragmented data message is in progress.

Client frames are required to be masked by RFC 6455, so unmasked payloads are rejected. The returned payload is null-terminated for convenience.

Parameters
wsWebSocket connection wrapper returned by cwist_websocket_upgrade().
Returns
Newly allocated frame, or NULL when the connection is closed or invalid.

Definition at line 217 of file websocket.c.

References cap, cwist_alloc(), cwist_free(), cwist_websocket_send(), CWIST_WS_FRAME_CLOSE, CWIST_WS_FRAME_CONTINUATION, CWIST_WS_FRAME_PING, CWIST_WS_FRAME_PONG, CWIST_WS_MAX_PAYLOAD_BYTES, cwist_websocket::fd, cwist_websocket::frag_buf, cwist_websocket::frag_cap, cwist_websocket::frag_len, cwist_websocket::frag_opcode, head, and cwist_websocket::is_closed.

◆ cwist_websocket_receive_sequenced()

uint8_t * cwist_websocket_receive_sequenced ( cwist_websocket *  ws,
size_t *  out_len 
)

Receive and reassemble a sequenced binary message.

Reads binary frames until every chunk of one sequenced message has arrived, discarding duplicates and reordering out-of-order chunks. The returned buffer is heap-allocated and must be freed with cwist_free().

Parameters
wsWebSocket connection.
out_lenReceives the length of the reassembled payload.
Returns
Newly allocated payload buffer, or NULL on error/incomplete message.

Definition at line 468 of file websocket.c.

References cap, cwist_alloc(), cwist_seq_assembler_create(), cwist_seq_assembler_destroy(), cwist_seq_assembler_feed(), cwist_seq_assembler_get_data(), cwist_seq_assembler_is_complete(), cwist_seq_chunk_parse(), cwist_websocket_frame_destroy(), cwist_websocket_receive(), CWIST_WS_FRAME_BINARY, CWIST_WS_FRAME_CLOSE, and cwist_websocket::is_closed.

◆ cwist_websocket_send()

int cwist_websocket_send ( cwist_websocket *  ws,
cwist_ws_opcode_t  opcode,
const uint8_t *  data,
size_t  len 
)

Send a frame with the specified opcode and payload.

Send a frame with the specified opcode and payload.

Parameters
wsActive WebSocket connection wrapper.
opcodeWebSocket opcode describing the payload semantics.
dataOptional payload buffer. May be NULL when len is zero.
lenNumber of payload bytes to transmit.
Returns
0 on success, or -1 when the socket write fails.

Definition at line 398 of file websocket.c.

References cap, cwist_websocket::fd, head, and cwist_websocket::is_closed.

◆ cwist_websocket_send_sequenced()

int cwist_websocket_send_sequenced ( cwist_websocket *  ws,
const uint8_t *  data,
size_t  len,
uint16_t  chunk_payload_size 
)

Send a large payload as sequenced binary frames.

Splits data into chunks of chunk_payload_size (or smaller for the final chunk), prefixes each chunk with the CWIST sequence header, and sends every chunk as an independent binary frame. The peer can reassemble the original payload even when frames arrive out of order.

Parameters
wsWebSocket connection.
dataPayload bytes.
lenPayload length.
chunk_payload_sizeMaximum payload bytes per chunk (must be > 0).
Returns
0 on success, -1 on failure.

Definition at line 446 of file websocket.c.

References cap, cwist_seq_message_free(), cwist_seq_split(), cwist_websocket_send(), CWIST_WS_FRAME_BINARY, and cwist_websocket::is_closed.

◆ cwist_websocket_upgrade()

cwist_websocket * cwist_websocket_upgrade ( cwist_http_request *  req,
int  client_fd 
)

Upgrade a standard HTTP request to a WebSocket connection.

Returns
NULL if the handshake fails or the request is invalid, otherwise the upgraded context.

Upgrade a standard HTTP request to a WebSocket connection.

The function validates the required upgrade headers, computes the Sec-WebSocket-Accept response, emits the 101 Switching Protocols reply, and returns a lightweight wrapper around the already-open client socket.

Parameters
reqParsed HTTP request that requested the upgrade.
client_fdAccepted client socket descriptor.
Returns
WebSocket wrapper on success, or NULL when the handshake fails.

Definition at line 119 of file websocket.c.

References cap, cwist_alloc(), cwist_http_response_create(), cwist_http_response_destroy(), cwist_http_send_response(), cwist_websocket_upgrade_response(), CWIST_WS_FRAME_CONTINUATION, cwist_websocket::fd, cwist_websocket::frag_buf, cwist_websocket::frag_cap, cwist_websocket::frag_len, cwist_websocket::frag_opcode, cwist_websocket::is_closed, and cwist_http_request::upgraded.

◆ cwist_websocket_upgrade_response()

bool cwist_websocket_upgrade_response ( cwist_http_request *  req,
cwist_http_response *  res 
)

Validate the upgrade request and fill a 101 Switching Protocols response.

Computes the Sec-WebSocket-Accept key (sha1 + base64), sets status 101 and the Upgrade/Connection/Sec-WebSocket-Accept headers on res, but does NOT send anything. Shared by the blocking cwist_websocket_upgrade() and the C1M reactor path, which sends the 101 through the coalesced HTTP writer.

Parameters
reqParsed upgrade request to validate.
resResponse object to fill (must be empty).
Returns
true when the handshake is valid and res carries the 101 reply.

Definition at line 71 of file websocket.c.

References base64_encode(), cap, cwist_free(), cwist_http_header_add(), cwist_http_header_get(), cwist_sstring_assign(), cwist_http_request::headers, cwist_http_response::headers, sha1(), cwist_http_response::status_code, cwist_http_response::status_text, and WS_GUID.

Referenced by cwist_websocket_upgrade().