31struct MHD_WebSocketStream
53 char control_utf8_step;
57 char *data_payload_start;
61 char *control_payload;
63 size_t max_payload_size;
65 size_t frame_header_size;
67 size_t data_payload_size;
73 char frame_header[32];
78#define MHD_WEBSOCKET_FLAG_MASK_SERVERCLIENT MHD_WEBSOCKET_FLAG_CLIENT
79#define MHD_WEBSOCKET_FLAG_MASK_FRAGMENTATION \
80 MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
81#define MHD_WEBSOCKET_FLAG_MASK_GENERATE_CLOSE_FRAMES \
82 MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR
83#define MHD_WEBSOCKET_FLAG_MASK_ALL \
84 (MHD_WEBSOCKET_FLAG_MASK_SERVERCLIENT \
85 | MHD_WEBSOCKET_FLAG_MASK_FRAGMENTATION \
86 | MHD_WEBSOCKET_FLAG_MASK_GENERATE_CLOSE_FRAMES)
220 if ((
'0' <=
c) && (
'9' >=
c))
241 const char *end =
NULL;
245 if ((
'0' <=
c) && (
'9' >=
c))
298 for (
size_t i = 0; ; ++
i)
306 if ((
'!' ==
c) || (
'#' ==
c) || (
'$' ==
c) || (
'%' ==
c) ||
307 (
'&' ==
c) || (
'\'' ==
c) || (
'*' ==
c) ||
308 (
'+' ==
c) || (
'-' ==
c) || (
'.' ==
c) || (
'^' ==
c) ||
309 (
'_' ==
c) || (
'`' ==
c) || (
'|' ==
c) || (
'~' ==
c) ||
310 ((
'0' <=
c) && (
'9' >=
c)) ||
311 ((
'A' <=
c) && (
'Z' >=
c)) || ((
'a' <=
c) && (
'z' >=
c)) )
320 else if ((
' ' ==
c) || (
'\t' ==
c))
324 else if ((
',' ==
c) || (0 ==
c))
381 for (
size_t i = 0; ; ++
i)
390 if ((
'!' ==
c) || (
'#' ==
c) || (
'$' ==
c) || (
'%' ==
c) ||
391 (
'&' ==
c) || (
'\'' ==
c) || (
'*' ==
c) ||
392 (
'+' ==
c) || (
'-' ==
c) || (
'.' ==
c) || (
'^' ==
c) ||
393 (
'_' ==
c) || (
'`' ==
c) || (
'|' ==
c) || (
'~' ==
c) ||
395 ((
'0' <=
c) && (
'9' >=
c)) ||
396 ((
'A' <=
c) && (
'Z' >=
c)) || ((
'a' <=
c) && (
'z' >=
c)) )
405 else if ((
' ' ==
c) || (
'\t' ==
c))
409 else if ((
',' ==
c) || (0 ==
c))
501 const char *
suffix =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
513 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
514 for (
int i = 0,
j = 0;
i < 20;)
540 size_t max_payload_size)
560 size_t max_payload_size,
574 ((
uint64_t) 0x7FFFFFFFFFFFFFFF < max_payload_size) ||
585 struct MHD_WebSocketStream *
ws_ = (
struct MHD_WebSocketStream *) malloc (
586 sizeof (
struct MHD_WebSocketStream));
591 memset (
ws_, 0,
sizeof (
struct MHD_WebSocketStream));
593 ws_->max_payload_size = max_payload_size;
597 ws_->cls_rng = cls_rng;
619 if (
ws->data_payload)
620 ws->free (
ws->data_payload);
621 if (
ws->control_payload)
622 ws->free (
ws->control_payload);
699 switch (
ws->decode_step)
729 if (0 ==
ws->data_type)
770 if (0 !=
ws->data_type)
915 if (0 != (
ws->frame_header [0] & 0x08))
969 (
ws->max_payload_size && (
ws->max_payload_size < size)) )
986 ws->payload_size = size;
1045 (
ws->max_payload_size && (
ws->max_payload_size < size)) )
1063 ws->payload_size = size;
1064 if (0 != (
ws->frame_header [1] & 0x80))
1083 if (0x7fffffffffffffff < size)
1121 (
ws->max_payload_size && (
ws->max_payload_size < size)) )
1141 if (0 != (
ws->frame_header [1] & 0x80))
1192 ws->data_payload_start :
1193 ws->control_payload;
1200 (
unsigned long) (
ws->payload_index
1210 (2 <
ws->payload_index)) )
1270 if (
ws->payload_size ==
ws->payload_index)
1302 switch (
ws->decode_step)
1306 if (
ws->payload_size ==
ws->payload_index)
1333 char opcode =
ws->frame_header [0] & 0x0f;
1340 if ((0 !=
ws->max_payload_size) && (
ws->max_payload_size <
1369 ws->data_payload_start = &
new_buf[
ws->data_payload_size];
1437 (
ws->frame_header [0] & 0x0F);
1438 char is_fin =
ws->frame_header [0] & 0x80;
1445 char data_type =
ws->data_type;
1453 ws->data_payload = 0;
1454 ws->data_payload_start = 0;
1455 ws->data_payload_size = 0;
1457 ws->payload_index = 0;
1459 ws->frame_header_size = 0;
1467 ws->control_payload = 0;
1469 ws->payload_index = 0;
1470 ws->frame_header_size = 0;
1471 return (
ws->frame_header [0] & 0x0f);
1484 switch (
ws->data_utf8_step)
1531 ws->payload_index = 0;
1532 ws->frame_header_size = 0;
1534 return ws->data_type | 0x20;
1536 return ws->data_type | 0x10;
1543 ws->data_payload = 0;
1544 ws->data_payload_start = 0;
1545 ws->data_payload_size = 0;
1547 ws->payload_index = 0;
1548 ws->frame_header_size = 0;
1550 return ws->data_type | 0x20;
1552 return ws->data_type | 0x10;
1560 ws->frame_header_size = 0;
1561 ws->payload_index = 0;
2087 for (
size_t i = 0;
i < len; ++
i)
2316 unsigned char mask_[4];
2401 if (((
char *) &
endian)[0] == 0x01)
2404 ((
char *) &
endian)[0] = ((
char *) &value)[1];
2405 ((
char *) &
endian)[1] = ((
char *) &value)[0];
2425 if (((
char *) &
endian)[0] == 0x01)
2428 ((
char *) &
endian)[0] = ((
char *) &value)[7];
2429 ((
char *) &
endian)[1] = ((
char *) &value)[6];
2430 ((
char *) &
endian)[2] = ((
char *) &value)[5];
2431 ((
char *) &
endian)[3] = ((
char *) &value)[4];
2432 ((
char *) &
endian)[4] = ((
char *) &value)[3];
2433 ((
char *) &
endian)[5] = ((
char *) &value)[2];
2434 ((
char *) &
endian)[6] = ((
char *) &value)[1];
2435 ((
char *) &
endian)[7] = ((
char *) &value)[0];
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_split_close_reason(const char *payload, size_t payload_len, unsigned short *reason_code, const char **reason_utf8, size_t *reason_utf8_len)
static uint64_t MHD_htonll(uint64_t value)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_check_http_version(const char *http_version)
_MHD_EXTERN enum MHD_WEBSOCKET_VALIDITY MHD_websocket_stream_is_valid(struct MHD_WebSocketStream *ws)
static char MHD_websocket_encode_is_masked(struct MHD_WebSocketStream *ws)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_stream_free(struct MHD_WebSocketStream *ws)
@ MHD_WebSocket_UTF8Result_Valid
@ MHD_WebSocket_UTF8Result_Invalid
@ MHD_WebSocket_UTF8Result_Incomplete
#define MHD_WEBSOCKET_FLAG_MASK_SERVERCLIENT
@ MHD_WebSocket_DecodeStep_Length1ofX
@ MHD_WebSocket_DecodeStep_Start
@ MHD_WebSocket_DecodeStep_Mask4Of4
@ MHD_WebSocket_DecodeStep_Length3of8
@ MHD_WebSocket_DecodeStep_HeaderCompleted
@ MHD_WebSocket_DecodeStep_Length7of8
@ MHD_WebSocket_DecodeStep_Length2of2
@ MHD_WebSocket_DecodeStep_Mask3Of4
@ MHD_WebSocket_DecodeStep_Length4of8
@ MHD_WebSocket_DecodeStep_Mask2Of4
@ MHD_WebSocket_DecodeStep_Length5of8
@ MHD_WebSocket_DecodeStep_PayloadOfControlFrame
@ MHD_WebSocket_DecodeStep_Length1of8
@ MHD_WebSocket_DecodeStep_PayloadOfDataFrame
@ MHD_WebSocket_DecodeStep_BrokenStream
@ MHD_WebSocket_DecodeStep_Mask1Of4
@ MHD_WebSocket_DecodeStep_Length2of8
@ MHD_WebSocket_DecodeStep_Length1of2
@ MHD_WebSocket_DecodeStep_Length6of8
@ MHD_WebSocket_DecodeStep_Length8of8
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_encode_pong(struct MHD_WebSocketStream *ws, const char *payload, size_t payload_len, char **frame, size_t *frame_len)
#define MHD_WEBSOCKET_FLAG_MASK_ALL
_MHD_EXTERN int MHD_websocket_free(struct MHD_WebSocketStream *ws, void *buf)
static uint32_t MHD_websocket_generate_mask(struct MHD_WebSocketStream *ws)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_stream_init(struct MHD_WebSocketStream **ws, int flags, size_t max_payload_size)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_encode_ping(struct MHD_WebSocketStream *ws, const char *payload, size_t payload_len, char **frame, size_t *frame_len)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_decode(struct MHD_WebSocketStream *ws, const char *streambuf, size_t streambuf_len, size_t *streambuf_read_len, char **payload, size_t *payload_len)
static enum MHD_WEBSOCKET_STATUS MHD_websocket_encode_data(struct MHD_WebSocketStream *ws, const char *payload, size_t payload_len, int fragmentation, char **frame, size_t *frame_len, char opcode)
static enum MHD_WEBSOCKET_STATUS MHD_websocket_encode_ping_pong(struct MHD_WebSocketStream *ws, const char *payload, size_t payload_len, char **frame, size_t *frame_len, char opcode)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_encode_close(struct MHD_WebSocketStream *ws, unsigned short reason_code, const char *reason_utf8, size_t reason_utf8_len, char **frame, size_t *frame_len)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_check_connection_header(const char *connection_header)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_stream_init2(struct MHD_WebSocketStream **ws, int flags, size_t max_payload_size, MHD_WebSocketMallocCallback callback_malloc, MHD_WebSocketReallocCallback callback_realloc, MHD_WebSocketFreeCallback callback_free, void *cls_rng, MHD_WebSocketRandomNumberGenerator callback_rng)
static char MHD_websocket_encode_overhead_size(struct MHD_WebSocketStream *ws, size_t payload_len)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_create_accept_header(const char *sec_websocket_key, char *sec_websocket_accept)
_MHD_EXTERN void * MHD_websocket_realloc(struct MHD_WebSocketStream *ws, void *buf, size_t new_buf_len)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_stream_invalidate(struct MHD_WebSocketStream *ws)
_MHD_EXTERN void * MHD_websocket_malloc(struct MHD_WebSocketStream *ws, size_t buf_len)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_encode_binary(struct MHD_WebSocketStream *ws, const char *payload, size_t payload_len, int fragmentation, char **frame, size_t *frame_len)
static uint16_t MHD_htons(uint16_t value)
static void MHD_websocket_copy_payload(char *dst, const char *src, size_t len, uint32_t mask, unsigned long mask_offset)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_encode_text(struct MHD_WebSocketStream *ws, const char *payload_utf8, size_t payload_utf8_len, int fragmentation, char **frame, size_t *frame_len, int *utf8_step)
static int MHD_websocket_check_utf8(const char *buf, size_t buf_len, int *utf8_step, size_t *buf_offset)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_check_version_header(const char *version_header)
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS MHD_websocket_check_upgrade_header(const char *upgrade_header)
static enum MHD_WEBSOCKET_STATUS MHD_websocket_decode_header_complete(struct MHD_WebSocketStream *ws, char **payload, size_t *payload_len)
static enum MHD_WEBSOCKET_STATUS MHD_websocket_decode_payload_complete(struct MHD_WebSocketStream *ws, char **payload, size_t *payload_len)
@ MHD_WebSocket_Opcode_Close
@ MHD_WebSocket_Opcode_Continuation
@ MHD_WebSocket_Opcode_Text
@ MHD_WebSocket_Opcode_Ping
@ MHD_WebSocket_Opcode_Binary
@ MHD_WebSocket_Opcode_Pong
void MHD_SHA1_update(void *ctx_, const uint8_t *data, size_t length)
void MHD_SHA1_finish(void *ctx_, uint8_t digest[SHA1_DIGEST_SIZE])
void MHD_SHA1_init(void *ctx_)
public interface to libmicrohttpd
interface for experimental web socket extension to libmicrohttpd
size_t(* MHD_WebSocketRandomNumberGenerator)(void *cls, void *buf, size_t buf_len)
MHD_WEBSOCKET_STATUS
Enum of the return value for almost every MHD_websocket function. Errors are negative and values equa...
@ MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED
@ MHD_WEBSOCKET_STATUS_STREAM_BROKEN
@ MHD_WEBSOCKET_STATUS_PARAMETER_ERROR
@ MHD_WEBSOCKET_STATUS_OK
@ MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR
@ MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER
@ MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR
@ MHD_WEBSOCKET_STATUS_MEMORY_ERROR
@ MHD_WEBSOCKET_FLAG_SERVER
@ MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
@ MHD_WEBSOCKET_FLAG_CLIENT
@ MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR
MHD_WEBSOCKET_VALIDITY
Enumeration of validity values.
@ MHD_WEBSOCKET_VALIDITY_INVALID
@ MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES
@ MHD_WEBSOCKET_VALIDITY_VALID
@ MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1
@ MHD_WEBSOCKET_UTF8STEP_NORMAL
@ MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3
@ MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3
@ MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3
@ MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2
@ MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3
@ MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2
@ MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2
@ MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2
@ MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3
@ MHD_WEBSOCKET_CLOSEREASON_MAXIMUM_ALLOWED_PAYLOAD_SIZE_EXCEEDED
@ MHD_WEBSOCKET_CLOSEREASON_MALFORMED_UTF8
@ MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR
@ MHD_WEBSOCKET_CLOSEREASON_NO_REASON
@ MHD_WEBSOCKET_FRAGMENTATION_FIRST
@ MHD_WEBSOCKET_FRAGMENTATION_LAST
@ MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING
@ MHD_WEBSOCKET_FRAGMENTATION_NONE
void *(* MHD_WebSocketReallocCallback)(void *buf, size_t new_buf_len)
void *(* MHD_WebSocketMallocCallback)(size_t buf_len)
void(* MHD_WebSocketFreeCallback)(void *buf)