SpriteHTTPD - embedded HTTP server with read-only filesystem and templating, originally developed for ESP8266, now stand-alone and POSIX compatible.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
spritehttpd/spritehttpd/include/cgi-websocket.h

122 lines
3.6 KiB

#pragma once
#include "httpd.h"
/**
* Websocket handle
*/
typedef struct Websock Websock;
#define WEBSOCK_FLAG_NONE 0
#define WEBSOCK_FLAG_MORE (1<<0) // Set if the data is not the final data in the message; more follows
#define WEBSOCK_FLAG_BIN (1<<1) // Set if the data is binary instead of text
#define WEBSOCK_FLAG_CONT (1<<2) // set if this is a continuation frame (after WEBSOCK_FLAG_MORE)
/* https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1 */
typedef enum websock_close_reason {
/// Normal close
WS_CLOSE_OK = 1000,
/// Server shutting down
WS_CLOSE_GONE = 1001,
/// Protocol error
WS_CLOSE_PROTOCOL_ERR = 1002,
/// Data type error (e.g. binary frame on a text socket)
WS_CLOSE_DATA_TYPE_ERR = 1003,
/// Data format error (e.g. malformed UTF-8)
WS_CLOSE_DATA_FORMAT_ERR = 1007,
/// Policy violation of some kind
WS_CLOSE_POLICY_ERR = 1008,
/// Message too big to handle
WS_CLOSE_MESSAGE_TOO_BIG = 1009,
/// Internal server error
WS_CLOSE_SERVER_ERROR = 1011,
} websock_close_reason;
/** Type for the WS connect callback */
typedef void(*WsConnectedCb)(Websock *ws);
/** Type for the WS receive callback */
typedef void(*WsRecvCb)(Websock *ws, uint8_t *data, size_t len, int flags);
/** Type for the WS sending done callback */
typedef void(*WsSentCb)(Websock *ws);
/** Type for the WS close callback */
typedef void(*WsCloseCb)(Websock *ws);
/** Internal websocket struct (opaque) */
typedef struct WebsockPriv WebsockPriv;
// TODO convert to container_of and avoid separate malloc for priv
struct Websock {
/// Pointer to arbitrary user data, put there e.g. during 'recvCb'
void *userData;
/// Connection pointer
HttpdConnData *conn;
/// Receive callback - new data; optional, set by user in WsConnectedCb
WsRecvCb recvCb;
/// Sent callback - last sending finished; optional, set by user in WsConnectedCb
WsSentCb sentCb;
/// Close callback - socket was closed, either by client or server ; optional, set by user in WsConnectedCb
WsCloseCb closeCb;
/// Websocket private data
WebsockPriv *priv;
};
/**
* CGI function for a websocket endpoint
*
* @param connData
* @return CGI state
*/
httpd_cgi_state cgiWebsocket(HttpdConnData *connData);
/**
* Send data to a websocket
*
* @param ws - Websocket handle
* @param data - data to send
* @param len - data len
* @param flags - flags, OR'ed WEBSOCK_FLAG_X constants
* @return 1 = OK
*/
int cgiWebsocketSend(Websock *ws, const uint8_t *data, size_t len, int flags);
/**
* Close a websocket
*
* @param ws - Websocket handle
* @param reason - close reason (2 bytes). Normally 1000
*/
void cgiWebsocketClose(Websock *ws, websock_close_reason reason);
/**
* Websocket endpoint receive handler (used in the CGI route)
*
* @param connData - connection
* @param data - bytes received
* @param len - data len
* @return CGI state
*/
httpd_cgi_state cgiWebSocketRecv(HttpdConnData *connData, uint8_t *data, size_t len);
/**
* Broadcast a message to all open websockets at a given endpoint
*
* @param resource - websocket path
* @param data - bytes received
* @param len - data len
* @param flags - OR'ed WEBSOCK_FLAG_X constants
* @return Returns the amount of connections sent to, -1 if sending failed
*/
int cgiWebsockBroadcast(const char *resource, const uint8_t *data, size_t len, int flags);
/**
* Measure websockets backlog (debug telemetry)
*
* @param resource - websocket path
* @param[out] total - the total backlog for the path is stored here
* @param[out] max - the max backlog per websock is stored here
*/
void cgiWebsockMeasureBacklog(const char *resource, size_t *total, size_t *max);