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)
134 unsigned long mask_offset);
145 size_t *payload_len);
150 size_t *payload_len);
192 if (
NULL == http_version)
202 if ((
'H' != http_version[0]) ||
203 (
'T' != http_version[1]) ||
204 (
'T' != http_version[2]) ||
205 (
'P' != http_version[3]) ||
206 (
'/' != http_version[4]))
214 const char *major =
NULL;
215 const char *dot =
NULL;
219 char c = http_version[i];
220 if ((
'0' <= c) && (
'9' >= c))
222 if ((
NULL == major) ||
223 ((http_version + i == major + 1) && (
'0' == *major)) )
225 major = http_version + i;
229 else if (
'.' == http_version[i])
231 dot = http_version + i;
240 const char *minor =
NULL;
241 const char *end =
NULL;
244 char c = http_version[i];
245 if ((
'0' <= c) && (
'9' >= c))
247 if ((
NULL == minor) ||
248 ((http_version + i == minor + 1) && (
'0' == *minor)) )
250 minor = http_version + i;
256 end = http_version + i;
268 if ((2 <= dot - major) || (
'2' <= *major) ||
269 ((
'1' == *major) && ((2 <= end - minor) || (
'1' <= *minor))) )
285 if (
NULL == connection_header)
296 const char *token_start =
NULL;
297 const char *token_end =
NULL;
298 for (
size_t i = 0; ; ++i)
300 char c = connection_header[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)) )
314 if (
NULL == token_start)
316 token_start = connection_header + i;
318 token_end = connection_header + i + 1;
320 else if ((
' ' == c) || (
'\t' == c))
324 else if ((
',' == c) || (0 == c))
327 if (
NULL != token_start)
329 if (7 == (token_end - token_start) )
331 if ( ((
'U' == token_start[0]) || (
'u' == token_start[0])) &&
332 ((
'P' == token_start[1]) || (
'p' == token_start[1])) &&
333 ((
'G' == token_start[2]) || (
'g' == token_start[2])) &&
334 ((
'R' == token_start[3]) || (
'r' == token_start[3])) &&
335 ((
'A' == token_start[4]) || (
'a' == token_start[4])) &&
336 ((
'D' == token_start[5]) || (
'd' == token_start[5])) &&
337 ((
'E' == token_start[6]) || (
'e' == token_start[6])) )
368 if (
NULL == upgrade_header)
379 const char *keyword_start =
NULL;
380 const char *keyword_end =
NULL;
381 for (
size_t i = 0; ; ++i)
383 char c = upgrade_header[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)) )
399 if (
NULL == keyword_start)
401 keyword_start = upgrade_header + i;
403 keyword_end = upgrade_header + i + 1;
405 else if ((
' ' == c) || (
'\t' == c))
409 else if ((
',' == c) || (0 == c))
412 if (
NULL != keyword_start)
414 if (9 == (keyword_end - keyword_start) )
416 if ( ((
'W' == keyword_start[0]) || (
'w' == keyword_start[0])) &&
417 ((
'E' == keyword_start[1]) || (
'e' == keyword_start[1])) &&
418 ((
'B' == keyword_start[2]) || (
'b' == keyword_start[2])) &&
419 ((
'S' == keyword_start[3]) || (
's' == keyword_start[3])) &&
420 ((
'O' == keyword_start[4]) || (
'o' == keyword_start[4])) &&
421 ((
'C' == keyword_start[5]) || (
'c' == keyword_start[5])) &&
422 ((
'K' == keyword_start[6]) || (
'k' == keyword_start[6])) &&
423 ((
'E' == keyword_start[7]) || (
'e' == keyword_start[7])) &&
424 ((
'T' == keyword_start[8]) || (
't' == keyword_start[8])) )
435 keyword_start =
NULL;
456 if (
NULL == version_header)
464 if ((
'1' == version_header[0]) &&
465 (
'3' == version_header[1]) &&
466 (0 == version_header[2]))
480 char *sec_websocket_accept)
483 if (
NULL != sec_websocket_accept)
484 *sec_websocket_accept = 0;
487 if (
NULL == sec_websocket_accept)
491 if (
NULL == sec_websocket_key)
501 const char *suffix =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
502 int length = (int) strlen (sec_websocket_key);
512 const char *base64_encoding_table =
513 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
514 for (
int i = 0, j = 0; i < 20;)
516 uint32_t octet_a = i < 20 ? (
unsigned char) sha1[i++] : 0;
517 uint32_t octet_b = i < 20 ? (
unsigned char) sha1[i++] : 0;
518 uint32_t octet_c = i < 20 ? (
unsigned char) sha1[i++] : 0;
519 uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
521 sec_websocket_accept[j++] = base64_encoding_table[(triple >> 3 * 6) & 0x3F];
522 sec_websocket_accept[j++] = base64_encoding_table[(triple >> 2 * 6) & 0x3F];
523 sec_websocket_accept[j++] = base64_encoding_table[(triple >> 1 * 6) & 0x3F];
524 sec_websocket_accept[j++] = base64_encoding_table[(triple >> 0 * 6) & 0x3F];
527 sec_websocket_accept[27] =
'=';
528 sec_websocket_accept[28] = 0;
540 size_t max_payload_size)
560 size_t max_payload_size,
574 ((uint64_t) 0x7FFFFFFFFFFFFFFF < max_payload_size) ||
575 (
NULL == callback_malloc) ||
576 (
NULL == callback_realloc) ||
577 (
NULL == callback_free) ||
579 (
NULL == callback_rng)))
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;
594 ws_->malloc = callback_malloc;
595 ws_->realloc = callback_realloc;
596 ws_->free = callback_free;
597 ws_->cls_rng = cls_rng;
598 ws_->rng = callback_rng;
619 if (ws->data_payload)
620 ws->free (ws->data_payload);
621 if (ws->control_payload)
622 ws->free (ws->control_payload);
667 const char *streambuf,
668 size_t streambuf_len,
669 size_t *streambuf_read_len,
674 if (
NULL != streambuf_read_len)
675 *streambuf_read_len = 0;
678 if (
NULL != payload_len)
683 ((
NULL == streambuf) && (0 != streambuf_len)) ||
684 (
NULL == streambuf_read_len) ||
686 (
NULL == payload_len) )
697 while (current < streambuf_len)
699 switch (ws->decode_step)
707 char opcode = streambuf [current];
708 if (0 != (opcode & 0x70))
723 *streambuf_read_len = current;
726 switch (opcode & 0x0F)
729 if (0 == ws->data_type)
743 *streambuf_read_len = current;
763 *streambuf_read_len = current;
770 if (0 != ws->data_type)
784 *streambuf_read_len = current;
804 *streambuf_read_len = current;
812 if ((opcode & 0x80) == 0)
826 *streambuf_read_len = current;
853 *streambuf_read_len = current;
857 ws->frame_header [ws->frame_header_size++] = streambuf [current++];
866 char frame_len = streambuf [current];
867 char is_masked = (frame_len & 0x80);
888 *streambuf_read_len = current;
909 *streambuf_read_len = current;
913 if (126 <= frame_len)
915 if (0 != (ws->frame_header [0] & 0x08))
929 *streambuf_read_len = current;
950 *streambuf_read_len = current;
955 ws->frame_header [ws->frame_header_size++] = streambuf [current++];
957 if (126 == frame_len)
961 else if (127 == frame_len)
967 size_t size = (size_t) frame_len;
969 (ws->max_payload_size && (ws->max_payload_size < size)) )
983 *streambuf_read_len = current;
986 ws->payload_size = size;
995 *((uint32_t *) ws->mask_key) = 0;
1016 ws->frame_header [ws->frame_header_size++] = streambuf [current++];
1023 ws->frame_header [ws->frame_header_size++] = streambuf [current++];
1025 *((uint16_t *) &ws->frame_header [2]));
1041 *streambuf_read_len = current;
1045 (ws->max_payload_size && (ws->max_payload_size < size)) )
1060 *streambuf_read_len = current;
1063 ws->payload_size = size;
1064 if (0 != (ws->frame_header [1] & 0x80))
1072 *((uint32_t *) ws->mask_key) = 0;
1081 ws->frame_header [ws->frame_header_size++] = streambuf [current++];
1082 uint64_t size =
MHD_htonll (*((uint64_t *) &ws->frame_header [2]));
1083 if (0x7fffffffffffffff < size)
1099 *streambuf_read_len = current;
1117 *streambuf_read_len = current;
1121 (ws->max_payload_size && (ws->max_payload_size < size)) )
1136 *streambuf_read_len = current;
1139 ws->payload_size = (size_t) size;
1141 if (0 != (ws->frame_header [1] & 0x80))
1149 *((uint32_t *) ws->mask_key) = 0;
1157 ws->frame_header [ws->frame_header_size++] = streambuf [current++];
1158 *((uint32_t *) ws->mask_key) = *((uint32_t *) &ws->frame_header [ws->
1173 *streambuf_read_len = current;
1183 size_t bytes_needed = ws->payload_size - ws->payload_index;
1184 size_t bytes_remaining = streambuf_len - current;
1185 size_t bytes_to_take = bytes_needed < bytes_remaining ? bytes_needed :
1187 if (0 != bytes_to_take)
1189 size_t utf8_start = ws->payload_index;
1190 char *decode_payload = ws->decode_step ==
1192 ws->data_payload_start :
1193 ws->control_payload;
1197 &streambuf [current],
1199 *((uint32_t *) ws->mask_key),
1200 (
unsigned long) (ws->payload_index
1202 current += bytes_to_take;
1203 ws->payload_index += bytes_to_take;
1210 (2 < ws->payload_index)) )
1214 char *decode_payload_utf8;
1215 size_t bytes_to_check;
1216 size_t utf8_error_offset = 0;
1219 utf8_step = ws->data_utf8_step;
1220 decode_payload_utf8 = decode_payload + utf8_start;
1221 bytes_to_check = bytes_to_take;
1225 utf8_step = ws->control_utf8_step;
1233 utf8_error_offset = 2;
1235 decode_payload_utf8 = decode_payload + utf8_start;
1236 bytes_to_check = bytes_to_take - utf8_start;
1238 size_t utf8_check_offset = 0;
1242 &utf8_check_offset);
1246 ws->data_utf8_step = utf8_step;
1262 *streambuf_read_len = current - bytes_to_take
1263 + utf8_check_offset + utf8_error_offset;
1270 if (ws->payload_size == ws->payload_index)
1278 *streambuf_read_len = current;
1285 *streambuf_read_len = current;
1298 *streambuf_read_len = current;
1302 switch (ws->decode_step)
1306 if (ws->payload_size == ws->payload_index)
1314 *streambuf_read_len = current;
1320 *streambuf_read_len = current;
1330 size_t *payload_len)
1333 char opcode = ws->frame_header [0] & 0x0f;
1339 size_t new_size_total = ws->payload_size + ws->data_payload_size;
1340 if ((0 != ws->max_payload_size) && (ws->max_payload_size <
1360 char *new_buf =
NULL;
1361 if (0 != new_size_total)
1363 new_buf = ws->realloc (ws->data_payload, new_size_total + 1);
1364 if (
NULL == new_buf)
1368 new_buf [new_size_total] = 0;
1369 ws->data_payload_start = &new_buf[ws->data_payload_size];
1373 ws->data_payload_start = new_buf;
1375 ws->data_payload = new_buf;
1376 ws->data_payload_size = new_size_total;
1385 size_t new_size_total = ws->payload_size;
1386 char *new_buf =
NULL;
1387 if (0 != new_size_total)
1389 new_buf = ws->malloc (new_size_total + 1);
1390 if (
NULL == new_buf)
1394 new_buf [new_size_total] = 0;
1396 ws->data_payload = new_buf;
1397 ws->data_payload_start = new_buf;
1398 ws->data_payload_size = new_size_total;
1399 ws->data_type = opcode;
1409 size_t new_size_total = ws->payload_size;
1410 char *new_buf =
NULL;
1411 if (0 != new_size_total)
1413 new_buf = ws->malloc (new_size_total + 1);
1414 if (
NULL == new_buf)
1418 new_buf[new_size_total] = 0;
1420 ws->control_payload = new_buf;
1433 size_t *payload_len)
1437 (ws->frame_header [0] & 0x0F);
1438 char is_fin = ws->frame_header [0] & 0x80;
1445 char data_type = ws->data_type;
1451 *payload = ws->data_payload;
1452 *payload_len = ws->data_payload_size;
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;
1465 *payload = ws->control_payload;
1466 *payload_len = ws->payload_size;
1467 ws->control_payload = 0;
1469 ws->payload_index = 0;
1470 ws->frame_header_size = 0;
1471 return (ws->frame_header [0] & 0x0f);
1483 size_t given_utf8 = 0;
1484 switch (ws->data_utf8_step)
1506 size_t new_len = ws->data_payload_size - given_utf8;
1509 char *next_payload = ws->malloc (given_utf8 + 1);
1510 if (
NULL == next_payload)
1514 memcpy (next_payload,
1515 ws->data_payload_start + ws->payload_index - given_utf8,
1517 next_payload[given_utf8] = 0;
1519 ws->data_payload[new_len] = 0;
1520 *payload = ws->data_payload;
1521 *payload_len = new_len;
1522 ws->data_payload = next_payload;
1523 ws->data_payload_size = given_utf8;
1531 ws->payload_index = 0;
1532 ws->frame_header_size = 0;
1533 if (0 != is_continue)
1534 return ws->data_type | 0x20;
1536 return ws->data_type | 0x10;
1541 *payload = ws->data_payload;
1542 *payload_len = ws->data_payload_size;
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;
1549 if (0 != is_continue)
1550 return ws->data_type | 0x20;
1552 return ws->data_type | 0x10;
1560 ws->frame_header_size = 0;
1561 ws->payload_index = 0;
1573 unsigned short *reason_code,
1574 const char **reason_utf8,
1575 size_t *reason_utf8_len)
1578 if (
NULL != reason_code)
1580 if (
NULL != reason_utf8)
1581 *reason_utf8 =
NULL;
1582 if (
NULL != reason_utf8_len)
1583 *reason_utf8_len = 0;
1586 if ((
NULL == payload) && (0 != payload_len))
1588 if (1 == payload_len)
1590 if (125 < payload_len)
1594 if (2 > payload_len)
1596 if (
NULL != reason_code)
1601 if (
NULL != reason_code)
1602 *reason_code =
MHD_htons (*((uint16_t *) payload));
1606 if (2 >= payload_len)
1608 if (
NULL != reason_utf8)
1609 *reason_utf8 =
NULL;
1610 if (
NULL != reason_utf8_len)
1611 *reason_utf8_len = 0;
1615 if (
NULL != reason_utf8)
1616 *reason_utf8 = payload + 2;
1617 if (
NULL != reason_utf8_len)
1618 *reason_utf8_len = payload_len - 2;
1630 const char *payload_utf8,
1631 size_t payload_utf8_len,
1640 if (
NULL != frame_len)
1642 if ((
NULL != utf8_step) &&
1652 ((0 != payload_utf8_len) && (
NULL == payload_utf8)) ||
1654 (
NULL == frame_len) ||
1658 (
NULL == utf8_step)) )
1664 if ((uint64_t) 0x7FFFFFFFFFFFFFFF < (uint64_t) payload_utf8_len)
1697 const char *payload,
1706 if (
NULL != frame_len)
1711 ((0 != payload_len) && (
NULL == payload)) ||
1713 (
NULL == frame_len) ||
1721 if ((uint64_t) 0x7FFFFFFFFFFFFFFF < (uint64_t) payload_len)
1741 const char *payload,
1751 size_t total_len = overhead_len + payload_len;
1755 char *result = ws->malloc (total_len + 1);
1758 result [total_len] = 0;
1760 *frame_len = total_len;
1763 switch (fragmentation)
1766 *(result++) = 0x80 | opcode;
1769 *(result++) = opcode;
1780 if (126 > payload_len)
1782 *(result++) = is_masked | (
char) payload_len;
1784 else if (65536 > payload_len)
1786 *(result++) = is_masked | 126;
1787 *((uint16_t *) result) =
MHD_htons ((uint16_t) payload_len);
1792 *(result++) = is_masked | 127;
1793 *((uint64_t *) result) =
MHD_htonll ((uint64_t) payload_len);
1801 *(result++) = ((
char *) &mask)[0];
1802 *(result++) = ((
char *) &mask)[1];
1803 *(result++) = ((
char *) &mask)[2];
1804 *(result++) = ((
char *) &mask)[3];
1808 if (0 != payload_len)
1826 const char *payload,
1846 const char *payload,
1866 const char *payload,
1875 if (
NULL != frame_len)
1880 ((0 != payload_len) && (
NULL == payload)) ||
1882 (
NULL == frame_len) )
1888 if (125 < payload_len)
1894 size_t total_len = overhead_len + payload_len;
1898 char *result = ws->malloc (total_len + 1);
1901 result [total_len] = 0;
1903 *frame_len = total_len;
1906 *(result++) = 0x80 | opcode;
1909 *(result++) = is_masked | (
char) payload_len;
1914 *(result++) = ((
char *) &mask)[0];
1915 *(result++) = ((
char *) &mask)[1];
1916 *(result++) = ((
char *) &mask)[2];
1917 *(result++) = ((
char *) &mask)[3];
1921 if (0 != payload_len)
1939 unsigned short reason_code,
1940 const char *reason_utf8,
1941 size_t reason_utf8_len,
1948 if (
NULL != frame_len)
1953 ((0 != reason_utf8_len) && (
NULL == reason_utf8)) ||
1955 (
NULL == frame_len) ||
1957 (1000 > reason_code)) ||
1958 ((0 != reason_utf8_len) &&
1967 if (123 < reason_utf8_len)
1971 if (0 != reason_utf8_len)
1984 2 + reason_utf8_len : 0);
1986 size_t total_len = overhead_len + payload_len;
1990 char *result = ws->malloc (total_len + 1);
1993 result [total_len] = 0;
1995 *frame_len = total_len;
2001 *(result++) = is_masked | (
char) payload_len;
2006 *(result++) = ((
char *) &mask)[0];
2007 *(result++) = ((
char *) &mask)[1];
2008 *(result++) = ((
char *) &mask)[2];
2009 *(result++) = ((
char *) &mask)[3];
2013 if (0 != reason_code)
2016 uint16_t reason_code_nb =
MHD_htons (reason_code);
2018 (
const char *) &reason_code_nb,
2025 if (0 != reason_utf8_len)
2073 unsigned long mask_offset)
2080 memcpy (dst, src, len);
2086 *((uint32_t *) mask_) = mask;
2087 for (
size_t i = 0; i < len; ++i)
2089 dst[i] = src[i] ^ mask_[(i + mask_offset) & 3];
2105 int utf8_step_ = (
NULL != utf8_step) ? *utf8_step :
2108 for (
size_t i = 0; i < buf_len; ++i)
2110 unsigned char character = (
unsigned char) buf[i];
2114 if ((0x00 <= character) && (0x7F >= character))
2119 else if ((0xC2 <= character) && (0xDF >= character))
2124 else if (0xE0 == character)
2129 else if (0xED == character)
2134 else if (((0xE1 <= character) && (0xEC >= character)) ||
2135 ((0xEE <= character) && (0xEF >= character)) )
2140 else if (0xF0 == character)
2145 else if (0xF4 == character)
2150 else if ((0xF1 <= character) && (0xF3 >= character))
2158 if (
NULL != buf_offset)
2165 if ((0xA0 <= character) && (0xBF >= character))
2173 if (
NULL != buf_offset)
2180 if ((0x80 <= character) && (0x9F >= character))
2188 if (
NULL != buf_offset)
2195 if ((0x80 <= character) && (0xBF >= character))
2203 if (
NULL != buf_offset)
2210 if ((0x90 <= character) && (0xBF >= character))
2218 if (
NULL != buf_offset)
2225 if ((0x80 <= character) && (0x8F >= character))
2233 if (
NULL != buf_offset)
2240 if ((0x80 <= character) && (0xBF >= character))
2248 if (
NULL != buf_offset)
2255 if ((0x80 <= character) && (0xBF >= character))
2263 if (
NULL != buf_offset)
2275 if ((0x80 <= character) && (0xBF >= character))
2282 if (
NULL != buf_offset)
2290 if (
NULL != buf_offset)
2297 if (
NULL != utf8_step)
2298 *utf8_step = utf8_step_;
2299 if (
NULL != buf_offset)
2300 *buf_offset = buf_len;
2316 unsigned char mask_[4];
2317 if (
NULL != ws->rng)
2322 size_t encoded = ws->rng (ws->cls_rng,
2337 return *((uint32_t *) mask_);
2353 return ws->malloc (buf_len);
2370 return ws->realloc (buf, new_buf_len);
2399 uint16_t endian = 0x0001;
2401 if (((
char *) &endian)[0] == 0x01)
2404 ((
char *) &endian)[0] = ((
char *) &value)[1];
2405 ((
char *) &endian)[1] = ((
char *) &value)[0];
2423 uint64_t endian = 0x0000000000000001;
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)