commit ff13abc1c1d7d2b30d69d5c0bd4a237e1801c50b
parent 1fd9b3779f58e2f3385f9fdd5df8761fb991508e
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 16 Sep 2025 11:00:37 +0200
remove broken experimental code
Diffstat:
7 files changed, 0 insertions(+), 13651 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
@@ -9,11 +9,6 @@ SUBDIRS += testzzuf
endif
endif
-# Finally (last!) also build experimental lib...
-if HAVE_EXPERIMENTAL
-SUBDIRS += microhttpd_ws
-endif
-
if BUILD_EXAMPLES
SUBDIRS += examples
endif
diff --git a/src/microhttpd_ws/Makefile.am b/src/microhttpd_ws/Makefile.am
@@ -1,43 +0,0 @@
-# This Makefile.am is in the public domain
-AM_CPPFLAGS = \
- -I$(top_srcdir)/src/include \
- -I$(top_srcdir)/src/microhttpd
-
-AM_CFLAGS = $(HIDDEN_VISIBILITY_CFLAGS)
-
-$(top_builddir)/src/microhttpd/libmicrohttpd.la: $(top_builddir)/src/microhttpd/Makefile
- @echo ' cd $(top_builddir)/src/microhttpd && $(MAKE) $(AM_MAKEFLAGS) libmicrohttpd.la'; \
- $(am__cd) $(top_builddir)/src/microhttpd && $(MAKE) $(AM_MAKEFLAGS) libmicrohttpd.la
-
-noinst_DATA =
-MOSTLYCLEANFILES =
-
-SUBDIRS = .
-
-lib_LTLIBRARIES = \
- libmicrohttpd_ws.la
-libmicrohttpd_ws_la_SOURCES = \
- sha1.c sha1.h \
- mhd_websocket.c
-libmicrohttpd_ws_la_CPPFLAGS = \
- $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) \
- -DBUILDING_MHD_LIB=1
-libmicrohttpd_ws_la_CFLAGS = \
- $(AM_CFLAGS) $(MHD_LIB_CFLAGS)
-libmicrohttpd_ws_la_LDFLAGS = \
- $(MHD_LIB_LDFLAGS) \
- $(W32_MHD_LIB_LDFLAGS) \
- -version-info 0:0:0
-libmicrohttpd_ws_la_LIBADD = \
- $(MHD_LIBDEPS)
-
-TESTS = $(check_PROGRAMS)
-
-check_PROGRAMS = \
- test_websocket
-
-test_websocket_SOURCES = \
- test_websocket.c
-test_websocket_LDADD = \
- $(top_builddir)/src/microhttpd_ws/libmicrohttpd_ws.la \
- $(top_builddir)/src/microhttpd/libmicrohttpd.la
diff --git a/src/microhttpd_ws/mhd_websocket.c b/src/microhttpd_ws/mhd_websocket.c
@@ -1,2443 +0,0 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2021 David Gausmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-*/
-
-/**
- * @file microhttpd_ws/mhd_websocket.c
- * @brief Support for the websocket protocol
- * @author David Gausmann
- */
-#include "platform.h"
-#include "microhttpd.h"
-#include "microhttpd_ws.h"
-#include "sha1.h"
-
-struct MHD_WebSocketStream
-{
- /* The function pointer to malloc for payload (can be used to use different memory management) */
- MHD_WebSocketMallocCallback malloc;
- /* The function pointer to realloc for payload (can be used to use different memory management) */
- MHD_WebSocketReallocCallback realloc;
- /* The function pointer to free for payload (can be used to use different memory management) */
- MHD_WebSocketFreeCallback free;
- /* A closure for the random number generator (only used for client mode; usually not required) */
- void *cls_rng;
- /* The random number generator (only used for client mode; usually not required) */
- MHD_WebSocketRandomNumberGenerator rng;
- /* The flags specified upon initialization. It may alter the behavior of decoding/encoding */
- int flags;
- /* The current step for the decoder. 0 means start of a frame. */
- char decode_step;
- /* Specifies whether the stream is valid (1) or not (0),
- if a close frame has been received this is (-1) to indicate that no data frames are allowed anymore */
- char validity;
- /* The current step of the UTF-8 encoding check in the data payload */
- char data_utf8_step;
- /* The current step of the UTF-8 encoding check in the control payload */
- char control_utf8_step;
- /* if != 0 means that we expect a CONTINUATION frame */
- char data_type;
- /* The start of the current frame (may differ from data_payload for CONTINUATION frames) */
- char *data_payload_start;
- /* The buffer for the data frame */
- char *data_payload;
- /* The buffer for the control frame */
- char *control_payload;
- /* Configuration for the maximum allowed buffer size for payload data */
- size_t max_payload_size;
- /* The current frame header size */
- size_t frame_header_size;
- /* The current data payload size (can be greater than payload_size for fragmented frames) */
- size_t data_payload_size;
- /* The size of the payload of the current frame (control or data) */
- size_t payload_size;
- /* The processing offset to the start of the payload of the current frame (control or data) */
- size_t payload_index;
- /* The frame header of the current frame (control or data) */
- char frame_header[32];
- /* The mask key of the current frame (control or data); this is 0 if no masking used */
- char mask_key[4];
-};
-
-#define MHD_WEBSOCKET_FLAG_MASK_SERVERCLIENT MHD_WEBSOCKET_FLAG_CLIENT
-#define MHD_WEBSOCKET_FLAG_MASK_FRAGMENTATION \
- MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
-#define MHD_WEBSOCKET_FLAG_MASK_GENERATE_CLOSE_FRAMES \
- MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR
-#define MHD_WEBSOCKET_FLAG_MASK_ALL \
- (MHD_WEBSOCKET_FLAG_MASK_SERVERCLIENT \
- | MHD_WEBSOCKET_FLAG_MASK_FRAGMENTATION \
- | MHD_WEBSOCKET_FLAG_MASK_GENERATE_CLOSE_FRAMES)
-
-enum MHD_WebSocket_Opcode
-{
- MHD_WebSocket_Opcode_Continuation = 0x0,
- MHD_WebSocket_Opcode_Text = 0x1,
- MHD_WebSocket_Opcode_Binary = 0x2,
- MHD_WebSocket_Opcode_Close = 0x8,
- MHD_WebSocket_Opcode_Ping = 0x9,
- MHD_WebSocket_Opcode_Pong = 0xA
-};
-
-enum MHD_WebSocket_DecodeStep
-{
- MHD_WebSocket_DecodeStep_Start = 0,
- MHD_WebSocket_DecodeStep_Length1ofX = 1,
- MHD_WebSocket_DecodeStep_Length1of2 = 2,
- MHD_WebSocket_DecodeStep_Length2of2 = 3,
- MHD_WebSocket_DecodeStep_Length1of8 = 4,
- MHD_WebSocket_DecodeStep_Length2of8 = 5,
- MHD_WebSocket_DecodeStep_Length3of8 = 6,
- MHD_WebSocket_DecodeStep_Length4of8 = 7,
- MHD_WebSocket_DecodeStep_Length5of8 = 8,
- MHD_WebSocket_DecodeStep_Length6of8 = 9,
- MHD_WebSocket_DecodeStep_Length7of8 = 10,
- MHD_WebSocket_DecodeStep_Length8of8 = 11,
- MHD_WebSocket_DecodeStep_Mask1Of4 = 12,
- MHD_WebSocket_DecodeStep_Mask2Of4 = 13,
- MHD_WebSocket_DecodeStep_Mask3Of4 = 14,
- MHD_WebSocket_DecodeStep_Mask4Of4 = 15,
- MHD_WebSocket_DecodeStep_HeaderCompleted = 16,
- MHD_WebSocket_DecodeStep_PayloadOfDataFrame = 17,
- MHD_WebSocket_DecodeStep_PayloadOfControlFrame = 18,
- MHD_WebSocket_DecodeStep_BrokenStream = 99
-};
-
-enum MHD_WebSocket_UTF8Result
-{
- MHD_WebSocket_UTF8Result_Invalid = 0,
- MHD_WebSocket_UTF8Result_Valid = 1,
- MHD_WebSocket_UTF8Result_Incomplete = 2
-};
-
-static void
-MHD_websocket_copy_payload (char *dst,
- const char *src,
- size_t len,
- uint32_t mask,
- unsigned long mask_offset);
-
-static int
-MHD_websocket_check_utf8 (const char *buf,
- size_t buf_len,
- int *utf8_step,
- size_t *buf_offset);
-
-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);
-
-static char
-MHD_websocket_encode_is_masked (struct MHD_WebSocketStream *ws);
-static char
-MHD_websocket_encode_overhead_size (struct MHD_WebSocketStream *ws,
- 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);
-
-static uint32_t
-MHD_websocket_generate_mask (struct MHD_WebSocketStream *ws);
-
-static uint16_t
-MHD_htons (uint16_t value);
-
-static uint64_t
-MHD_htonll (uint64_t value);
-
-
-/**
- * Checks whether the HTTP version is 1.1 or above.
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_check_http_version (const char *http_version)
-{
- /* validate parameters */
- if (NULL == http_version)
- {
- /* Like with the other check routines, */
- /* NULL is threated as "value not given" and not as parameter error */
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
-
- /* Check whether the version has a valid format */
- /* RFC 1945 3.1: The format must be "HTTP/x.x" where x is */
- /* any digit and must appear at least once */
- if (('H' != http_version[0]) ||
- ('T' != http_version[1]) ||
- ('T' != http_version[2]) ||
- ('P' != http_version[3]) ||
- ('/' != http_version[4]))
- {
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
-
- /* Find the major and minor part of the version */
- /* RFC 1945 3.1: Both numbers must be threated as separate integers. */
- /* Leading zeros must be ignored and both integers may have multiple digits */
- const char *major = NULL;
- const char *dot = NULL;
- size_t i = 5;
- for (;;)
- {
- char c = http_version[i];
- if (('0' <= c) && ('9' >= c))
- {
- if ((NULL == major) ||
- ((http_version + i == major + 1) && ('0' == *major)) )
- {
- major = http_version + i;
- }
- ++i;
- }
- else if ('.' == http_version[i])
- {
- dot = http_version + i;
- ++i;
- break;
- }
- else
- {
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
- }
- const char *minor = NULL;
- const char *end = NULL;
- for (;;)
- {
- char c = http_version[i];
- if (('0' <= c) && ('9' >= c))
- {
- if ((NULL == minor) ||
- ((http_version + i == minor + 1) && ('0' == *minor)) )
- {
- minor = http_version + i;
- }
- ++i;
- }
- else if (0 == c)
- {
- end = http_version + i;
- break;
- }
- else
- {
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
- }
- if ((NULL == major) || (NULL == dot) || (NULL == minor) || (NULL == end))
- {
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
- if ((2 <= dot - major) || ('2' <= *major) ||
- (('1' == *major) && ((2 <= end - minor) || ('1' <= *minor))) )
- {
- return MHD_WEBSOCKET_STATUS_OK;
- }
-
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
-}
-
-
-/**
- * Checks whether the "Connection" request header has the 'Upgrade' token.
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_check_connection_header (const char *connection_header)
-{
- /* validate parameters */
- if (NULL == connection_header)
- {
- /* To be compatible with the return value */
- /* of MHD_lookup_connection_value, */
- /* NULL is threated as "value not given" and not as parameter error */
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
-
- /* Check whether the Connection includes an Upgrade token */
- /* RFC 7230 6.1: Multiple tokens may appear. */
- /* RFC 7230 3.2.6: Tokens are comma separated */
- const char *token_start = NULL;
- const char *token_end = NULL;
- for (size_t i = 0; ; ++i)
- {
- char c = connection_header[i];
-
- /* RFC 7230 3.2.6: The list of allowed characters is a token is: */
- /* "!" / "#" / "$" / "%" / "&" / "'" / "*" / */
- /* "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" */
- /* DIGIT / ALPHA */
- if (('!' == c) || ('#' == c) || ('$' == c) || ('%' == c) ||
- ('&' == c) || ('\'' == c) || ('*' == c) ||
- ('+' == c) || ('-' == c) || ('.' == c) || ('^' == c) ||
- ('_' == c) || ('`' == c) || ('|' == c) || ('~' == c) ||
- (('0' <= c) && ('9' >= c)) ||
- (('A' <= c) && ('Z' >= c)) || (('a' <= c) && ('z' >= c)) )
- {
- /* This is a valid token character */
- if (NULL == token_start)
- {
- token_start = connection_header + i;
- }
- token_end = connection_header + i + 1;
- }
- else if ((' ' == c) || ('\t' == c))
- {
- /* White-spaces around tokens will be ignored */
- }
- else if ((',' == c) || (0 == c))
- {
- /* Check the token (case-insensitive) */
- if (NULL != token_start)
- {
- if (7 == (token_end - token_start) )
- {
- if ( (('U' == token_start[0]) || ('u' == token_start[0])) &&
- (('P' == token_start[1]) || ('p' == token_start[1])) &&
- (('G' == token_start[2]) || ('g' == token_start[2])) &&
- (('R' == token_start[3]) || ('r' == token_start[3])) &&
- (('A' == token_start[4]) || ('a' == token_start[4])) &&
- (('D' == token_start[5]) || ('d' == token_start[5])) &&
- (('E' == token_start[6]) || ('e' == token_start[6])) )
- {
- /* The token equals to "Upgrade" */
- return MHD_WEBSOCKET_STATUS_OK;
- }
- }
- }
- if (0 == c)
- {
- break;
- }
- token_start = NULL;
- token_end = NULL;
- }
- else
- {
- /* RFC 7230 3.2.6: Other characters are not allowed */
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
- }
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
-}
-
-
-/**
- * Checks whether the "Upgrade" request header has the "websocket" keyword.
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_check_upgrade_header (const char *upgrade_header)
-{
- /* validate parameters */
- if (NULL == upgrade_header)
- {
- /* To be compatible with the return value */
- /* of MHD_lookup_connection_value, */
- /* NULL is threated as "value not given" and not as parameter error */
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
-
- /* Check whether the Connection includes an Upgrade token */
- /* RFC 7230 6.1: Multiple tokens may appear. */
- /* RFC 7230 3.2.6: Tokens are comma separated */
- const char *keyword_start = NULL;
- const char *keyword_end = NULL;
- for (size_t i = 0; ; ++i)
- {
- char c = upgrade_header[i];
-
- /* RFC 7230 3.2.6: The list of allowed characters is a token is: */
- /* "!" / "#" / "$" / "%" / "&" / "'" / "*" / */
- /* "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" */
- /* DIGIT / ALPHA */
- /* We also allow "/" here as the sub-delimiter for the protocol version */
- if (('!' == c) || ('#' == c) || ('$' == c) || ('%' == c) ||
- ('&' == c) || ('\'' == c) || ('*' == c) ||
- ('+' == c) || ('-' == c) || ('.' == c) || ('^' == c) ||
- ('_' == c) || ('`' == c) || ('|' == c) || ('~' == c) ||
- ('/' == c) ||
- (('0' <= c) && ('9' >= c)) ||
- (('A' <= c) && ('Z' >= c)) || (('a' <= c) && ('z' >= c)) )
- {
- /* This is a valid token character */
- if (NULL == keyword_start)
- {
- keyword_start = upgrade_header + i;
- }
- keyword_end = upgrade_header + i + 1;
- }
- else if ((' ' == c) || ('\t' == c))
- {
- /* White-spaces around tokens will be ignored */
- }
- else if ((',' == c) || (0 == c))
- {
- /* Check the token (case-insensitive) */
- if (NULL != keyword_start)
- {
- if (9 == (keyword_end - keyword_start) )
- {
- if ( (('W' == keyword_start[0]) || ('w' == keyword_start[0])) &&
- (('E' == keyword_start[1]) || ('e' == keyword_start[1])) &&
- (('B' == keyword_start[2]) || ('b' == keyword_start[2])) &&
- (('S' == keyword_start[3]) || ('s' == keyword_start[3])) &&
- (('O' == keyword_start[4]) || ('o' == keyword_start[4])) &&
- (('C' == keyword_start[5]) || ('c' == keyword_start[5])) &&
- (('K' == keyword_start[6]) || ('k' == keyword_start[6])) &&
- (('E' == keyword_start[7]) || ('e' == keyword_start[7])) &&
- (('T' == keyword_start[8]) || ('t' == keyword_start[8])) )
- {
- /* The keyword equals to "websocket" */
- return MHD_WEBSOCKET_STATUS_OK;
- }
- }
- }
- if (0 == c)
- {
- break;
- }
- keyword_start = NULL;
- keyword_end = NULL;
- }
- else
- {
- /* RFC 7230 3.2.6: Other characters are not allowed */
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
- }
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
-}
-
-
-/**
- * Checks whether the "Sec-WebSocket-Version" request header
- * equals to "13"
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_check_version_header (const char *version_header)
-{
- /* validate parameters */
- if (NULL == version_header)
- {
- /* To be compatible with the return value */
- /* of MHD_lookup_connection_value, */
- /* NULL is threated as "value not given" and not as parameter error */
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
-
- if (('1' == version_header[0]) &&
- ('3' == version_header[1]) &&
- (0 == version_header[2]))
- {
- /* The version equals to "13" */
- return MHD_WEBSOCKET_STATUS_OK;
- }
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
-}
-
-
-/**
- * Creates the response for the Sec-WebSocket-Accept header
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_create_accept_header (const char *sec_websocket_key,
- char *sec_websocket_accept)
-{
- /* initialize output variables for errors cases */
- if (NULL != sec_websocket_accept)
- *sec_websocket_accept = 0;
-
- /* validate parameters */
- if (NULL == sec_websocket_accept)
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
- if (NULL == sec_websocket_key)
- {
- /* NULL is not a parameter error, */
- /* because MHD_lookup_connection_value returns NULL */
- /* if the header wasn't found */
- return MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER;
- }
-
- /* build SHA1 hash of the given key and the UUID appended */
- char sha1[20];
- const char *suffix = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- int length = (int) strlen (sec_websocket_key);
- struct sha1_ctx ctx;
- MHD_SHA1_init (&ctx);
- MHD_SHA1_update (&ctx, (const uint8_t *) sec_websocket_key, length);
- MHD_SHA1_update (&ctx, (const uint8_t *) suffix, 36);
- MHD_SHA1_finish (&ctx, (uint8_t *) sha1);
-
- /* base64 encode that SHA1 hash */
- /* (simple algorithm here; SHA1 has always 20 bytes, */
- /* which will always result in a 28 bytes base64 hash) */
- const char *base64_encoding_table =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- for (int i = 0, j = 0; i < 20;)
- {
- uint32_t octet_a = i < 20 ? (unsigned char) sha1[i++] : 0;
- uint32_t octet_b = i < 20 ? (unsigned char) sha1[i++] : 0;
- uint32_t octet_c = i < 20 ? (unsigned char) sha1[i++] : 0;
- uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
-
- sec_websocket_accept[j++] = base64_encoding_table[(triple >> 3 * 6) & 0x3F];
- sec_websocket_accept[j++] = base64_encoding_table[(triple >> 2 * 6) & 0x3F];
- sec_websocket_accept[j++] = base64_encoding_table[(triple >> 1 * 6) & 0x3F];
- sec_websocket_accept[j++] = base64_encoding_table[(triple >> 0 * 6) & 0x3F];
-
- }
- sec_websocket_accept[27] = '=';
- sec_websocket_accept[28] = 0;
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Initializes a new websocket stream
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_stream_init (struct MHD_WebSocketStream **ws,
- int flags,
- size_t max_payload_size)
-{
- return MHD_websocket_stream_init2 (ws,
- flags,
- max_payload_size,
- malloc,
- realloc,
- free,
- NULL,
- NULL);
-}
-
-
-/**
- * Initializes a new websocket stream with
- * additional parameters for allocation functions
- */
-_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)
-{
- /* initialize output variables for errors cases */
- if (NULL != ws)
- *ws = NULL;
-
- /* validate parameters */
- if ((NULL == ws) ||
- (0 != (flags & ~MHD_WEBSOCKET_FLAG_MASK_ALL)) ||
- ((uint64_t) 0x7FFFFFFFFFFFFFFF < max_payload_size) ||
- (NULL == callback_malloc) ||
- (NULL == callback_realloc) ||
- (NULL == callback_free) ||
- ((0 != (flags & MHD_WEBSOCKET_FLAG_CLIENT)) &&
- (NULL == callback_rng)))
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
-
- /* allocate stream */
- struct MHD_WebSocketStream *ws_ = (struct MHD_WebSocketStream *) malloc (
- sizeof (struct MHD_WebSocketStream));
- if (NULL == ws_)
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
-
- /* initialize stream */
- memset (ws_, 0, sizeof (struct MHD_WebSocketStream));
- ws_->flags = flags;
- ws_->max_payload_size = max_payload_size;
- ws_->malloc = callback_malloc;
- ws_->realloc = callback_realloc;
- ws_->free = callback_free;
- ws_->cls_rng = cls_rng;
- ws_->rng = callback_rng;
- ws_->validity = MHD_WEBSOCKET_VALIDITY_VALID;
-
- /* return stream */
- *ws = ws_;
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Frees a previously allocated websocket stream
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_stream_free (struct MHD_WebSocketStream *ws)
-{
- /* validate parameters */
- if (NULL == ws)
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
-
- /* free allocated payload data */
- if (ws->data_payload)
- ws->free (ws->data_payload);
- if (ws->control_payload)
- ws->free (ws->control_payload);
-
- /* free the stream */
- free (ws);
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Invalidates a websocket stream (no more decoding possible)
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
-MHD_websocket_stream_invalidate (struct MHD_WebSocketStream *ws)
-{
- /* validate parameters */
- if (NULL == ws)
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
-
- /* invalidate stream */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Returns whether a websocket stream is valid
- */
-_MHD_EXTERN enum MHD_WEBSOCKET_VALIDITY
-MHD_websocket_stream_is_valid (struct MHD_WebSocketStream *ws)
-{
- /* validate parameters */
- if (NULL == ws)
- return MHD_WEBSOCKET_VALIDITY_INVALID;
-
- return ws->validity;
-}
-
-
-/**
- * Decodes incoming data to a websocket frame
- */
-_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)
-{
- /* initialize output variables for errors cases */
- if (NULL != streambuf_read_len)
- *streambuf_read_len = 0;
- if (NULL != payload)
- *payload = NULL;
- if (NULL != payload_len)
- *payload_len = 0;
-
- /* validate parameters */
- if ((NULL == ws) ||
- ((NULL == streambuf) && (0 != streambuf_len)) ||
- (NULL == streambuf_read_len) ||
- (NULL == payload) ||
- (NULL == payload_len) )
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
-
- /* validate stream validity */
- if (MHD_WEBSOCKET_VALIDITY_INVALID == ws->validity)
- return MHD_WEBSOCKET_STATUS_STREAM_BROKEN;
-
- /* decode loop */
- size_t current = 0;
- while (current < streambuf_len)
- {
- switch (ws->decode_step)
- {
- /* start of frame */
- case MHD_WebSocket_DecodeStep_Start:
- {
- /* The first byte contains the opcode, the fin flag and three reserved bits */
- if (MHD_WEBSOCKET_VALIDITY_INVALID != ws->validity)
- {
- char opcode = streambuf [current];
- if (0 != (opcode & 0x70))
- {
- /* RFC 6455 5.2 RSV1-3: If a reserved flag is set */
- /* (while it isn't specified by an extension) the communication must fail. */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- switch (opcode & 0x0F)
- {
- case MHD_WebSocket_Opcode_Continuation:
- if (0 == ws->data_type)
- {
- /* RFC 6455 5.4: Continuation frame without previous data frame */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- if (MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES ==
- ws->validity)
- {
- /* RFC 6455 5.5.1: After a close frame has been sent, */
- /* no data frames may be sent (so we don't accept data frames */
- /* for decoding anymore) */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- break;
-
- case MHD_WebSocket_Opcode_Text:
- case MHD_WebSocket_Opcode_Binary:
- if (0 != ws->data_type)
- {
- /* RFC 6455 5.4: Continuation expected, but new data frame */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- if (MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES ==
- ws->validity)
- {
- /* RFC 6455 5.5.1: After a close frame has been sent, */
- /* no data frames may be sent (so we don't accept data frames */
- /* for decoding anymore) */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- break;
-
- case MHD_WebSocket_Opcode_Close:
- case MHD_WebSocket_Opcode_Ping:
- case MHD_WebSocket_Opcode_Pong:
- if ((opcode & 0x80) == 0)
- {
- /* RFC 6455 5.4: Control frames may not be fragmented */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- if (MHD_WebSocket_Opcode_Close == (opcode & 0x0F))
- {
- /* RFC 6455 5.5.1: After a close frame has been sent, */
- /* no data frames may be sent (so we don't accept data frames */
- /* for decoding anymore) */
- ws->validity =
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES;
- }
- break;
-
- default:
- /* RFC 6455 5.2 OPCODE: Only six opcodes are specified. */
- /* All other are invalid in version 13 of the protocol. */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- }
- ws->frame_header [ws->frame_header_size++] = streambuf [current++];
- ws->decode_step = MHD_WebSocket_DecodeStep_Length1ofX;
- }
- break;
-
- case MHD_WebSocket_DecodeStep_Length1ofX:
- {
- /* The second byte specifies whether the data is masked and the size */
- /* (the client MUST mask the payload, the server MUST NOT mask the payload) */
- char frame_len = streambuf [current];
- char is_masked = (frame_len & 0x80);
- frame_len &= 0x7f;
- if (MHD_WEBSOCKET_VALIDITY_INVALID != ws->validity)
- {
- if (0 != is_masked)
- {
- if (MHD_WEBSOCKET_FLAG_CLIENT == (ws->flags
- & MHD_WEBSOCKET_FLAG_CLIENT))
- {
- /* RFC 6455 5.1: All frames from the server must be unmasked */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- }
- else
- {
- if (MHD_WEBSOCKET_FLAG_SERVER == (ws->flags
- & MHD_WEBSOCKET_FLAG_CLIENT))
- {
- /* RFC 6455 5.1: All frames from the client must be masked */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- }
- if (126 <= frame_len)
- {
- if (0 != (ws->frame_header [0] & 0x08))
- {
- /* RFC 6455 5.5: Control frames may not have more payload than 125 bytes */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- }
- if (1 == frame_len)
- {
- if (MHD_WebSocket_Opcode_Close == (ws->frame_header [0] & 0x0F))
- {
- /* RFC 6455 5.5.1: The close frame must have at least */
- /* two bytes of payload if payload is used */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- }
- }
- ws->frame_header [ws->frame_header_size++] = streambuf [current++];
-
- if (126 == frame_len)
- {
- ws->decode_step = MHD_WebSocket_DecodeStep_Length1of2;
- }
- else if (127 == frame_len)
- {
- ws->decode_step = MHD_WebSocket_DecodeStep_Length1of8;
- }
- else
- {
- size_t size = (size_t) frame_len;
- if ((SIZE_MAX < size) ||
- (ws->max_payload_size && (ws->max_payload_size < size)) )
- {
- /* RFC 6455 7.4.1 1009: If the message is too big to process, we may close the connection */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_MAXIMUM_ALLOWED_PAYLOAD_SIZE_EXCEEDED,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
- }
- ws->payload_size = size;
- if (0 != is_masked)
- {
- /* with mask */
- ws->decode_step = MHD_WebSocket_DecodeStep_Mask1Of4;
- }
- else
- {
- /* without mask */
- *((uint32_t *) ws->mask_key) = 0;
- ws->decode_step = MHD_WebSocket_DecodeStep_HeaderCompleted;
- }
- }
- }
- break;
-
- /* Payload size first byte of 2 bytes */
- case MHD_WebSocket_DecodeStep_Length1of2:
- /* Payload size first 7 bytes of 8 bytes */
- case MHD_WebSocket_DecodeStep_Length1of8:
- case MHD_WebSocket_DecodeStep_Length2of8:
- case MHD_WebSocket_DecodeStep_Length3of8:
- case MHD_WebSocket_DecodeStep_Length4of8:
- case MHD_WebSocket_DecodeStep_Length5of8:
- case MHD_WebSocket_DecodeStep_Length6of8:
- case MHD_WebSocket_DecodeStep_Length7of8:
- /* Mask first 3 bytes of 4 bytes */
- case MHD_WebSocket_DecodeStep_Mask1Of4:
- case MHD_WebSocket_DecodeStep_Mask2Of4:
- case MHD_WebSocket_DecodeStep_Mask3Of4:
- ws->frame_header [ws->frame_header_size++] = streambuf [current++];
- ++ws->decode_step;
- break;
-
- /* 2 byte length finished */
- case MHD_WebSocket_DecodeStep_Length2of2:
- {
- ws->frame_header [ws->frame_header_size++] = streambuf [current++];
- size_t size = (size_t) MHD_htons (
- *((uint16_t *) &ws->frame_header [2]));
- if (125 >= size)
- {
- /* RFC 6455 5.2 Payload length: The minimal number of bytes */
- /* must be used for the length */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- if ((SIZE_MAX < size) ||
- (ws->max_payload_size && (ws->max_payload_size < size)) )
- {
- /* RFC 6455 7.4.1 1009: If the message is too big to process, */
- /* we may close the connection */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_MAXIMUM_ALLOWED_PAYLOAD_SIZE_EXCEEDED,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
- }
- ws->payload_size = size;
- if (0 != (ws->frame_header [1] & 0x80))
- {
- /* with mask */
- ws->decode_step = MHD_WebSocket_DecodeStep_Mask1Of4;
- }
- else
- {
- /* without mask */
- *((uint32_t *) ws->mask_key) = 0;
- ws->decode_step = MHD_WebSocket_DecodeStep_HeaderCompleted;
- }
- }
- break;
-
- /* 8 byte length finished */
- case MHD_WebSocket_DecodeStep_Length8of8:
- {
- ws->frame_header [ws->frame_header_size++] = streambuf [current++];
- uint64_t size = MHD_htonll (*((uint64_t *) &ws->frame_header [2]));
- if (0x7fffffffffffffff < size)
- {
- /* RFC 6455 5.2 frame-payload-length-63: The length may */
- /* not exceed 0x7fffffffffffffff */
- ws->decode_step = MHD_WebSocket_DecodeStep_BrokenStream;
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- if (65535 >= size)
- {
- /* RFC 6455 5.2 Payload length: The minimal number of bytes */
- /* must be used for the length */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- }
- if ((SIZE_MAX < size) ||
- (ws->max_payload_size && (ws->max_payload_size < size)) )
- {
- /* RFC 6455 7.4.1 1009: If the message is too big to process, */
- /* we may close the connection */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_MAXIMUM_ALLOWED_PAYLOAD_SIZE_EXCEEDED,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
- }
- ws->payload_size = (size_t) size;
-
- if (0 != (ws->frame_header [1] & 0x80))
- {
- /* with mask */
- ws->decode_step = MHD_WebSocket_DecodeStep_Mask1Of4;
- }
- else
- {
- /* without mask */
- *((uint32_t *) ws->mask_key) = 0;
- ws->decode_step = MHD_WebSocket_DecodeStep_HeaderCompleted;
- }
- }
- break;
-
- /* mask finished */
- case MHD_WebSocket_DecodeStep_Mask4Of4:
- ws->frame_header [ws->frame_header_size++] = streambuf [current++];
- *((uint32_t *) ws->mask_key) = *((uint32_t *) &ws->frame_header [ws->
- frame_header_size
- - 4]);
- ws->decode_step = MHD_WebSocket_DecodeStep_HeaderCompleted;
- break;
-
- /* header finished */
- case MHD_WebSocket_DecodeStep_HeaderCompleted:
- /* return or assign either to data or control */
- {
- int ret = MHD_websocket_decode_header_complete (ws,
- payload,
- payload_len);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- *streambuf_read_len = current;
- return ret;
- }
- }
- break;
-
- /* payload data */
- case MHD_WebSocket_DecodeStep_PayloadOfDataFrame:
- case MHD_WebSocket_DecodeStep_PayloadOfControlFrame:
- {
- size_t bytes_needed = ws->payload_size - ws->payload_index;
- size_t bytes_remaining = streambuf_len - current;
- size_t bytes_to_take = bytes_needed < bytes_remaining ? bytes_needed :
- bytes_remaining;
- if (0 != bytes_to_take)
- {
- size_t utf8_start = ws->payload_index;
- char *decode_payload = ws->decode_step ==
- MHD_WebSocket_DecodeStep_PayloadOfDataFrame ?
- ws->data_payload_start :
- ws->control_payload;
-
- /* copy the new payload data (with unmasking if necessary */
- MHD_websocket_copy_payload (decode_payload + ws->payload_index,
- &streambuf [current],
- bytes_to_take,
- *((uint32_t *) ws->mask_key),
- (unsigned long) (ws->payload_index
- & 0x03));
- current += bytes_to_take;
- ws->payload_index += bytes_to_take;
- if (((MHD_WebSocket_DecodeStep_PayloadOfDataFrame ==
- ws->decode_step) &&
- (MHD_WebSocket_Opcode_Text == ws->data_type)) ||
- ((MHD_WebSocket_DecodeStep_PayloadOfControlFrame ==
- ws->decode_step) &&
- (MHD_WebSocket_Opcode_Close == (ws->frame_header [0] & 0x0f)) &&
- (2 < ws->payload_index)) )
- {
- /* RFC 6455 8.1: We need to check the UTF-8 validity */
- int utf8_step;
- char *decode_payload_utf8;
- size_t bytes_to_check;
- size_t utf8_error_offset = 0;
- if (MHD_WebSocket_DecodeStep_PayloadOfDataFrame == ws->decode_step)
- {
- utf8_step = ws->data_utf8_step;
- decode_payload_utf8 = decode_payload + utf8_start;
- bytes_to_check = bytes_to_take;
- }
- else
- {
- utf8_step = ws->control_utf8_step;
- if ((MHD_WebSocket_Opcode_Close == (ws->frame_header [0]
- & 0x0f)) &&
- (2 > utf8_start) )
- {
- /* The first two bytes of the close frame are binary content and */
- /* must be skipped in the UTF-8 check */
- utf8_start = 2;
- utf8_error_offset = 2;
- }
- decode_payload_utf8 = decode_payload + utf8_start;
- bytes_to_check = bytes_to_take - utf8_start;
- }
- size_t utf8_check_offset = 0;
- int utf8_result = MHD_websocket_check_utf8 (decode_payload_utf8,
- bytes_to_check,
- &utf8_step,
- &utf8_check_offset);
- if (MHD_WebSocket_UTF8Result_Invalid != utf8_result)
- {
- /* memorize current validity check step to continue later */
- ws->data_utf8_step = utf8_step;
- }
- else
- {
- /* RFC 6455 8.1: We must fail on broken UTF-8 sequence */
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_MALFORMED_UTF8,
- 0,
- 0,
- payload,
- payload_len);
- }
- *streambuf_read_len = current - bytes_to_take
- + utf8_check_offset + utf8_error_offset;
- return MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR;
- }
- }
- }
- }
-
- if (ws->payload_size == ws->payload_index)
- {
- /* all payload data of the current frame has been received */
- int ret = MHD_websocket_decode_payload_complete (ws,
- payload,
- payload_len);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- *streambuf_read_len = current;
- return ret;
- }
- }
- break;
-
- case MHD_WebSocket_DecodeStep_BrokenStream:
- *streambuf_read_len = current;
- return MHD_WEBSOCKET_STATUS_STREAM_BROKEN;
- }
- }
-
- /* Special treatment for zero payload length messages */
- if (MHD_WebSocket_DecodeStep_HeaderCompleted == ws->decode_step)
- {
- int ret = MHD_websocket_decode_header_complete (ws,
- payload,
- payload_len);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- *streambuf_read_len = current;
- return ret;
- }
- }
- switch (ws->decode_step)
- {
- case MHD_WebSocket_DecodeStep_PayloadOfDataFrame:
- case MHD_WebSocket_DecodeStep_PayloadOfControlFrame:
- if (ws->payload_size == ws->payload_index)
- {
- /* all payload data of the current frame has been received */
- int ret = MHD_websocket_decode_payload_complete (ws,
- payload,
- payload_len);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- *streambuf_read_len = current;
- return ret;
- }
- }
- break;
- }
- *streambuf_read_len = current;
-
- /* more data needed */
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-static enum MHD_WEBSOCKET_STATUS
-MHD_websocket_decode_header_complete (struct MHD_WebSocketStream *ws,
- char **payload,
- size_t *payload_len)
-{
- /* assign either to data or control */
- char opcode = ws->frame_header [0] & 0x0f;
- switch (opcode)
- {
- case MHD_WebSocket_Opcode_Continuation:
- {
- /* validate payload size */
- size_t new_size_total = ws->payload_size + ws->data_payload_size;
- if ((0 != ws->max_payload_size) && (ws->max_payload_size <
- new_size_total) )
- {
- /* RFC 6455 7.4.1 1009: If the message is too big to process, */
- /* we may close the connection */
- ws->decode_step = MHD_WebSocket_DecodeStep_BrokenStream;
- ws->validity = MHD_WEBSOCKET_VALIDITY_INVALID;
- if (0 != (ws->flags
- & MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR))
- {
- MHD_websocket_encode_close (ws,
- MHD_WEBSOCKET_CLOSEREASON_MAXIMUM_ALLOWED_PAYLOAD_SIZE_EXCEEDED,
- 0,
- 0,
- payload,
- payload_len);
- }
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
- }
- /* allocate buffer for continued data frame */
- char *new_buf = NULL;
- if (0 != new_size_total)
- {
- new_buf = ws->realloc (ws->data_payload, new_size_total + 1);
- if (NULL == new_buf)
- {
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
- }
- new_buf [new_size_total] = 0;
- ws->data_payload_start = &new_buf[ws->data_payload_size];
- }
- else
- {
- ws->data_payload_start = new_buf;
- }
- ws->data_payload = new_buf;
- ws->data_payload_size = new_size_total;
- }
- ws->decode_step = MHD_WebSocket_DecodeStep_PayloadOfDataFrame;
- break;
-
- case MHD_WebSocket_Opcode_Text:
- case MHD_WebSocket_Opcode_Binary:
- /* allocate buffer for data frame */
- {
- size_t new_size_total = ws->payload_size;
- char *new_buf = NULL;
- if (0 != new_size_total)
- {
- new_buf = ws->malloc (new_size_total + 1);
- if (NULL == new_buf)
- {
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
- }
- new_buf [new_size_total] = 0;
- }
- ws->data_payload = new_buf;
- ws->data_payload_start = new_buf;
- ws->data_payload_size = new_size_total;
- ws->data_type = opcode;
- }
- ws->decode_step = MHD_WebSocket_DecodeStep_PayloadOfDataFrame;
- break;
-
- case MHD_WebSocket_Opcode_Close:
- case MHD_WebSocket_Opcode_Ping:
- case MHD_WebSocket_Opcode_Pong:
- /* allocate buffer for control frame */
- {
- size_t new_size_total = ws->payload_size;
- char *new_buf = NULL;
- if (0 != new_size_total)
- {
- new_buf = ws->malloc (new_size_total + 1);
- if (NULL == new_buf)
- {
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
- }
- new_buf[new_size_total] = 0;
- }
- ws->control_payload = new_buf;
- }
- ws->decode_step = MHD_WebSocket_DecodeStep_PayloadOfControlFrame;
- break;
- }
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-static enum MHD_WEBSOCKET_STATUS
-MHD_websocket_decode_payload_complete (struct MHD_WebSocketStream *ws,
- char **payload,
- size_t *payload_len)
-{
- /* all payload data of the current frame has been received */
- char is_continue = MHD_WebSocket_Opcode_Continuation ==
- (ws->frame_header [0] & 0x0F);
- char is_fin = ws->frame_header [0] & 0x80;
- if (0 != is_fin)
- {
- /* the frame is complete */
- if (MHD_WebSocket_DecodeStep_PayloadOfDataFrame == ws->decode_step)
- {
- /* data frame */
- char data_type = ws->data_type;
- if ((0 != (ws->flags & MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS)) &&
- (0 != is_continue))
- {
- data_type |= 0x40; /* mark as last fragment */
- }
- *payload = ws->data_payload;
- *payload_len = ws->data_payload_size;
- ws->data_payload = 0;
- ws->data_payload_start = 0;
- ws->data_payload_size = 0;
- ws->decode_step = MHD_WebSocket_DecodeStep_Start;
- ws->payload_index = 0;
- ws->data_type = 0;
- ws->frame_header_size = 0;
- return data_type;
- }
- else
- {
- /* control frame */
- *payload = ws->control_payload;
- *payload_len = ws->payload_size;
- ws->control_payload = 0;
- ws->decode_step = MHD_WebSocket_DecodeStep_Start;
- ws->payload_index = 0;
- ws->frame_header_size = 0;
- return (ws->frame_header [0] & 0x0f);
- }
- }
- else if (0 != (ws->flags & MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS))
- {
- /* RFC 6455 5.4: To allow streaming, the user can choose */
- /* to return fragments */
- if ((MHD_WebSocket_Opcode_Text == ws->data_type) &&
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != ws->data_utf8_step) )
- {
- /* the last UTF-8 sequence is incomplete, so we keep the start of
- that and only return the part before */
- size_t given_utf8 = 0;
- switch (ws->data_utf8_step)
- {
- /* one byte given */
- case MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1:
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2:
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2:
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2:
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3:
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3:
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3:
- given_utf8 = 1;
- break;
- /* two bytes given */
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2:
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3:
- given_utf8 = 2;
- break;
- /* three bytes given */
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3:
- given_utf8 = 3;
- break;
- }
- size_t new_len = ws->data_payload_size - given_utf8;
- if (0 != new_len)
- {
- char *next_payload = ws->malloc (given_utf8 + 1);
- if (NULL == next_payload)
- {
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
- }
- memcpy (next_payload,
- ws->data_payload_start + ws->payload_index - given_utf8,
- given_utf8);
- next_payload[given_utf8] = 0;
-
- ws->data_payload[new_len] = 0;
- *payload = ws->data_payload;
- *payload_len = new_len;
- ws->data_payload = next_payload;
- ws->data_payload_size = given_utf8;
- }
- else
- {
- *payload = NULL;
- *payload_len = 0;
- }
- ws->decode_step = MHD_WebSocket_DecodeStep_Start;
- ws->payload_index = 0;
- ws->frame_header_size = 0;
- if (0 != is_continue)
- return ws->data_type | 0x20; /* mark as middle fragment */
- else
- return ws->data_type | 0x10; /* mark as first fragment */
- }
- else
- {
- /* we simply pass the entire data frame */
- *payload = ws->data_payload;
- *payload_len = ws->data_payload_size;
- ws->data_payload = 0;
- ws->data_payload_start = 0;
- ws->data_payload_size = 0;
- ws->decode_step = MHD_WebSocket_DecodeStep_Start;
- ws->payload_index = 0;
- ws->frame_header_size = 0;
- if (0 != is_continue)
- return ws->data_type | 0x20; /* mark as middle fragment */
- else
- return ws->data_type | 0x10; /* mark as first fragment */
- }
- }
- else
- {
- /* RFC 6455 5.4: We must await a continuation frame to get */
- /* the remainder of this data frame */
- ws->decode_step = MHD_WebSocket_DecodeStep_Start;
- ws->frame_header_size = 0;
- ws->payload_index = 0;
- return MHD_WEBSOCKET_STATUS_OK;
- }
-}
-
-
-/**
- * Splits the received close reason
- */
-_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)
-{
- /* initialize output variables for errors cases */
- if (NULL != reason_code)
- *reason_code = MHD_WEBSOCKET_CLOSEREASON_NO_REASON;
- if (NULL != reason_utf8)
- *reason_utf8 = NULL;
- if (NULL != reason_utf8_len)
- *reason_utf8_len = 0;
-
- /* validate parameters */
- if ((NULL == payload) && (0 != payload_len))
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- if (1 == payload_len)
- return MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR;
- if (125 < payload_len)
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
-
- /* decode reason code */
- if (2 > payload_len)
- {
- if (NULL != reason_code)
- *reason_code = MHD_WEBSOCKET_CLOSEREASON_NO_REASON;
- }
- else
- {
- if (NULL != reason_code)
- *reason_code = MHD_htons (*((uint16_t *) payload));
- }
-
- /* decode reason text */
- if (2 >= payload_len)
- {
- if (NULL != reason_utf8)
- *reason_utf8 = NULL;
- if (NULL != reason_utf8_len)
- *reason_utf8_len = 0;
- }
- else
- {
- if (NULL != reason_utf8)
- *reason_utf8 = payload + 2;
- if (NULL != reason_utf8_len)
- *reason_utf8_len = payload_len - 2;
- }
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Encodes a text into a websocket text frame
- */
-_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)
-{
- /* initialize output variables for errors cases */
- if (NULL != frame)
- *frame = NULL;
- if (NULL != frame_len)
- *frame_len = 0;
- if ((NULL != utf8_step) &&
- ((MHD_WEBSOCKET_FRAGMENTATION_FIRST == fragmentation) ||
- (MHD_WEBSOCKET_FRAGMENTATION_NONE == fragmentation) ))
- {
- /* the old UTF-8 step will be ignored for new fragments */
- *utf8_step = MHD_WEBSOCKET_UTF8STEP_NORMAL;
- }
-
- /* validate parameters */
- if ((NULL == ws) ||
- ((0 != payload_utf8_len) && (NULL == payload_utf8)) ||
- (NULL == frame) ||
- (NULL == frame_len) ||
- (MHD_WEBSOCKET_FRAGMENTATION_NONE > fragmentation) ||
- (MHD_WEBSOCKET_FRAGMENTATION_LAST < fragmentation) ||
- ((MHD_WEBSOCKET_FRAGMENTATION_NONE != fragmentation) &&
- (NULL == utf8_step)) )
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
-
- /* check max length */
- if ((uint64_t) 0x7FFFFFFFFFFFFFFF < (uint64_t) payload_utf8_len)
- {
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
- }
-
- /* check UTF-8 */
- int utf8_result = MHD_websocket_check_utf8 (payload_utf8,
- payload_utf8_len,
- utf8_step,
- NULL);
- if ((MHD_WebSocket_UTF8Result_Invalid == utf8_result) ||
- ((MHD_WebSocket_UTF8Result_Incomplete == utf8_result) &&
- (MHD_WEBSOCKET_FRAGMENTATION_NONE == fragmentation)) )
- {
- return MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR;
- }
-
- /* encode data */
- return MHD_websocket_encode_data (ws,
- payload_utf8,
- payload_utf8_len,
- fragmentation,
- frame,
- frame_len,
- MHD_WebSocket_Opcode_Text);
-}
-
-
-/**
- * Encodes binary data into a websocket binary frame
- */
-_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)
-{
- /* initialize output variables for errors cases */
- if (NULL != frame)
- *frame = NULL;
- if (NULL != frame_len)
- *frame_len = 0;
-
- /* validate parameters */
- if ((NULL == ws) ||
- ((0 != payload_len) && (NULL == payload)) ||
- (NULL == frame) ||
- (NULL == frame_len) ||
- (MHD_WEBSOCKET_FRAGMENTATION_NONE > fragmentation) ||
- (MHD_WEBSOCKET_FRAGMENTATION_LAST < fragmentation) )
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
-
- /* check max length */
- if ((uint64_t) 0x7FFFFFFFFFFFFFFF < (uint64_t) payload_len)
- {
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
- }
-
- return MHD_websocket_encode_data (ws,
- payload,
- payload_len,
- fragmentation,
- frame,
- frame_len,
- MHD_WebSocket_Opcode_Binary);
-}
-
-
-/**
- * Internal function for encoding text/binary data into a websocket frame
- */
-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)
-{
- /* calculate length and masking */
- char is_masked = MHD_websocket_encode_is_masked (ws);
- size_t overhead_len = MHD_websocket_encode_overhead_size (ws, payload_len);
- size_t total_len = overhead_len + payload_len;
- uint32_t mask = 0 != is_masked ? MHD_websocket_generate_mask (ws) : 0;
-
- /* allocate memory */
- char *result = ws->malloc (total_len + 1);
- if (NULL == result)
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
- result [total_len] = 0;
- *frame = result;
- *frame_len = total_len;
-
- /* add the opcode */
- switch (fragmentation)
- {
- case MHD_WEBSOCKET_FRAGMENTATION_NONE:
- *(result++) = 0x80 | opcode;
- break;
- case MHD_WEBSOCKET_FRAGMENTATION_FIRST:
- *(result++) = opcode;
- break;
- case MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING:
- *(result++) = MHD_WebSocket_Opcode_Continuation;
- break;
- case MHD_WEBSOCKET_FRAGMENTATION_LAST:
- *(result++) = 0x80 | MHD_WebSocket_Opcode_Continuation;
- break;
- }
-
- /* add the length */
- if (126 > payload_len)
- {
- *(result++) = is_masked | (char) payload_len;
- }
- else if (65536 > payload_len)
- {
- *(result++) = is_masked | 126;
- *((uint16_t *) result) = MHD_htons ((uint16_t) payload_len);
- result += 2;
- }
- else
- {
- *(result++) = is_masked | 127;
- *((uint64_t *) result) = MHD_htonll ((uint64_t) payload_len);
- result += 8;
-
- }
-
- /* add the mask */
- if (0 != is_masked)
- {
- *(result++) = ((char *) &mask)[0];
- *(result++) = ((char *) &mask)[1];
- *(result++) = ((char *) &mask)[2];
- *(result++) = ((char *) &mask)[3];
- }
-
- /* add the payload */
- if (0 != payload_len)
- {
- MHD_websocket_copy_payload (result,
- payload,
- payload_len,
- mask,
- 0);
- }
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Encodes a websocket ping frame
- */
-_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)
-{
- /* encode the ping frame */
- return MHD_websocket_encode_ping_pong (ws,
- payload,
- payload_len,
- frame,
- frame_len,
- MHD_WebSocket_Opcode_Ping);
-}
-
-
-/**
- * Encodes a websocket pong frame
- */
-_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)
-{
- /* encode the pong frame */
- return MHD_websocket_encode_ping_pong (ws,
- payload,
- payload_len,
- frame,
- frame_len,
- MHD_WebSocket_Opcode_Pong);
-}
-
-
-/**
- * Internal function for encoding ping/pong frames
- */
-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)
-{
- /* initialize output variables for errors cases */
- if (NULL != frame)
- *frame = NULL;
- if (NULL != frame_len)
- *frame_len = 0;
-
- /* validate the parameters */
- if ((NULL == ws) ||
- ((0 != payload_len) && (NULL == payload)) ||
- (NULL == frame) ||
- (NULL == frame_len) )
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
-
- /* RFC 6455 5.5: Control frames may only have up to 125 bytes of payload data */
- if (125 < payload_len)
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
-
- /* calculate length and masking */
- char is_masked = MHD_websocket_encode_is_masked (ws);
- size_t overhead_len = MHD_websocket_encode_overhead_size (ws, payload_len);
- size_t total_len = overhead_len + payload_len;
- uint32_t mask = is_masked != 0 ? MHD_websocket_generate_mask (ws) : 0;
-
- /* allocate memory */
- char *result = ws->malloc (total_len + 1);
- if (NULL == result)
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
- result [total_len] = 0;
- *frame = result;
- *frame_len = total_len;
-
- /* add the opcode */
- *(result++) = 0x80 | opcode;
-
- /* add the length */
- *(result++) = is_masked | (char) payload_len;
-
- /* add the mask */
- if (0 != is_masked)
- {
- *(result++) = ((char *) &mask)[0];
- *(result++) = ((char *) &mask)[1];
- *(result++) = ((char *) &mask)[2];
- *(result++) = ((char *) &mask)[3];
- }
-
- /* add the payload */
- if (0 != payload_len)
- {
- MHD_websocket_copy_payload (result,
- payload,
- payload_len,
- mask,
- 0);
- }
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Encodes a websocket close frame
- */
-_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)
-{
- /* initialize output variables for errors cases */
- if (NULL != frame)
- *frame = NULL;
- if (NULL != frame_len)
- *frame_len = 0;
-
- /* validate the parameters */
- if ((NULL == ws) ||
- ((0 != reason_utf8_len) && (NULL == reason_utf8)) ||
- (NULL == frame) ||
- (NULL == frame_len) ||
- ((MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code) &&
- (1000 > reason_code)) ||
- ((0 != reason_utf8_len) &&
- (MHD_WEBSOCKET_CLOSEREASON_NO_REASON == reason_code)) )
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
-
- /* RFC 6455 5.5: Control frames may only have up to 125 bytes of payload data, */
- /* but in this case only 123 bytes, because 2 bytes are reserved */
- /* for the close reason code. */
- if (123 < reason_utf8_len)
- return MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED;
-
- /* RFC 6455 5.5.1: If close payload data is given, it must be valid UTF-8 */
- if (0 != reason_utf8_len)
- {
- int utf8_result = MHD_websocket_check_utf8 (reason_utf8,
- reason_utf8_len,
- NULL,
- NULL);
- if (MHD_WebSocket_UTF8Result_Valid != utf8_result)
- return MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR;
- }
-
- /* calculate length and masking */
- char is_masked = MHD_websocket_encode_is_masked (ws);
- size_t payload_len = (MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code ?
- 2 + reason_utf8_len : 0);
- size_t overhead_len = MHD_websocket_encode_overhead_size (ws, payload_len);
- size_t total_len = overhead_len + payload_len;
- uint32_t mask = is_masked != 0 ? MHD_websocket_generate_mask (ws) : 0;
-
- /* allocate memory */
- char *result = ws->malloc (total_len + 1);
- if (NULL == result)
- return MHD_WEBSOCKET_STATUS_MEMORY_ERROR;
- result [total_len] = 0;
- *frame = result;
- *frame_len = total_len;
-
- /* add the opcode */
- *(result++) = 0x88;
-
- /* add the length */
- *(result++) = is_masked | (char) payload_len;
-
- /* add the mask */
- if (0 != is_masked)
- {
- *(result++) = ((char *) &mask)[0];
- *(result++) = ((char *) &mask)[1];
- *(result++) = ((char *) &mask)[2];
- *(result++) = ((char *) &mask)[3];
- }
-
- /* add the payload */
- if (0 != reason_code)
- {
- /* close reason code */
- uint16_t reason_code_nb = MHD_htons (reason_code);
- MHD_websocket_copy_payload (result,
- (const char *) &reason_code_nb,
- 2,
- mask,
- 0);
- result += 2;
-
- /* custom reason payload */
- if (0 != reason_utf8_len)
- {
- MHD_websocket_copy_payload (result,
- reason_utf8,
- reason_utf8_len,
- mask,
- 2);
- }
- }
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Returns the 0x80 prefix for masked data, 0x00 otherwise
- */
-static char
-MHD_websocket_encode_is_masked (struct MHD_WebSocketStream *ws)
-{
- return (ws->flags & MHD_WEBSOCKET_FLAG_MASK_SERVERCLIENT) ==
- MHD_WEBSOCKET_FLAG_CLIENT ? 0x80 : 0x00;
-}
-
-
-/**
- * Calculates the size of the overhead in bytes
- */
-static char
-MHD_websocket_encode_overhead_size (struct MHD_WebSocketStream *ws,
- size_t payload_len)
-{
- return 2 + (MHD_websocket_encode_is_masked (ws) != 0 ? 4 : 0) + (125 <
- payload_len ?
- (65535 <
- payload_len
- ? 8 : 2) : 0);
-}
-
-
-/**
- * Copies the payload to the destination (using mask)
- */
-static void
-MHD_websocket_copy_payload (char *dst,
- const char *src,
- size_t len,
- uint32_t mask,
- unsigned long mask_offset)
-{
- if (0 != len)
- {
- if (0 == mask)
- {
- /* when the mask is zero, we can just copy the data */
- memcpy (dst, src, len);
- }
- else
- {
- /* mask is used */
- char mask_[4];
- *((uint32_t *) mask_) = mask;
- for (size_t i = 0; i < len; ++i)
- {
- dst[i] = src[i] ^ mask_[(i + mask_offset) & 3];
- }
- }
- }
-}
-
-
-/**
- * Checks a UTF-8 sequence
- */
-static int
-MHD_websocket_check_utf8 (const char *buf,
- size_t buf_len,
- int *utf8_step,
- size_t *buf_offset)
-{
- int utf8_step_ = (NULL != utf8_step) ? *utf8_step :
- MHD_WEBSOCKET_UTF8STEP_NORMAL;
-
- for (size_t i = 0; i < buf_len; ++i)
- {
- unsigned char character = (unsigned char) buf[i];
- switch (utf8_step_)
- {
- case MHD_WEBSOCKET_UTF8STEP_NORMAL:
- if ((0x00 <= character) && (0x7F >= character))
- {
- /* RFC 3629 4: single byte UTF-8 sequence */
- /* (nothing to do here) */
- }
- else if ((0xC2 <= character) && (0xDF >= character))
- {
- /* RFC 3629 4: two byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1;
- }
- else if (0xE0 == character)
- {
- /* RFC 3629 4: three byte UTF-8 sequence, but the second byte must be 0xA0-0xBF */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2;
- }
- else if (0xED == character)
- {
- /* RFC 3629 4: three byte UTF-8 sequence, but the second byte must be 0x80-0x9F */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2;
- }
- else if (((0xE1 <= character) && (0xEC >= character)) ||
- ((0xEE <= character) && (0xEF >= character)) )
- {
- /* RFC 3629 4: three byte UTF-8 sequence, both tail bytes must be 0x80-0xBF */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2;
- }
- else if (0xF0 == character)
- {
- /* RFC 3629 4: four byte UTF-8 sequence, but the second byte must be 0x90-0xBF */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3;
- }
- else if (0xF4 == character)
- {
- /* RFC 3629 4: four byte UTF-8 sequence, but the second byte must be 0x80-0x8F */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3;
- }
- else if ((0xF1 <= character) && (0xF3 >= character))
- {
- /* RFC 3629 4: four byte UTF-8 sequence, all three tail bytes must be 0x80-0xBF */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2:
- if ((0xA0 <= character) && (0xBF >= character))
- {
- /* RFC 3629 4: Second byte of three byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2:
- if ((0x80 <= character) && (0x9F >= character))
- {
- /* RFC 3629 4: Second byte of three byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2:
- if ((0x80 <= character) && (0xBF >= character))
- {
- /* RFC 3629 4: Second byte of three byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3:
- if ((0x90 <= character) && (0xBF >= character))
- {
- /* RFC 3629 4: Second byte of four byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3:
- if ((0x80 <= character) && (0x8F >= character))
- {
- /* RFC 3629 4: Second byte of four byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3:
- if ((0x80 <= character) && (0xBF >= character))
- {
- /* RFC 3629 4: Second byte of four byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3:
- if ((0x80 <= character) && (0xBF >= character))
- {
- /* RFC 3629 4: Third byte of four byte UTF-8 sequence */
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- /* RFC 3629 4: Second byte of two byte UTF-8 sequence */
- case MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1:
- /* RFC 3629 4: Third byte of three byte UTF-8 sequence */
- case MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2:
- /* RFC 3629 4: Fourth byte of four byte UTF-8 sequence */
- case MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3:
- if ((0x80 <= character) && (0xBF >= character))
- {
- utf8_step_ = MHD_WEBSOCKET_UTF8STEP_NORMAL;
- }
- else
- {
- /* RFC 3629 4: Invalid UTF-8 byte */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- break;
-
- default:
- /* Invalid last step...? */
- if (NULL != buf_offset)
- *buf_offset = i;
- return MHD_WebSocket_UTF8Result_Invalid;
- }
- }
-
- /* return values */
- if (NULL != utf8_step)
- *utf8_step = utf8_step_;
- if (NULL != buf_offset)
- *buf_offset = buf_len;
- if (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step_)
- {
- return MHD_WebSocket_UTF8Result_Incomplete;
- }
- return MHD_WebSocket_UTF8Result_Valid;
-}
-
-
-/**
- * Generates a mask for masking by calling
- * a random number generator.
- */
-static uint32_t
-MHD_websocket_generate_mask (struct MHD_WebSocketStream *ws)
-{
- unsigned char mask_[4];
- if (NULL != ws->rng)
- {
- size_t offset = 0;
- while (offset < 4)
- {
- size_t encoded = ws->rng (ws->cls_rng,
- mask_ + offset,
- 4 - offset);
- offset += encoded;
- }
- }
- else
- {
- /* this case should never happen */
- mask_ [0] = 0;
- mask_ [1] = 0;
- mask_ [2] = 0;
- mask_ [3] = 0;
- }
-
- return *((uint32_t *) mask_);
-}
-
-
-/**
- * Calls the malloc function associated with the websocket steam
- */
-_MHD_EXTERN void *
-MHD_websocket_malloc (struct MHD_WebSocketStream *ws,
- size_t buf_len)
-{
- if (NULL == ws)
- {
- return NULL;
- }
-
- return ws->malloc (buf_len);
-}
-
-
-/**
- * Calls the realloc function associated with the websocket steam
- */
-_MHD_EXTERN void *
-MHD_websocket_realloc (struct MHD_WebSocketStream *ws,
- void *buf,
- size_t new_buf_len)
-{
- if (NULL == ws)
- {
- return NULL;
- }
-
- return ws->realloc (buf, new_buf_len);
-}
-
-
-/**
- * Calls the free function associated with the websocket steam
- */
-_MHD_EXTERN int
-MHD_websocket_free (struct MHD_WebSocketStream *ws,
- void *buf)
-{
- if (NULL == ws)
- {
- return MHD_WEBSOCKET_STATUS_PARAMETER_ERROR;
- }
-
- ws->free (buf);
-
- return MHD_WEBSOCKET_STATUS_OK;
-}
-
-
-/**
- * Converts a 16 bit value into network byte order (MSB first)
- * in dependence of the host system
- */
-static uint16_t
-MHD_htons (uint16_t value)
-{
- uint16_t endian = 0x0001;
-
- if (((char *) &endian)[0] == 0x01)
- {
- /* least significant byte first */
- ((char *) &endian)[0] = ((char *) &value)[1];
- ((char *) &endian)[1] = ((char *) &value)[0];
- return endian;
- }
- else
- {
- /* most significant byte first */
- return value;
- }
-}
-
-
-/**
- * Converts a 64 bit value into network byte order (MSB first)
- * in dependence of the host system
- */
-static uint64_t
-MHD_htonll (uint64_t value)
-{
- uint64_t endian = 0x0000000000000001;
-
- if (((char *) &endian)[0] == 0x01)
- {
- /* least significant byte first */
- ((char *) &endian)[0] = ((char *) &value)[7];
- ((char *) &endian)[1] = ((char *) &value)[6];
- ((char *) &endian)[2] = ((char *) &value)[5];
- ((char *) &endian)[3] = ((char *) &value)[4];
- ((char *) &endian)[4] = ((char *) &value)[3];
- ((char *) &endian)[5] = ((char *) &value)[2];
- ((char *) &endian)[6] = ((char *) &value)[1];
- ((char *) &endian)[7] = ((char *) &value)[0];
- return endian;
- }
- else
- {
- /* most significant byte first */
- return value;
- }
-}
diff --git a/src/microhttpd_ws/sha1.c b/src/microhttpd_ws/sha1.c
@@ -1,378 +0,0 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2019-2021 Karlson2k (Evgeny Grin)
-
- libmicrohttpd is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library.
- If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @file microhttpd/sha1.c
- * @brief Calculation of SHA-1 digest as defined in FIPS PUB 180-4 (2015)
- * @author Karlson2k (Evgeny Grin)
- */
-
-#include "sha1.h"
-
-#include <string.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif /* HAVE_MEMORY_H */
-#include "mhd_bithelpers.h"
-#include "mhd_assert.h"
-
-/**
- * Initialise structure for SHA-1 calculation.
- *
- * @param ctx_ must be a `struct sha1_ctx *`
- */
-void
-MHD_SHA1_init (void *ctx_)
-{
- struct sha1_ctx *const ctx = ctx_;
- /* Initial hash values, see FIPS PUB 180-4 paragraph 5.3.1 */
- /* Just some "magic" numbers defined by standard */
- ctx->H[0] = UINT32_C (0x67452301);
- ctx->H[1] = UINT32_C (0xefcdab89);
- ctx->H[2] = UINT32_C (0x98badcfe);
- ctx->H[3] = UINT32_C (0x10325476);
- ctx->H[4] = UINT32_C (0xc3d2e1f0);
-
- /* Initialise number of bytes. */
- ctx->count = 0;
-}
-
-
-/**
- * Base of SHA-1 transformation.
- * Gets full 512 bits / 64 bytes block of data and updates hash values;
- * @param H hash values
- * @param data data, must be exactly 64 bytes long
- */
-static void
-sha1_transform (uint32_t H[_SHA1_DIGEST_LENGTH],
- const uint8_t data[SHA1_BLOCK_SIZE])
-{
- /* Working variables,
- see FIPS PUB 180-4 paragraph 6.1.3 */
- uint32_t a = H[0];
- uint32_t b = H[1];
- uint32_t c = H[2];
- uint32_t d = H[3];
- uint32_t e = H[4];
-
- /* Data buffer, used as cyclic buffer.
- See FIPS PUB 180-4 paragraphs 5.2.1, 6.1.3 */
- uint32_t W[16];
-
- /* 'Ch' and 'Maj' macro functions are defined with
- widely-used optimization.
- See FIPS PUB 180-4 formulae 4.1. */
-#define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) )
-#define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
- /* Unoptimized (original) versions: */
-/* #define Ch(x,y,z) ( ( (x) & (y) ) ^ ( ~(x) & (z) ) ) */
-/* #define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */
-#define Par(x,y,z) ( (x) ^ (y) ^ (z) )
-
- /* Single step of SHA-1 computation,
- see FIPS PUB 180-4 paragraph 6.1.3 step 3.
- * Note: instead of reassigning all working variables on each step,
- variables are rotated for each step:
- SHA1STEP32 (a, b, c, d, e, func, K00, W[0]);
- SHA1STEP32 (e, a, b, c, d, func, K00, W[1]);
- so current 'vC' will be used as 'vD' on the next step,
- current 'vE' will be used as 'vA' on the next step.
- * Note: 'wt' must be used exactly one time in this macro as it change other data as well
- every time when used. */
-
-#define SHA1STEP32(vA,vB,vC,vD,vE,ft,kt,wt) do { \
- (vE) += _MHD_ROTL32 ((vA), 5) + ft ((vB), (vC), (vD)) + (kt) + (wt); \
- (vB) = _MHD_ROTL32 ((vB), 30); } while (0)
-
- /* Get value of W(t) from input data buffer,
- See FIPS PUB 180-4 paragraph 6.1.3.
- Input data must be read in big-endian bytes order,
- see FIPS PUB 180-4 paragraph 3.1.2. */
-#define GET_W_FROM_DATA(buf,t) \
- _MHD_GET_32BIT_BE (((const uint8_t*) (buf)) + (t) * SHA1_BYTES_IN_WORD)
-
-#ifndef _MHD_GET_32BIT_BE_UNALIGNED
- if (0 != (((uintptr_t) data) % _MHD_UINT32_ALIGN))
- {
- /* Copy the unaligned input data to the aligned buffer */
- memcpy (W, data, SHA1_BLOCK_SIZE);
- /* The W[] buffer itself will be used as the source of the data,
- * but data will be reloaded in correct bytes order during
- * the next steps */
- data = (uint8_t *) W;
- }
-#endif /* _MHD_GET_32BIT_BE_UNALIGNED */
-
-/* SHA-1 values of Kt for t=0..19, see FIPS PUB 180-4 paragraph 4.2.1. */
-#define K00 UINT32_C(0x5a827999)
-/* SHA-1 values of Kt for t=20..39, see FIPS PUB 180-4 paragraph 4.2.1.*/
-#define K20 UINT32_C(0x6ed9eba1)
-/* SHA-1 values of Kt for t=40..59, see FIPS PUB 180-4 paragraph 4.2.1.*/
-#define K40 UINT32_C(0x8f1bbcdc)
-/* SHA-1 values of Kt for t=60..79, see FIPS PUB 180-4 paragraph 4.2.1.*/
-#define K60 UINT32_C(0xca62c1d6)
-
- /* During first 16 steps, before making any calculations on each step,
- the W element is read from input data buffer as big-endian value and
- stored in array of W elements. */
- /* Note: instead of using K constants as array, all K values are specified
- individually for each step. */
- SHA1STEP32 (a, b, c, d, e, Ch, K00, W[0] = GET_W_FROM_DATA (data, 0));
- SHA1STEP32 (e, a, b, c, d, Ch, K00, W[1] = GET_W_FROM_DATA (data, 1));
- SHA1STEP32 (d, e, a, b, c, Ch, K00, W[2] = GET_W_FROM_DATA (data, 2));
- SHA1STEP32 (c, d, e, a, b, Ch, K00, W[3] = GET_W_FROM_DATA (data, 3));
- SHA1STEP32 (b, c, d, e, a, Ch, K00, W[4] = GET_W_FROM_DATA (data, 4));
- SHA1STEP32 (a, b, c, d, e, Ch, K00, W[5] = GET_W_FROM_DATA (data, 5));
- SHA1STEP32 (e, a, b, c, d, Ch, K00, W[6] = GET_W_FROM_DATA (data, 6));
- SHA1STEP32 (d, e, a, b, c, Ch, K00, W[7] = GET_W_FROM_DATA (data, 7));
- SHA1STEP32 (c, d, e, a, b, Ch, K00, W[8] = GET_W_FROM_DATA (data, 8));
- SHA1STEP32 (b, c, d, e, a, Ch, K00, W[9] = GET_W_FROM_DATA (data, 9));
- SHA1STEP32 (a, b, c, d, e, Ch, K00, W[10] = GET_W_FROM_DATA (data, 10));
- SHA1STEP32 (e, a, b, c, d, Ch, K00, W[11] = GET_W_FROM_DATA (data, 11));
- SHA1STEP32 (d, e, a, b, c, Ch, K00, W[12] = GET_W_FROM_DATA (data, 12));
- SHA1STEP32 (c, d, e, a, b, Ch, K00, W[13] = GET_W_FROM_DATA (data, 13));
- SHA1STEP32 (b, c, d, e, a, Ch, K00, W[14] = GET_W_FROM_DATA (data, 14));
- SHA1STEP32 (a, b, c, d, e, Ch, K00, W[15] = GET_W_FROM_DATA (data, 15));
-
- /* 'W' generation and assignment for 16 <= t <= 79.
- See FIPS PUB 180-4 paragraph 6.1.3.
- As only last 16 'W' are used in calculations, it is possible to
- use 16 elements array of W as cyclic buffer. */
-#define Wgen(w,t) _MHD_ROTL32((w)[(t + 13) & 0xf] ^ (w)[(t + 8) & 0xf] \
- ^ (w)[(t + 2) & 0xf] ^ (w)[t & 0xf], 1)
-
- /* During last 60 steps, before making any calculations on each step,
- W element is generated from W elements of cyclic buffer and generated value
- stored back in cyclic buffer. */
- /* Note: instead of using K constants as array, all K values are specified
- individually for each step, see FIPS PUB 180-4 paragraph 4.2.1. */
- SHA1STEP32 (e, a, b, c, d, Ch, K00, W[16 & 0xf] = Wgen (W, 16));
- SHA1STEP32 (d, e, a, b, c, Ch, K00, W[17 & 0xf] = Wgen (W, 17));
- SHA1STEP32 (c, d, e, a, b, Ch, K00, W[18 & 0xf] = Wgen (W, 18));
- SHA1STEP32 (b, c, d, e, a, Ch, K00, W[19 & 0xf] = Wgen (W, 19));
- SHA1STEP32 (a, b, c, d, e, Par, K20, W[20 & 0xf] = Wgen (W, 20));
- SHA1STEP32 (e, a, b, c, d, Par, K20, W[21 & 0xf] = Wgen (W, 21));
- SHA1STEP32 (d, e, a, b, c, Par, K20, W[22 & 0xf] = Wgen (W, 22));
- SHA1STEP32 (c, d, e, a, b, Par, K20, W[23 & 0xf] = Wgen (W, 23));
- SHA1STEP32 (b, c, d, e, a, Par, K20, W[24 & 0xf] = Wgen (W, 24));
- SHA1STEP32 (a, b, c, d, e, Par, K20, W[25 & 0xf] = Wgen (W, 25));
- SHA1STEP32 (e, a, b, c, d, Par, K20, W[26 & 0xf] = Wgen (W, 26));
- SHA1STEP32 (d, e, a, b, c, Par, K20, W[27 & 0xf] = Wgen (W, 27));
- SHA1STEP32 (c, d, e, a, b, Par, K20, W[28 & 0xf] = Wgen (W, 28));
- SHA1STEP32 (b, c, d, e, a, Par, K20, W[29 & 0xf] = Wgen (W, 29));
- SHA1STEP32 (a, b, c, d, e, Par, K20, W[30 & 0xf] = Wgen (W, 30));
- SHA1STEP32 (e, a, b, c, d, Par, K20, W[31 & 0xf] = Wgen (W, 31));
- SHA1STEP32 (d, e, a, b, c, Par, K20, W[32 & 0xf] = Wgen (W, 32));
- SHA1STEP32 (c, d, e, a, b, Par, K20, W[33 & 0xf] = Wgen (W, 33));
- SHA1STEP32 (b, c, d, e, a, Par, K20, W[34 & 0xf] = Wgen (W, 34));
- SHA1STEP32 (a, b, c, d, e, Par, K20, W[35 & 0xf] = Wgen (W, 35));
- SHA1STEP32 (e, a, b, c, d, Par, K20, W[36 & 0xf] = Wgen (W, 36));
- SHA1STEP32 (d, e, a, b, c, Par, K20, W[37 & 0xf] = Wgen (W, 37));
- SHA1STEP32 (c, d, e, a, b, Par, K20, W[38 & 0xf] = Wgen (W, 38));
- SHA1STEP32 (b, c, d, e, a, Par, K20, W[39 & 0xf] = Wgen (W, 39));
- SHA1STEP32 (a, b, c, d, e, Maj, K40, W[40 & 0xf] = Wgen (W, 40));
- SHA1STEP32 (e, a, b, c, d, Maj, K40, W[41 & 0xf] = Wgen (W, 41));
- SHA1STEP32 (d, e, a, b, c, Maj, K40, W[42 & 0xf] = Wgen (W, 42));
- SHA1STEP32 (c, d, e, a, b, Maj, K40, W[43 & 0xf] = Wgen (W, 43));
- SHA1STEP32 (b, c, d, e, a, Maj, K40, W[44 & 0xf] = Wgen (W, 44));
- SHA1STEP32 (a, b, c, d, e, Maj, K40, W[45 & 0xf] = Wgen (W, 45));
- SHA1STEP32 (e, a, b, c, d, Maj, K40, W[46 & 0xf] = Wgen (W, 46));
- SHA1STEP32 (d, e, a, b, c, Maj, K40, W[47 & 0xf] = Wgen (W, 47));
- SHA1STEP32 (c, d, e, a, b, Maj, K40, W[48 & 0xf] = Wgen (W, 48));
- SHA1STEP32 (b, c, d, e, a, Maj, K40, W[49 & 0xf] = Wgen (W, 49));
- SHA1STEP32 (a, b, c, d, e, Maj, K40, W[50 & 0xf] = Wgen (W, 50));
- SHA1STEP32 (e, a, b, c, d, Maj, K40, W[51 & 0xf] = Wgen (W, 51));
- SHA1STEP32 (d, e, a, b, c, Maj, K40, W[52 & 0xf] = Wgen (W, 52));
- SHA1STEP32 (c, d, e, a, b, Maj, K40, W[53 & 0xf] = Wgen (W, 53));
- SHA1STEP32 (b, c, d, e, a, Maj, K40, W[54 & 0xf] = Wgen (W, 54));
- SHA1STEP32 (a, b, c, d, e, Maj, K40, W[55 & 0xf] = Wgen (W, 55));
- SHA1STEP32 (e, a, b, c, d, Maj, K40, W[56 & 0xf] = Wgen (W, 56));
- SHA1STEP32 (d, e, a, b, c, Maj, K40, W[57 & 0xf] = Wgen (W, 57));
- SHA1STEP32 (c, d, e, a, b, Maj, K40, W[58 & 0xf] = Wgen (W, 58));
- SHA1STEP32 (b, c, d, e, a, Maj, K40, W[59 & 0xf] = Wgen (W, 59));
- SHA1STEP32 (a, b, c, d, e, Par, K60, W[60 & 0xf] = Wgen (W, 60));
- SHA1STEP32 (e, a, b, c, d, Par, K60, W[61 & 0xf] = Wgen (W, 61));
- SHA1STEP32 (d, e, a, b, c, Par, K60, W[62 & 0xf] = Wgen (W, 62));
- SHA1STEP32 (c, d, e, a, b, Par, K60, W[63 & 0xf] = Wgen (W, 63));
- SHA1STEP32 (b, c, d, e, a, Par, K60, W[64 & 0xf] = Wgen (W, 64));
- SHA1STEP32 (a, b, c, d, e, Par, K60, W[65 & 0xf] = Wgen (W, 65));
- SHA1STEP32 (e, a, b, c, d, Par, K60, W[66 & 0xf] = Wgen (W, 66));
- SHA1STEP32 (d, e, a, b, c, Par, K60, W[67 & 0xf] = Wgen (W, 67));
- SHA1STEP32 (c, d, e, a, b, Par, K60, W[68 & 0xf] = Wgen (W, 68));
- SHA1STEP32 (b, c, d, e, a, Par, K60, W[69 & 0xf] = Wgen (W, 69));
- SHA1STEP32 (a, b, c, d, e, Par, K60, W[70 & 0xf] = Wgen (W, 70));
- SHA1STEP32 (e, a, b, c, d, Par, K60, W[71 & 0xf] = Wgen (W, 71));
- SHA1STEP32 (d, e, a, b, c, Par, K60, W[72 & 0xf] = Wgen (W, 72));
- SHA1STEP32 (c, d, e, a, b, Par, K60, W[73 & 0xf] = Wgen (W, 73));
- SHA1STEP32 (b, c, d, e, a, Par, K60, W[74 & 0xf] = Wgen (W, 74));
- SHA1STEP32 (a, b, c, d, e, Par, K60, W[75 & 0xf] = Wgen (W, 75));
- SHA1STEP32 (e, a, b, c, d, Par, K60, W[76 & 0xf] = Wgen (W, 76));
- SHA1STEP32 (d, e, a, b, c, Par, K60, W[77 & 0xf] = Wgen (W, 77));
- SHA1STEP32 (c, d, e, a, b, Par, K60, W[78 & 0xf] = Wgen (W, 78));
- SHA1STEP32 (b, c, d, e, a, Par, K60, W[79 & 0xf] = Wgen (W, 79));
-
- /* Compute intermediate hash.
- See FIPS PUB 180-4 paragraph 6.1.3 step 4. */
- H[0] += a;
- H[1] += b;
- H[2] += c;
- H[3] += d;
- H[4] += e;
-}
-
-
-/**
- * Process portion of bytes.
- *
- * @param ctx_ must be a `struct sha1_ctx *`
- * @param data bytes to add to hash
- * @param length number of bytes in @a data
- */
-void
-MHD_SHA1_update (void *ctx_,
- const uint8_t *data,
- size_t length)
-{
- struct sha1_ctx *const ctx = ctx_;
- unsigned bytes_have; /**< Number of bytes in buffer */
-
- mhd_assert ((data != NULL) || (length == 0));
-
- if (0 == length)
- return; /* Do nothing */
-
- /* Note: (count & (SHA1_BLOCK_SIZE-1))
- equal (count % SHA1_BLOCK_SIZE) for this block size. */
- bytes_have = (unsigned) (ctx->count & (SHA1_BLOCK_SIZE - 1));
- ctx->count += length;
-
- if (0 != bytes_have)
- {
- unsigned bytes_left = SHA1_BLOCK_SIZE - bytes_have;
- if (length >= bytes_left)
- { /* Combine new data with the data in the buffer and
- process the full block. */
- memcpy (ctx->buffer + bytes_have,
- data,
- bytes_left);
- data += bytes_left;
- length -= bytes_left;
- sha1_transform (ctx->H, ctx->buffer);
- bytes_have = 0;
- }
- }
-
- while (SHA1_BLOCK_SIZE <= length)
- { /* Process any full blocks of new data directly,
- without copying to the buffer. */
- sha1_transform (ctx->H, data);
- data += SHA1_BLOCK_SIZE;
- length -= SHA1_BLOCK_SIZE;
- }
-
- if (0 != length)
- { /* Copy incomplete block of new data (if any)
- to the buffer. */
- memcpy (ctx->buffer + bytes_have, data, length);
- }
-}
-
-
-/**
- * Size of "length" padding addition in bytes.
- * See FIPS PUB 180-4 paragraph 5.1.1.
- */
-#define SHA1_SIZE_OF_LEN_ADD (64 / 8)
-
-/**
- * Finalise SHA-1 calculation, return digest.
- *
- * @param ctx_ must be a `struct sha1_ctx *`
- * @param[out] digest set to the hash, must be #SHA1_DIGEST_SIZE bytes
- */
-void
-MHD_SHA1_finish (void *ctx_,
- uint8_t digest[SHA1_DIGEST_SIZE])
-{
- struct sha1_ctx *const ctx = ctx_;
- uint64_t num_bits; /**< Number of processed bits */
- unsigned bytes_have; /**< Number of bytes in buffer */
-
- num_bits = ctx->count << 3;
- /* Note: (count & (SHA1_BLOCK_SIZE-1))
- equals (count % SHA1_BLOCK_SIZE) for this block size. */
- bytes_have = (unsigned) (ctx->count & (SHA1_BLOCK_SIZE - 1));
-
- /* Input data must be padded with bit "1" and with length of data in bits.
- See FIPS PUB 180-4 paragraph 5.1.1. */
- /* Data is always processed in form of bytes (not by individual bits),
- therefore position of first padding bit in byte is always predefined (0x80). */
- /* Buffer always have space at least for one byte (as full buffers are
- processed immediately). */
- ctx->buffer[bytes_have++] = 0x80;
-
- if (SHA1_BLOCK_SIZE - bytes_have < SHA1_SIZE_OF_LEN_ADD)
- { /* No space in current block to put total length of message.
- Pad current block with zeros and process it. */
- if (SHA1_BLOCK_SIZE > bytes_have)
- memset (ctx->buffer + bytes_have, 0, SHA1_BLOCK_SIZE - bytes_have);
- /* Process full block. */
- sha1_transform (ctx->H, ctx->buffer);
- /* Start new block. */
- bytes_have = 0;
- }
-
- /* Pad the rest of the buffer with zeros. */
- memset (ctx->buffer + bytes_have, 0,
- SHA1_BLOCK_SIZE - SHA1_SIZE_OF_LEN_ADD - bytes_have);
- /* Put the number of bits in the processed message as a big-endian value. */
- _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA1_BLOCK_SIZE - SHA1_SIZE_OF_LEN_ADD,
- num_bits);
- /* Process the full final block. */
- sha1_transform (ctx->H, ctx->buffer);
-
- /* Put final hash/digest in BE mode */
-#ifndef _MHD_PUT_32BIT_BE_UNALIGNED
- if (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN)
- {
- uint32_t alig_dgst[_SHA1_DIGEST_LENGTH];
- _MHD_PUT_32BIT_BE (alig_dgst + 0, ctx->H[0]);
- _MHD_PUT_32BIT_BE (alig_dgst + 1, ctx->H[1]);
- _MHD_PUT_32BIT_BE (alig_dgst + 2, ctx->H[2]);
- _MHD_PUT_32BIT_BE (alig_dgst + 3, ctx->H[3]);
- _MHD_PUT_32BIT_BE (alig_dgst + 4, ctx->H[4]);
- /* Copy result to unaligned destination address */
- memcpy (digest, alig_dgst, SHA1_DIGEST_SIZE);
- }
- else
-#else /* _MHD_PUT_32BIT_BE_UNALIGNED */
- if (1)
-#endif /* _MHD_PUT_32BIT_BE_UNALIGNED */
- {
- _MHD_PUT_32BIT_BE (digest + 0 * SHA1_BYTES_IN_WORD, ctx->H[0]);
- _MHD_PUT_32BIT_BE (digest + 1 * SHA1_BYTES_IN_WORD, ctx->H[1]);
- _MHD_PUT_32BIT_BE (digest + 2 * SHA1_BYTES_IN_WORD, ctx->H[2]);
- _MHD_PUT_32BIT_BE (digest + 3 * SHA1_BYTES_IN_WORD, ctx->H[3]);
- _MHD_PUT_32BIT_BE (digest + 4 * SHA1_BYTES_IN_WORD, ctx->H[4]);
- }
-
- /* Erase potentially sensitive data. */
- memset (ctx, 0, sizeof(struct sha1_ctx));
-}
diff --git a/src/microhttpd_ws/sha1.h b/src/microhttpd_ws/sha1.h
@@ -1,110 +0,0 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2019-2021 Karlson2k (Evgeny Grin)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library.
- If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @file microhttpd/sha1.h
- * @brief Calculation of SHA-1 digest
- * @author Karlson2k (Evgeny Grin)
- */
-
-#ifndef MHD_SHA1_H
-#define MHD_SHA1_H 1
-
-#include "mhd_options.h"
-#include <stdint.h>
-#ifdef HAVE_STDDEF_H
-#include <stddef.h> /* for size_t */
-#endif /* HAVE_STDDEF_H */
-
-/**
- * SHA-1 digest is kept internally as 5 32-bit words.
- */
-#define _SHA1_DIGEST_LENGTH 5
-
-/**
- * Number of bits in single SHA-1 word
- */
-#define SHA1_WORD_SIZE_BITS 32
-
-/**
- * Number of bytes in single SHA-1 word
- */
-#define SHA1_BYTES_IN_WORD (SHA1_WORD_SIZE_BITS / 8)
-
-/**
- * Size of SHA-1 digest in bytes
- */
-#define SHA1_DIGEST_SIZE (_SHA1_DIGEST_LENGTH * SHA1_BYTES_IN_WORD)
-
-/**
- * Size of SHA-1 digest string in chars including termination NUL
- */
-#define SHA1_DIGEST_STRING_SIZE ((SHA1_DIGEST_SIZE) * 2 + 1)
-
-/**
- * Size of single processing block in bits
- */
-#define SHA1_BLOCK_SIZE_BITS 512
-
-/**
- * Size of single processing block in bytes
- */
-#define SHA1_BLOCK_SIZE (SHA1_BLOCK_SIZE_BITS / 8)
-
-
-struct sha1_ctx
-{
- uint32_t H[_SHA1_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */
- uint8_t buffer[SHA1_BLOCK_SIZE]; /**< SHA256 input data buffer */
- uint64_t count; /**< number of bytes, mod 2^64 */
-};
-
-/**
- * Initialise structure for SHA-1 calculation.
- *
- * @param ctx must be a `struct sha1_ctx *`
- */
-void
-MHD_SHA1_init (void *ctx_);
-
-
-/**
- * Process portion of bytes.
- *
- * @param ctx_ must be a `struct sha1_ctx *`
- * @param data bytes to add to hash
- * @param length number of bytes in @a data
- */
-void
-MHD_SHA1_update (void *ctx_,
- const uint8_t *data,
- size_t length);
-
-
-/**
- * Finalise SHA-1 calculation, return digest.
- *
- * @param ctx_ must be a `struct sha1_ctx *`
- * @param[out] digest set to the hash, must be #SHA1_DIGEST_SIZE bytes
- */
-void
-MHD_SHA1_finish (void *ctx_,
- uint8_t digest[SHA1_DIGEST_SIZE]);
-
-#endif /* MHD_SHA1_H */
diff --git a/src/microhttpd_ws/test_websocket.c b/src/microhttpd_ws/test_websocket.c
@@ -1,10105 +0,0 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2021 David Gausmann
-
- libmicrohttpd is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- libmicrohttpd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with libmicrohttpd; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-/**
- * @file test_websocket.c
- * @brief Testcase for WebSocket decoding/encoding
- * @author David Gausmann
- */
-#include "microhttpd.h"
-#include "microhttpd_ws.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <time.h>
-
-#if SIZE_MAX >= 0x100000000
- #define ENABLE_64BIT_TESTS 1
-#endif
-
-int disable_alloc = 0;
-size_t open_allocs = 0;
-
-/**
- * Custom `malloc()` function used for memory tests
- */
-static void *
-test_malloc (size_t buf_len)
-{
- if (0 != disable_alloc)
- return NULL;
- void *result = malloc (buf_len);
- if (NULL != result)
- ++open_allocs;
- return result;
-}
-
-
-/**
- * Custom `realloc()` function used for memory tests
- */
-static void *
-test_realloc (void *buf, size_t buf_len)
-{
- if (0 != disable_alloc)
- return NULL;
- void *result = realloc (buf, buf_len);
- if ((NULL != result) && (NULL == buf))
- ++open_allocs;
- return result;
-}
-
-
-/**
- * Custom `free()` function used for memory tests
- */
-static void
-test_free (void *buf)
-{
- if (NULL != buf)
- --open_allocs;
- free (buf);
-}
-
-
-/**
- * Custom `rng()` function used for client mode tests
- */
-static size_t
-test_rng (void *cls, void *buf, size_t buf_len)
-{
- for (size_t i = 0; i < buf_len; ++i)
- {
- ((char *) buf) [i] = (char) (rand () % 0xFF);
- }
-
- return buf_len;
-}
-
-
-/**
- * Helper function which allocates a big amount of data
- */
-static void
-allocate_length_test_data (char **buf1,
- char **buf2,
- size_t buf_len,
- const char *buf1_prefix,
- size_t buf1_prefix_len)
-{
- if (NULL != *buf1)
- free (*buf1);
- if (NULL != *buf2)
- free (*buf2);
- *buf1 = (char *) malloc (buf_len + buf1_prefix_len);
- *buf2 = (char *) malloc (buf_len);
- if ((NULL == buf1) || (NULL == buf2))
- return;
- memcpy (*buf1,
- buf1_prefix,
- buf1_prefix_len);
- for (size_t i = 0; i < buf_len; i += 64)
- {
- size_t bytes_to_copy = buf_len - i;
- if (64 < bytes_to_copy)
- bytes_to_copy = 64;
- memcpy (*buf1 + i + buf1_prefix_len,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-",
- bytes_to_copy);
- memcpy (*buf2 + i,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-",
- bytes_to_copy);
- }
-}
-
-
-/**
- * Helper function which performs a single decoder test
- */
-static int
-test_decode_single (unsigned int test_line,
- int flags, size_t max_payload_size, size_t decode_count,
- size_t buf_step,
- const char *buf, size_t buf_len,
- const char *expected_payload, size_t expected_payload_len,
- int expected_return, int expected_valid, size_t
- expected_streambuf_read_len)
-{
- struct MHD_WebSocketStream *ws = NULL;
- int ret = MHD_WEBSOCKET_STATUS_OK;
-
- /* initialize stream */
- ret = MHD_websocket_stream_init2 (&ws,
- flags,
- max_payload_size,
- malloc,
- realloc,
- free,
- NULL,
- test_rng);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "Allocation failed for decode test in line %u.\n",
- (unsigned int) test_line);
- return 1;
- }
-
- /* perform decoding in a loop */
- size_t streambuf_read_len = 0;
- size_t payload_len = 0;
- char *payload = NULL;
- for (size_t i = 0; i < decode_count; ++i)
- {
- size_t streambuf_read_len_ = 0;
- size_t bytes_to_take = buf_len - streambuf_read_len;
- if ((0 != buf_step) && (buf_step < bytes_to_take))
- bytes_to_take = buf_step;
- ret = MHD_websocket_decode (ws, buf + streambuf_read_len, bytes_to_take,
- &streambuf_read_len_, &payload, &payload_len);
- streambuf_read_len += streambuf_read_len_;
- if (i + 1 < decode_count)
- {
- if (payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- payload_len = 0;
- }
- }
- }
-
- /* check the (last) result */
- if (ret != expected_return)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The return value should be %d, but is %d\n",
- (unsigned int) test_line,
- (int) expected_return,
- (int) ret);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- if (payload_len != expected_payload_len)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The payload_len should be %u, but is %u\n",
- (unsigned int) test_line,
- (unsigned int) expected_payload_len,
- (unsigned int) payload_len);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- if (0 != payload_len)
- {
- if (NULL == payload)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The payload is NULL\n",
- (unsigned int) test_line);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- else if (NULL == expected_payload)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The expected_payload is NULL (wrong test declaration)\n",
- (unsigned int) test_line);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- else if (0 != memcmp (payload, expected_payload, payload_len))
- {
- fprintf (stderr,
- "Decode test failed in line %u: The payload differs from the expected_payload\n",
- (unsigned int) test_line);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- }
- else
- {
- if (NULL != payload)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The payload is not NULL, but payload_len is 0\n",
- (unsigned int) test_line);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- else if (NULL != expected_payload)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The expected_payload is not NULL, but expected_payload_len is 0 (wrong test declaration)\n",
- (unsigned int) test_line);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- }
- if (streambuf_read_len != expected_streambuf_read_len)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The streambuf_read_len should be %u, but is %u\n",
- (unsigned int) test_line,
- (unsigned int) expected_streambuf_read_len,
- (unsigned int) streambuf_read_len);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
- ret = MHD_websocket_stream_is_valid (ws);
- if (ret != expected_valid)
- {
- fprintf (stderr,
- "Decode test failed in line %u: The stream validity should be %u, but is %u\n",
- (unsigned int) test_line,
- (int) expected_valid,
- (int) ret);
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
- return 1;
- }
-
- /* cleanup */
- MHD_websocket_free (ws, payload);
- MHD_websocket_stream_free (ws);
-
- return 0;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_stream_init()` and
- * `MHD_websocket_stream_init2()`
- */
-int
-test_inits ()
-{
- int failed = 0;
- struct MHD_WebSocketStream *ws;
- int ret;
-
- /*
- ------------------------------------------------------------------------------
- All valid flags
- ------------------------------------------------------------------------------
- */
- /* Regular test: all valid flags for init (only the even ones work) */
- for (int i = 0; i < 7; ++i)
- {
- ws = NULL;
- ret = MHD_websocket_stream_init (&ws,
- i,
- 0);
- if (((0 == (i & MHD_WEBSOCKET_FLAG_CLIENT)) &&
- ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws))) ||
- ((0 != (i & MHD_WEBSOCKET_FLAG_CLIENT)) &&
- ((MHD_WEBSOCKET_STATUS_OK == ret) ||
- (NULL != ws))))
- {
- fprintf (stderr,
- "Init test failed in line %u for flags %d.\n",
- (unsigned int) __LINE__,
- (int) i);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- }
- /* Regular test: all valid flags for init2 */
- for (int i = 0; i < 7; ++i)
- {
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- i,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- test_rng);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for flags %d.\n",
- (unsigned int) __LINE__,
- (int) i);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- }
- /* Fail test: Invalid flags for init */
- for (int i = 4; i < 32; ++i)
- {
- int flags = 1 << i;
- ws = NULL;
- ret = MHD_websocket_stream_init (&ws,
- flags,
- 0);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for invalid flags %d.\n",
- (unsigned int) __LINE__,
- (int) flags);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- }
- /* Fail test: Invalid flag for init2 */
- for (int i = 4; i < 32; ++i)
- {
- int flags = 1 << i;
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- flags,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for invalid flags %d.\n",
- (unsigned int) __LINE__,
- (int) flags);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- }
-
- /*
- ------------------------------------------------------------------------------
- max_payload_size
- ------------------------------------------------------------------------------
- */
- /* Regular test: max_payload_size = 0 for init */
- ws = NULL;
- ret = MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 0.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Regular test: max_payload_size = 0 for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 0.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Edge test (success): max_payload_size = 1 for init */
- ws = NULL;
- ret = MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 1);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 1.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Edge test (success): max_payload_size = 1 for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 1,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 1.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Regular test: max_payload_size = 1000 for init */
- ws = NULL;
- ret = MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 1000);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 1000.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Regular test: max_payload_size = 1000 for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 1000,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 1000.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
-#ifdef ENABLE_64BIT_TESTS
- /* Edge test (success): max_payload_size = 0x7FFFFFFFFFFFFFFF for init */
- ws = NULL;
- ret = MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- (uint64_t) 0x7FFFFFFFFFFFFFFF);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 0x7FFFFFFFFFFFFFFF.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Edge test (success): max_payload_size = 0x7FFFFFFFFFFFFFFF for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- (uint64_t) 0x7FFFFFFFFFFFFFFF,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 0x7FFFFFFFFFFFFFFF.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Edge test (fail): max_payload_size = 0x8000000000000000 for init */
- ws = NULL;
- ret = MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- (uint64_t) 0x8000000000000000);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 0x8000000000000000.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Edge test (fail): max_payload_size = 0x8000000000000000 for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- (uint64_t) 0x8000000000000000,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u for max_payload_size 0x8000000000000000.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
-#endif
-
- /*
- ------------------------------------------------------------------------------
- Missing parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: websocket stream variable missing for init */
- ws = NULL;
- ret = MHD_websocket_stream_init (NULL,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Fail test: websocket stream variable missing for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (NULL,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Fail test: malloc missing for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- NULL,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Fail test: realloc missing for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- NULL,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Fail test: free missing for init2 */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- NULL,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Regular test: rng given for server mode (will be ignored) */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- test_rng);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Regular test: cls_rng given for server mode (will be ignored) */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- (void *) 12345,
- test_rng);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Regular test: rng given for client mode */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- test_rng);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL == ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
- /* Fail test: rng not given for client mode */
- ws = NULL;
- ret = MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != ws) )
- {
- fprintf (stderr,
- "Init test failed in line %u %u.\n",
- (unsigned int) __LINE__, ret);
- ++failed;
- }
- if (NULL != ws)
- {
- MHD_websocket_stream_free (ws);
- ws = NULL;
- }
-
- return failed != 0 ? 0x01 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_create_accept_header()`
- */
-int
-test_accept ()
-{
- int failed = 0;
- char accept_key[29];
- int ret;
-
- /*
- ------------------------------------------------------------------------------
- accepting
- ------------------------------------------------------------------------------
- */
- /* Regular test: Test case from RFC6455 4.2.2 */
- memset (accept_key, 0, 29);
- ret = MHD_websocket_create_accept_header ("dGhlIHNhbXBsZSBub25jZQ==",
- accept_key);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != memcmp (accept_key, "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", 29)))
- {
- fprintf (stderr,
- "Accept test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Missing parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: missing sec-key value */
- memset (accept_key, 0, 29);
- ret = MHD_websocket_create_accept_header (NULL,
- accept_key);
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "Accept test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: missing accept variable */
- memset (accept_key, 0, 29);
- ret = MHD_websocket_create_accept_header ("dGhlIHNhbXBsZSBub25jZQ==",
- NULL);
- if (MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret)
- {
- fprintf (stderr,
- "Accept test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- return failed != 0 ? 0x02 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_decode()`
- */
-int
-test_decodes ()
-{
- int failed = 0;
- char *buf1 = NULL, *buf2 = NULL;
-
- /*
- ------------------------------------------------------------------------------
- text frame
- ------------------------------------------------------------------------------
- */
- /* Regular test: Masked text frame from RFC 6455, must succeed for server */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58",
- 11,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Unmasked text frame from RFC 6455, must succeed for client */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x05\x48\x65\x6c\x6c\x6f",
- 7,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 7);
- /* Fail test: Unmasked text frame from RFC 6455, must fail for server */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x05\x48\x65\x6c\x6c\x6f",
- 7,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Fail test: Masked text frame from RFC 6455, must fail for client */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Text frame with UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x90\x00\x00\x00\x00" "This is my n"
- "\xC3\xB6" "te",
- 22,
- "This is my n" "\xC3\xB6" "te",
- 16,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 22);
- /* Fail test: Text frame with with invalid UTF-8 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8F\x00\x00\x00\x00" "This is my n" "\xFF"
- "te",
- 21,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 18);
- /* Fail test: Text frame with broken UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8F\x00\x00\x00\x00" "This is my n" "\xC3"
- "te",
- 21,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 19);
- /* Regular test: Text frame without payload and mask (caller = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x80\x01\x02\x03\x04",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 6);
- /* Fail test: Text frame without payload and no mask (caller = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Text frame without payload and mask (caller = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 2);
- /* Fail test: Text frame without payload and no mask (caller = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x80\x01\x02\x03\x04",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
-
- /*
- ------------------------------------------------------------------------------
- binary frame
- ------------------------------------------------------------------------------
- */
- /* Regular test: Masked binary frame (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58",
- 11,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Unmasked binary frame (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x05\x48\x65\x6c\x6c\x6f",
- 7,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 7);
- /* Fail test: Unmasked binary frame (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x05\x48\x65\x6c\x6c\x6f",
- 7,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Fail test: Masked binary frame (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Binary frame without payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 6);
- /* Regular test: Fragmented binary frame without payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x02\x80\x00\x00\x00\x00\x80\x80\x00\x00\x00\x00",
- 12,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 12);
- /* Regular test: Fragmented binary frame without payload, fragments to the caller, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x02\x80\x00\x00\x00\x00\x80\x80\x00\x00\x00\x00",
- 12,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 6);
- /* Regular test: Fragmented binary frame without payload, fragments to the caller, 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x02\x80\x00\x00\x00\x00\x80\x80\x00\x00\x00\x00",
- 12,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 12);
- /* Regular test: Fragmented binary frame with payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x80\x83\x00\x00\x00\x00\x04\x05\x06",
- 18,
- "\x01\x02\x03\x04\x05\x06",
- 6,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 18);
- /* Regular test: Fragmented binary frame with payload, fragments to the caller, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x80\x83\x00\x00\x00\x00\x04\x05\x06",
- 18,
- "\x01\x02\x03",
- 3,
- MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 9);
- /* Regular test: Fragmented binary frame without payload, fragments to the caller, 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x80\x83\x00\x00\x00\x00\x04\x05\x06",
- 18,
- "\x04\x05\x06",
- 3,
- MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 18);
- /* Regular test: Fragmented binary frame with payload, fragments to the caller, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C",
- 36,
- "\x01\x02\x03",
- 3,
- MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 9);
- /* Regular test: Fragmented binary frame without payload, fragments to the caller, 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C",
- 36,
- "\x04\x05\x06",
- 3,
- MHD_WEBSOCKET_STATUS_BINARY_NEXT_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 18);
- /* Regular test: Fragmented binary frame without payload, fragments to the caller, 3rd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 3,
- 0,
- "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C",
- 36,
- "\x07\x08\x09",
- 3,
- MHD_WEBSOCKET_STATUS_BINARY_NEXT_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 27);
- /* Regular test: Fragmented binary frame without payload, fragments to the caller, 4th call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 4,
- 0,
- "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C",
- 36,
- "\x0A\x0B\x0C",
- 3,
- MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 36);
- /* Regular test: Binary frame with bytes which look like invalid UTF-8 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x85\x00\x00\x00\x00" "Hell\xf6",
- 11,
- "Hell\xf6",
- 5,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Binary frame with bytes which look like broken UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x85\x00\x00\x00\x00" "H\xC3llo",
- 11,
- "H\xC3llo",
- 5,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Binary frame with bytes which look like valid UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x82\x85\x00\x00\x00\x00" "H\xC3\xA4lo",
- 11,
- "H\xC3\xA4lo",
- 5,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Fragmented binary frame with bytes which look like valid UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x02\x82\x00\x00\x00\x00" "H\xC3"
- "\x80\x83\x00\x00\x00\x00" "\xA4lo",
- 17,
- "H\xC3\xA4lo",
- 5,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Regular test: Fragmented binary frame with bytes which look like valid UTF-8 sequence,
- fragments to the caller, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x02\x82\x00\x00\x00\x00" "H\xC3"
- "\x80\x83\x00\x00\x00\x00" "\xA4lo",
- 17,
- "H\xC3",
- 2,
- MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 8);
- /* Regular test: Fragmented binary frame with bytes which look like valid UTF-8 sequence,
- fragments to the caller, 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x02\x82\x00\x00\x00\x00" "H\xC3"
- "\x80\x83\x00\x00\x00\x00" "\xA4lo",
- 17,
- "\xA4lo",
- 3,
- MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
-
- /*
- ------------------------------------------------------------------------------
- close frame
- ------------------------------------------------------------------------------
- */
- /* Regular test: Close frame with no payload but with mask (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 6);
- /* Regular test: Close frame with no payload (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 2);
- /* Fail test: Close frame with no payload and no mask (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Fail test: Close frame with no payload but with mask (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Close frame with 2 byte payload for close reason */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x82\x00\x00\x00\x00\x03\xEB",
- 8,
- "\x03\xEB",
- 2,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 8);
- /* Fail test: Close frame with 1 byte payload (no valid close reason) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x81\x00\x00\x00\x00\x03",
- 7,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Close frame with close reason and UTF-8 description */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x95\x00\x00\x00\x00\x03\xEB"
- "Something was wrong",
- 27,
- "\x03\xEB" "Something was wrong",
- 21,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 27);
- /* Regular test: Close frame with close reason and UTF-8 description (with UTF-8 sequence) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x96\x00\x00\x00\x00\x03\xEB"
- "Something was wr" "\xC3\xB6" "ng",
- 28,
- "\x03\xEB" "Something was wr" "\xC3\xB6" "ng",
- 22,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 28);
- /* Fail test: Close frame with close reason and invalid UTF-8 in description */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x95\x00\x00\x00\x00\x03\xEB"
- "Something was wr" "\xFF" "ng",
- 27,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 24);
- /* Fail test: Close frame with close reason and broken UTF-8 sequence in description */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x95\x00\x00\x00\x00\x03\xEB"
- "Something was wr" "\xC3" "ng",
- 27,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 25);
- /* Edge test (success): Close frame with 125 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\xFD\x00\x00\x00\x00\x03\xEB"
- "Something was wrong, so I decided to close this websocket. I hope you are not angry. But this is also the 123 cap test. :-)",
- 131,
- "\x03\xEB"
- "Something was wrong, so I decided to close this websocket. I hope you are not angry. But this is also the 123 cap test. :-)",
- 125,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 131);
- /* Edge test (failure): Close frame with 126 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\xFE\x00\x7e\x00\x00\x00\x00\x03\xEB"
- "Something was wrong, so I decided to close this websocket. I hope you are not angry. But this is also the 123 cap test. >:-)",
- 134,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Fail test: Close frame with 500 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\xFE\x01\xf4\x00\x00\x00\x00\x03\xEB"
- "The payload of this test isn't parsed.",
- 49,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Edge test (failure): Close frame with 65535 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\xFE\xff\xff\x00\x00\x00\x00\x03\xEB"
- "The payload of this test isn't parsed.",
- 49,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Edge test (failure): Close frame with 65536 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\xFF\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\xEB"
- "The payload of this test isn't parsed.",
- 54,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Fail test: Close frame with 1000000 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\xFF\x00\x00\x00\x00\x00\x0F\x42\x40\x00\x00\x00\x00\x03\xEB"
- "The payload of this test isn't parsed.",
- 54,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
-
- /*
- ------------------------------------------------------------------------------
- ping frame
- ------------------------------------------------------------------------------
- */
- /* Regular test: Ping frame with no payload but with mask (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 6);
- /* Regular test: Ping frame with no payload (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 2);
- /* Fail test: Ping frame with no payload and no mask (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Fail test: Ping frame with no payload but with mask (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Ping frame with some (masked) payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x88\x01\x20\x03\x40\xFF\xFF\xFF\xFF\x00\x00\x00\x00",
- 14,
- "\xFE\xDF\xFC\xBF\x01\x20\x03\x40",
- 8,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 14);
- /* Edge test (success): Ping frame with one byte of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x81\x00\x00\x00\x00" "a",
- 7,
- "a",
- 1,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 7);
- /* Edge test (success): Ping frame with 125 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\xFD\x00\x00\x00\x00"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 131,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 125,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 131);
- /* Edge test (fail): Ping frame with 126 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\xFE\x00\x7E\x00\x00\x00\x00"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 134,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Ping frame with UTF-8 data */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x90\x00\x00\x00\x00" "Ping is bin"
- "\xC3\xA4" "ry.",
- 22,
- "Ping is bin" "\xC3\xA4" "ry.",
- 16,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 22);
- /* Regular test: Ping frame with invalid UTF-8 data */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x8F\x00\x00\x00\x00" "Ping is bin" "\xFF"
- "ry.",
- 21,
- "Ping is bin" "\xFF" "ry.",
- 15,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 21);
- /* Regular test: Ping frame with broken UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x8F\x00\x00\x00\x00" "Ping is bin" "\xC3"
- "ry.",
- 21,
- "Ping is bin" "\xC3" "ry.",
- 15,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 21);
-
- /*
- ------------------------------------------------------------------------------
- pong frame
- ------------------------------------------------------------------------------
- */
- /* Regular test: Pong frame with no payload but with mask (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 6);
- /* Regular test: Pong frame with no payload (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 2);
- /* Fail test: Pong frame with no payload and no mask (decoder = server) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x00",
- 2,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Fail test: Pong frame with no payload but with mask (decoder = client) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_CLIENT
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Pong frame with some (masked) payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x88\x01\x20\x03\x40\xFF\xFF\xFF\xFF\x00\x00\x00\x00",
- 14,
- "\xFE\xDF\xFC\xBF\x01\x20\x03\x40",
- 8,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 14);
- /* Edge test (success): Pong frame with one byte of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x81\x00\x00\x00\x00" "a",
- 7,
- "a",
- 1,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 7);
- /* Edge test (success): Pong frame with 125 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\xFD\x00\x00\x00\x00"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 131,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 125,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 131);
- /* Edge test (fail): Pong frame with 126 bytes of payload */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\xFE\x00\x7E\x00\x00\x00\x00"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 134,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 1);
- /* Regular test: Pong frame with UTF-8 data */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x90\x00\x00\x00\x00" "Pong is bin"
- "\xC3\xA4" "ry.",
- 22,
- "Pong is bin" "\xC3\xA4" "ry.",
- 16,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 22);
- /* Regular test: Pong frame with invalid UTF-8 data */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x8F\x00\x00\x00\x00" "Pong is bin" "\xFF"
- "ry.",
- 21,
- "Pong is bin" "\xFF" "ry.",
- 15,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 21);
- /* Regular test: Pong frame with broken UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8A\x8F\x00\x00\x00\x00" "Pong is bin" "\xC3"
- "ry.",
- 21,
- "Pong is bin" "\xC3" "ry.",
- 15,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 21);
-
- /*
- ------------------------------------------------------------------------------
- fragmentation
- ------------------------------------------------------------------------------
- */
- /* Regular test: Fragmented, masked text frame, we are the server and don't want fragments as caller */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58",
- 17,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Regular test: Fragmented, masked text frame, we are the server and don't want fragments as caller, but call decode two times */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58",
- 17,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_OK,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Regular test: Fragmented, masked text frame, we are the server and want fragments, one call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58",
- 17,
- "Hel",
- 3,
- MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 9);
- /* Regular test: Fragmented, masked text frame, we are the server and want fragments, second call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58",
- 17,
- "lo",
- 2,
- MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Regular test: Fragmented, masked text frame, we are the server and want fragments, third call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 3,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58",
- 17,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_OK,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Regular test: Fragmented, masked text frame, we are the server and want fragments, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x00\x81\x3d\x37\xfa\x21\x51\x80\x81\x37\x37\xfa\x21\x58",
- 23,
- "Hel",
- 3,
- MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 9);
- /* Regular test: Fragmented, masked text frame, we are the server and want fragments, 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x00\x81\x3d\x37\xfa\x21\x51\x80\x81\x37\x37\xfa\x21\x58",
- 23,
- "l",
- 1,
- MHD_WEBSOCKET_STATUS_TEXT_NEXT_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Regular test: Fragmented, masked text frame, we are the server and want fragments, 3rd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 3,
- 0,
- "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x00\x81\x3d\x37\xfa\x21\x51\x80\x81\x37\x37\xfa\x21\x58",
- 23,
- "o",
- 1,
- MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 23);
-
-
- /*
- ------------------------------------------------------------------------------
- invalid flags
- ------------------------------------------------------------------------------
- */
- /* Regular test: Template with valid data for the next tests (this one must succeed) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x85\x00\x00\x00\x00Hello",
- 11,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Fail test: RSV1 flag set */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x91\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: RSV2 flag set */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\xA1\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: RSV3 flag set */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\xC1\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
-
- /*
- ------------------------------------------------------------------------------
- invalid opcodes
- ------------------------------------------------------------------------------
- */
- /* Fail test: Invalid opcode 0 (0 is usually valid, but only if there was a data frame before) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x80\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 3 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x83\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 4 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x84\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 5 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x85\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 6 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x86\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 7 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x87\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 0x0B */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8B\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 0x0C */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8c\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 0x0D */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8d\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 0x0E */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8e\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Invalid opcode 0x0F */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x8f\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
-
-
- /*
- ------------------------------------------------------------------------------
- control frames without FIN flag
- ------------------------------------------------------------------------------
- */
- /* Fail test: Close frame without FIN flag */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x08\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Ping frame without FIN flag */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x09\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Fail test: Pong frame without FIN flag */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x0a\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
-
- /*
- ------------------------------------------------------------------------------
- length checks (without max_payload_len)
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): 0 bytes of payload (requires 1 byte length) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x80\x00\x00\x00\x00",
- 6,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 6);
- /* Edge test (success): 1 byte of payload (requires 1 byte length) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x81\x00\x00\x00\x00" "a",
- 7,
- "a",
- 1,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 7);
- /* Edge test (success): 125 bytes of payload (requires 1 byte length) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xfd\x00\x00\x00\x00"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 131,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 125,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 131);
- /* Edge test (success): 126 bytes of payload (requires 2 byte length) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xfe\x00\x7e\x00\x00\x00\x00"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 134,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 126,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 134);
- /* Edge test (success): 65535 bytes of payload (requires 2 byte length) */
- allocate_length_test_data (&buf1,
- &buf2,
- 65535,
- "\x81\xfe\xff\xff\x00\x00\x00\x00",
- 8);
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- buf1,
- 65535 + 8,
- buf2,
- 65535,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 65535 + 8);
- /* Edge test (success): 65536 bytes of payload (requires 8 byte length) */
- allocate_length_test_data (&buf1,
- &buf2,
- 65536,
- "\x81\xff\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00",
- 14);
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- buf1,
- 65536 + 14,
- buf2,
- 65536,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 65536 + 14);
- /* Regular test: 1 MB of payload */
- allocate_length_test_data (&buf1,
- &buf2,
- 1048576,
- "\x81\xff\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00",
- 14);
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- buf1,
- 1048576 + 14,
- buf2,
- 1048576,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 1048576 + 14);
- /* Regular test: 100 MB of payload */
- allocate_length_test_data (&buf1,
- &buf2,
- 104857600,
- "\x81\xff\x00\x00\x00\x00\x06\x40\x00\x00\x00\x00\x00\x00",
- 14);
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- buf1,
- 104857600 + 14,
- buf2,
- 104857600,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 104857600 + 14);
- if (NULL != buf1)
- {
- free (buf1);
- buf1 = NULL;
- }
- if (NULL != buf2)
- {
- free (buf2);
- buf2 = NULL;
- }
-#ifdef ENABLE_64BIT_TESTS
- /* Edge test (success): Maximum allowed length (here is only the header checked) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xff\x7f\xff\xff\xff\xff\xff\xff\xff",
- 10,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_OK,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 10);
-#else
- /* Edge test (fail): Maximum allowed length
- (the size is allowed, but the system cannot handle this amount of memory) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xff\x7f\xff\xff\xff\xff\xff\xff\xff",
- 10,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 10);
-#endif
- /* Edge test (fail): Too big payload length */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xff\x80\x00\x00\x00\x00\x00\x00\x00",
- 10,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 10);
- /* Edge test (fail): Too big payload length */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xff\xff\xff\xff\xff\xff\xff\xff\xff",
- 10,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 10);
- /* Fail test: Not the smallest payload length syntax used (2 byte instead of 1 byte) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xfe\x00\x05\x00\x00\x00\x00" "abcde",
- 13,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 4);
- /* Fail test: Not the smallest payload length syntax used (8 byte instead of 1 byte) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xff\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00"
- "abcde",
- 13,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 10);
- /* Fail test: Not the smallest payload length syntax used (8 byte instead of 2 byte) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\xff\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00"
- "abcde",
- 13,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 10);
-
- /*
- ------------------------------------------------------------------------------
- length checks (with max_payload_len)
- ------------------------------------------------------------------------------
- */
- /* Regular test: Frame with less payload than specified as limit */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 100,
- 1,
- 0,
- "\x81\x85\x00\x00\x00\x00" "Hello",
- 11,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Edge test (success): Frame with the same payload as the specified limit */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 5,
- 1,
- 0,
- "\x81\x85\x00\x00\x00\x00" "Hello",
- 11,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Edge test (fail): Frame with more payload than specified as limit */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 4,
- 1,
- 0,
- "\x81\x85\x00\x00\x00\x00" "Hello",
- 11,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 2);
- /* Regular test: Fragmented frames with the sum of payload less than specified as limit */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 100,
- 1,
- 0,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Edge test (success): Fragmented frames with the sum of payload equal to the specified limit */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 5,
- 1,
- 0,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Edge test (fail): Fragmented frames with the sum of payload more than specified as limit */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 4,
- 1,
- 0,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 15);
- /* Edge test (success): Fragmented frames with the sum of payload greater than
- the specified limit, but we take fragments (one call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 5,
- 1,
- 0,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- "Hel",
- 3,
- MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 9);
- /* Edge test (success): Fragmented frames with the sum of payload greater than
- the specified limit, but we take fragments (two calls) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 5,
- 2,
- 0,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- "lo",
- 2,
- MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
-
- /*
- ------------------------------------------------------------------------------
- UTF-8 sequences
- ------------------------------------------------------------------------------
- */
- /* Regular test: No UTF-8 characters */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 a ",
- 16,
- " a ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Fail test: A UTF-8 tail character without sequence start character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xA4 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Regular test: A two byte UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xC3\xA4 ",
- 16,
- " \xC3\xA4 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Fail test: A broken two byte UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xC3 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Fail test: A two byte UTF-8 sequence with one UTF-8 tail too much */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xC3\xA4\xA4 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 9);
- /* Regular test: A three byte UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEF\x8F\x8F ",
- 16,
- " \xEF\x8F\x8F ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Fail test: A broken byte UTF-8 sequence (two of three bytes) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEF\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 9);
- /* Fail test: A broken byte UTF-8 sequence (one of three bytes) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEF ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Fail test: A three byte UTF-8 sequence followed by one UTF-8 tail byte */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEF\x8F\x8F\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 10);
- /* Regular test: A four byte UTF-8 sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF2\x8F\x8F\x8F ",
- 16,
- " \xF2\x8F\x8F\x8F ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Fail test: A broken four byte UTF-8 sequence (three of four bytes) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF2\x8F\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 10);
- /* Fail test: A broken four byte UTF-8 sequence (two of four bytes) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF2\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 9);
- /* Fail test: A broken four byte UTF-8 sequence (one of four bytes) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF2 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Fail test: A four byte UTF-8 sequence followed by UTF-8 tail */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF2\x8F\x8F\x8F\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 11);
- /* Fail test: A five byte UTF-8 sequence (only up to four bytes allowed) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xFB\x8F\x8F\x8F\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Fail test: A six byte UTF-8 sequence (only up to four bytes allowed) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xFD\x8F\x8F\x8F\x8F\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Fail test: A seven byte UTF-8 sequence (only up to four bytes allowed) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xFE\x8F\x8F\x8F\x8F\x8F\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Fail test: A eight byte UTF-8 sequence (only up to four bytes allowed) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xFF\x8F\x8F\x8F\x8F\x8F\x8F\x8F ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Edge test (success): The maximum allowed UTF-8 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF4\x8F\xBF\xBF ",
- 16,
- " \xF4\x8F\xBF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The maximum allowed UTF-8 character + 1 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF4\x90\x80\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (success): The last valid UTF8-1 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \x7F ",
- 16,
- " \x7F ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The value after the last valid UTF8-1 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Edge test (fail): The value before the first valid UTF8-2 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xC1\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Edge test (success): The first valid UTF8-2 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xC2\x80 ",
- 16,
- " \xC2\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-2 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xDF\xBF ",
- 16,
- " \xDF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The value after the lst valid UTF8-2 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xE0\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (fail): The value before the first valid UTF8-3 character (tail 1) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xE0\x9F\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (success): The first valid UTF8-3 character (tail 1) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xE0\xA0\x80 ",
- 16,
- " \xE0\xA0\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-3 character (tail 1) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xE0\xBF\xBF ",
- 16,
- " \xE0\xBF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The value after the first valid UTF8-3 character (tail 1) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xE0\xC0\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (success): The first valid UTF8-3 character (tail 2) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xE1\x80\x80 ",
- 16,
- " \xE1\x80\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-3 character (tail 2) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEC\xBF\xBF ",
- 16,
- " \xEC\xBF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The value after the last valid UTF8-3 character (tail 2) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEC\xC0\xBF ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (fail): The value before the first valid UTF8-3 character (tail 3) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xED\x7F\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (success): The first valid UTF8-3 character (tail 3) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xED\x80\x80 ",
- 16,
- " \xED\x80\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-3 character (tail 3) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xED\x9F\xBF ",
- 16,
- " \xED\x9F\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The value after the last valid UTF8-3 character (tail 3) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xED\xA0\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (fail): The value before the first valid UTF8-3 character (tail 4) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEE\x7F\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (success): The first valid UTF8-3 character (tail 4) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEE\x80\x80 ",
- 16,
- " \xEE\x80\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-3 character (tail 4) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEF\xBF\xBF ",
- 16,
- " \xEF\xBF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The value after the last valid UTF8-3 character (tail 4) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEF\xBF\xC0 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 9);
- /* Edge test (fail): The value after the last valid UTF8-3 character (tail 4) #2 */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xEF\xC0\xBF ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (fail): The value before the first valid UTF8-4 character (tail 1) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF0\x8F\x80\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (success): The first valid UTF8-4 character (tail 1) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF0\x90\x80\x80 ",
- 16,
- " \xF0\x90\x80\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-4 character (tail 1) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF0\xBF\xBF\xBF ",
- 16,
- " \xF0\xBF\xBF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The first valid UTF8-4 character (tail 2) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF1\x80\x80\x80 ",
- 16,
- " \xF1\x80\x80\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-4 character (tail 2) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF3\xBF\xBF\xBF ",
- 16,
- " \xF3\xBF\xBF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): A value before the last valid UTF8-4 character in the second byte (tail 2) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF3\x7F\x80\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (fail): A value after the last valid UTF8-4 character in the second byte (tail 2) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF3\xC0\x80\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (success): The first valid UTF8-4 character (tail 3) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF4\x80\x80\x80 ",
- 16,
- " \xF4\x80\x80\x80 ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (success): The last valid UTF8-4 character (tail 3) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF4\x8F\xBF\xBF ",
- 16,
- " \xF4\x8F\xBF\xBF ",
- 10,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 16);
- /* Edge test (fail): The value after the last valid UTF8-4 character (tail 3) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF4\x90\x80\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 8);
- /* Edge test (fail): The first byte value the last valid UTF8-4 character */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x8A\x00\x00\x00\x00 \xF5\x90\x80\x80 ",
- 16,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
-
- /*
- ------------------------------------------------------------------------------
- Unfinished UTF-8 sequence between fragmented text frame
- ------------------------------------------------------------------------------
- */
- /* Regular test: UTF-8 sequence between fragments, no fragmentation for the caller */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x8D\x00\x00\x00\x00" "This is my n"
- "\xC3\x80\x83\x00\x00\x00\x00\xB6" "te",
- 28,
- "This is my n" "\xC3\xB6" "te",
- 16,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 28);
- /* Regular test: UTF-8 sequence between fragments, fragmentation for the caller, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x8D\x00\x00\x00\x00" "This is my n"
- "\xC3\x80\x83\x00\x00\x00\x00\xB6" "te",
- 28,
- "This is my n",
- 12,
- MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 19);
- /* Regular test: UTF-8 sequence between fragments, fragmentation for the caller, 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x8D\x00\x00\x00\x00" "This is my n"
- "\xC3\x80\x83\x00\x00\x00\x00\xB6" "te",
- 28,
- "\xC3\xB6" "te",
- 4,
- MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 28);
- /* Edge test (success): UTF-8 sequence between fragments, but nothing before, fragmentation for the caller, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x81\x00\x00\x00\x00\xC3\x80\x81\x00\x00\x00\x00\xB6",
- 14,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 7);
- /* Edge test (success): UTF-8 sequence between fragments, but nothing before, fragmentation for the caller, 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x81\x00\x00\x00\x00\xC3\x80\x81\x00\x00\x00\x00\xB6",
- 14,
- "\xC3\xB6",
- 2,
- MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 14);
-
- /*
- ------------------------------------------------------------------------------
- Decoding with broken stream
- ------------------------------------------------------------------------------
- */
- /* Failure test: Invalid sequence */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\xFF\x81\x85\x00\x00\x00\x00" "Hello",
- 12,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Failure test: Call after invalidated stream */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\xFF\x81\x85\x00\x00\x00\x00" "Hello",
- 12,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_STREAM_BROKEN,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Failure test: Call after invalidated stream (but with different buffer) */
- {
- struct MHD_WebSocketStream *ws;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0))
- {
- size_t streambuf_read_len = 0;
- char *payload = NULL;
- size_t payload_len = 0;
- int ret = 0;
- ret = MHD_websocket_decode (ws,
- "\xFF",
- 1,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if (MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR != ret)
- {
- fprintf (stderr,
- "Test failed in line %u: The return value should be -1, but is %d\n",
- (unsigned int) __LINE__,
- (int) ret);
- ++failed;
- }
- else
- {
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00" "Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if (MHD_WEBSOCKET_STATUS_STREAM_BROKEN != ret)
- {
- fprintf (stderr,
- "Test failed in line %u: The return value should be -2, but is %d\n",
- (unsigned int) __LINE__,
- (int) ret);
- ++failed;
- }
- }
- MHD_websocket_stream_free (ws);
- }
- else
- {
- fprintf (stderr,
- "Individual test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- /*
- ------------------------------------------------------------------------------
- frame after close frame
- ------------------------------------------------------------------------------
- */
- /* Regular test: Close frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x88\x80\x00\x00\x00\x00\x81\x85\x00\x00\x00\x00"
- "Hello",
- 17,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 6);
- /* Failure test: Text frame after close frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x88\x80\x00\x00\x00\x00\x81\x85\x00\x00\x00\x00"
- "Hello",
- 17,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 6);
- /* Failure test: Binary frame after close frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x88\x80\x00\x00\x00\x00\x82\x85\x00\x00\x00\x00"
- "Hello",
- 17,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 6);
- /* Failure test: Continue frame after close frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x88\x80\x00\x00\x00\x00\x80\x85\x00\x00\x00\x00"
- "Hello",
- 17,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 6);
- /* Regular test: Ping frame after close frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x88\x80\x00\x00\x00\x00\x89\x85\x00\x00\x00\x00"
- "Hello",
- 17,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 17);
- /* Regular test: Pong frame after close frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x88\x80\x00\x00\x00\x00\x8A\x85\x00\x00\x00\x00"
- "Hello",
- 17,
- "Hello",
- 5,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 17);
- /* Regular test: Close frame after close frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x88\x80\x00\x00\x00\x00\x88\x80\x00\x00\x00\x00",
- 12,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 12);
-
- /*
- ------------------------------------------------------------------------------
- decoding byte-by-byte
- ------------------------------------------------------------------------------
- */
- /* Regular test: Text frame, 2 bytes per loop, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 2,
- "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/",
- 23,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_OK,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 2);
- /* Regular test: Text frame, 2 bytes per loop, 11th call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 11,
- 2,
- "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/",
- 23,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_OK,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 22);
- /* Regular test: Text frame, 2 bytes per loop, 12th call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 12,
- 2,
- "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/",
- 23,
- "This is the test.",
- 17,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 23);
- /* Regular test: Text frame, 1 byte per loop, 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 1,
- "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/",
- 23,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_OK,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 1);
- /* Regular test: Text frame, 1 byte per loop, 22nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 22,
- 1,
- "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/",
- 23,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_OK,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 22);
- /* Regular test: Text frame, 1 byte per loop, 23rd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 23,
- 1,
- "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/",
- 23,
- "This is the test.",
- 17,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 23);
-
- /*
- ------------------------------------------------------------------------------
- mix of fragmented data frames and control frames
- ------------------------------------------------------------------------------
- */
- /* Regular test: Fragmented text frame mixed with one ping frame (1st call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x89\x80\x00\x00\x00\x00"
- "\x80\x8C\x00\x00\x00\x00" "is the test.",
- 35,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Regular test: Fragmented text frame mixed with one ping frame (2nd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x89\x80\x00\x00\x00\x00"
- "\x80\x8C\x00\x00\x00\x00" "is the test.",
- 35,
- "This is the test.",
- 17,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 35);
- /* Regular test: Fragmented text frame mixed with one close frame (1st call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x88\x80\x00\x00\x00\x00"
- "\x80\x8C\x00\x00\x00\x00" "is the test.",
- 35,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 17);
- /* Fail test: Fragmented text frame mixed with one ping frame (2nd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x88\x80\x00\x00\x00\x00"
- "\x80\x8C\x00\x00\x00\x00" "is the test.",
- 35,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 17);
- /* Regular test: Fragmented text frame mixed with one ping frame, the caller wants fragments (1st call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x89\x80\x00\x00\x00\x00"
- "\x80\x8C\x00\x00\x00\x00" "is the test.",
- 35,
- "This ",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Fragmented text frame mixed with one ping frame, the caller wants fragments (2nd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x89\x80\x00\x00\x00\x00"
- "\x80\x8C\x00\x00\x00\x00" "is the test.",
- 35,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 17);
- /* Regular test: Fragmented text frame mixed with one ping frame, the caller wants fragments (3rd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 3,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x89\x80\x00\x00\x00\x00"
- "\x80\x8C\x00\x00\x00\x00" "is the test.",
- 35,
- "is the test.",
- 12,
- MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 35);
-
- /*
- ------------------------------------------------------------------------------
- mix of fragmented data frames and data frames
- ------------------------------------------------------------------------------
- */
- /* Fail test: Fragmented text frame mixed with one non-fragmented binary frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x82\x81\x00\x00\x00\x00"
- "a\x80\x8C\x00\x00\x00\x00" "is the test.",
- 36,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 11);
- /* Regular test: Fragmented text frame mixed with one non-fragmented binary frame; the caller wants fragments; 1st call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x82\x81\x00\x00\x00\x00"
- "a\x80\x8C\x00\x00\x00\x00" "is the test.",
- 36,
- "This ",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Fail test: Fragmented text frame mixed with one non-fragmented binary frame; the caller wants fragments; 2nd call */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x82\x81\x00\x00\x00\x00"
- "a\x80\x8C\x00\x00\x00\x00" "is the test.",
- 36,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 11);
- /* Fail test: Fragmented text frame mixed with one fragmented binary frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x02\x81\x00\x00\x00\x00"
- "a\x80\x8C\x00\x00\x00\x00" "is the test.",
- 36,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 11);
- /* Fail test: Fragmented text frame, continue frame, non-fragmented binary frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x00\x8C\x00\x00\x00\x00"
- "is the test.\x82\x81\x00\x00\x00\x00" "a",
- 36,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 29);
- /* Fail test: Fragmented text frame, continue frame, fragmented binary frame */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x01\x85\x00\x00\x00\x00"
- "This \x00\x8C\x00\x00\x00\x00"
- "is the test.\x02\x81\x00\x00\x00\x00" "a",
- 36,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 29);
-
- /*
- ------------------------------------------------------------------------------
- multiple data frames
- ------------------------------------------------------------------------------
- */
- /* Regular test: Text frame, binary frame, text frame (1st call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x81\x85\x00\x00\x00\x00"
- "This \x82\x87\x00\x00\x00\x00"
- "is the \x81\x85\x00\x00\x00\x00" "test.",
- 35,
- "This ",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Text frame, binary frame, text frame (2nd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x81\x85\x00\x00\x00\x00"
- "This \x82\x87\x00\x00\x00\x00"
- "is the \x81\x85\x00\x00\x00\x00" "test.",
- 35,
- "is the ",
- 7,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 24);
- /* Regular test: Text frame, binary frame, text frame (3rd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 3,
- 0,
- "\x81\x85\x00\x00\x00\x00"
- "This \x82\x87\x00\x00\x00\x00"
- "is the \x81\x85\x00\x00\x00\x00" "test.",
- 35,
- "test.",
- 5,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 35);
- /*
- ------------------------------------------------------------------------------
- multiple control frames
- ------------------------------------------------------------------------------
- */
- /* Regular test: Ping frame, pong frame, close frame (1st call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- "\x89\x85\x00\x00\x00\x00"
- "This \x8A\x87\x00\x00\x00\x00"
- "is the \x88\x85\x00\x00\x00\x00" "test.",
- 35,
- "This ",
- 5,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 11);
- /* Regular test: Ping frame, pong frame, close frame (2nd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 2,
- 0,
- "\x89\x85\x00\x00\x00\x00"
- "This \x8A\x87\x00\x00\x00\x00"
- "is the \x88\x85\x00\x00\x00\x00" "test.",
- 35,
- "is the ",
- 7,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- 24);
- /* Regular test: Ping frame, pong frame, close frame (3rd call) */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 3,
- 0,
- "\x89\x85\x00\x00\x00\x00"
- "This \x8A\x87\x00\x00\x00\x00"
- "is the \x88\x85\x00\x00\x00\x00" "test.",
- 35,
- "test.",
- 5,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- 35);
-
- /*
- ------------------------------------------------------------------------------
- generated close frames for errors
- ------------------------------------------------------------------------------
- */
- /* Regular test: Close frame generated for protocol error */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS
- |
- MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR,
- 0,
- 1,
- 0,
- "\xFF",
- 1,
- "\x88\x02\x03\xEA",
- 4,
- MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 0);
- /* Regular test: Close frame generated for UTF-8 sequence error */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS
- |
- MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR,
- 0,
- 1,
- 0,
- "\x81\x85\x00\x00\x00\x00T\xFFst.",
- 11,
- "\x88\x02\x03\xEF",
- 4,
- MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 7);
- /* Regular test: Close frame generated for message size exceeded */
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS
- |
- MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR,
- 3,
- 1,
- 0,
- "\x81\x85\x00\x00\x00\x00T\xFFst.",
- 11,
- "\x88\x02\x03\xF1",
- 4,
- MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED,
- MHD_WEBSOCKET_VALIDITY_INVALID,
- 2);
-
- /*
- ------------------------------------------------------------------------------
- terminating NUL character
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *ws;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0))
- {
- size_t streambuf_read_len = 0;
- char *payload = NULL;
- size_t payload_len = 0;
- int ret = 0;
-
- /* Regular test: text frame */
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00" "Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_TEXT_FRAME != ret) ||
- (5 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("Hello", payload, 5 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- /* Regular test: text frame fragment */
- ret = MHD_websocket_decode (ws,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_TEXT_FRAME != ret) ||
- (5 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("Hello", payload, 5 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- /* Regular test: binary frame */
- ret = MHD_websocket_decode (ws,
- "\x82\x85\x00\x00\x00\x00" "Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_BINARY_FRAME != ret) ||
- (5 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("Hello", payload, 5 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- /* Regular test: binary frame fragment */
- ret = MHD_websocket_decode (ws,
- "\x02\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_BINARY_FRAME != ret) ||
- (5 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("Hello", payload, 5 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- MHD_websocket_stream_free (ws);
- }
- else
- {
- fprintf (stderr,
- "Individual decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
- {
- struct MHD_WebSocketStream *ws;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS,
- 0))
- {
- size_t streambuf_read_len = 0;
- char *payload = NULL;
- size_t payload_len = 0;
- int ret = 0;
-
- /* Regular test: text frame fragment (caller wants fragment, 1st call) */
- ret = MHD_websocket_decode (ws,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo",
- 17,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT != ret) ||
- (3 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("Hel", payload, 3 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- /* Regular test: text frame fragment (caller wants fragment, 2nd call) */
- ret = MHD_websocket_decode (ws,
- "\x01\x83\x00\x00\x00\x00"
- "Hel\x80\x82\x00\x00\x00\x00" "lo"
- + streambuf_read_len,
- 17 - streambuf_read_len,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT != ret) ||
- (2 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("lo", payload, 2 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- /* Regular test: text frame fragment with broken UTF-8 sequence (caller wants fragment, 1st call) */
- ret = MHD_websocket_decode (ws,
- "\x01\x83\x00\x00\x00\x00"
- "He\xC3\x80\x82\x00\x00\x00\x00" "\xB6o",
- 17,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT != ret) ||
- (2 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("He", payload, 2 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- /* Regular test: text frame fragment with broken UTF-8 sequence (caller wants fragment, 2nd call) */
- ret = MHD_websocket_decode (ws,
- "\x01\x83\x00\x00\x00\x00"
- "He\xC3\x80\x82\x00\x00\x00\x00" "\xB6o"
- + streambuf_read_len,
- 17 - streambuf_read_len,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT != ret) ||
- (3 != payload_len) ||
- (NULL == payload) ||
- (0 != memcmp ("\xC3\xB6o", payload, 3 + 1)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- payload = NULL;
- }
-
- MHD_websocket_stream_free (ws);
- }
- else
- {
- fprintf (stderr,
- "Individual decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
-
- /*
- ------------------------------------------------------------------------------
- invalid parameters
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *ws;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0))
- {
- size_t streambuf_read_len = 0;
- char *payload = NULL;
- size_t payload_len = 0;
- int ret = 0;
-
- /* Failure test: `ws` is NULL */
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (NULL,
- "\x81\x85\x00\x00\x00\x00Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (0 != streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- /* Failure test: `buf` is NULL, while `buf_len` != 0 */
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- NULL,
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (0 != streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- /* Failure test: `streambuf_read_len` is NULL */
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00Hello",
- 11,
- NULL,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- /* Failure test: `payload` is NULL */
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00Hello",
- 11,
- &streambuf_read_len,
- NULL,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != payload_len) ||
- (0 != streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Failure test: `payload_len` is NULL */
- payload = (char *) (uintptr_t) 0xBAADF00D;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00Hello",
- 11,
- &streambuf_read_len,
- &payload,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != payload) ||
- (0 != streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- /* Regular test: `buf` is NULL and `buf_len` is 0 */
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- NULL,
- 0,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (0 != streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- /* Regular test: `buf` is not NULL and `buf_len` is 0 */
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00Hello",
- 0,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (0 != streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
-
- MHD_websocket_stream_free (ws);
- }
- else
- {
- fprintf (stderr,
- "Parameter decode tests failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- /*
- ------------------------------------------------------------------------------
- validity after temporary out-of-memory
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *ws;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- size_t streambuf_read_len = 0;
- char *payload = NULL;
- size_t payload_len = 0;
- int ret = 0;
-
- /* Failure test: No memory allocation at the start */
- disable_alloc = 1;
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (1000 == streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- MHD_websocket_stream_free (ws);
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- /* Failure test: No memory allocation after fragmented frame */
- disable_alloc = 0;
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- "\x01\x83\x00\x00\x00\x00" "Hel",
- 9,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (9 != streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (
- ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- disable_alloc = 1;
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- streambuf_read_len = 1000;
- ret = MHD_websocket_decode (ws,
- "\x80\x82\x00\x00\x00\x00" "lo",
- 8,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) ||
- (NULL != payload) ||
- (0 != payload_len) ||
- (1000 == streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (
- ws)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
- /* Regular test: Success after memory allocation ok again */
- /* (streambuf_read_len may not be overwritten for this test) */
- disable_alloc = 0;
- payload = (char *) (uintptr_t) 0xBAADF00D;
- payload_len = 0x87654321;
- size_t old_streambuf_read_len = streambuf_read_len;
- ret = MHD_websocket_decode (ws,
- "\x80\x82\x00\x00\x00\x00lo"
- + old_streambuf_read_len,
- 8 - old_streambuf_read_len,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_TEXT_FRAME != ret) ||
- (NULL == payload) ||
- (5 != payload_len) ||
- (8 != streambuf_read_len + old_streambuf_read_len) ||
- (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (
- ws)) ||
- (0 != memcmp ("Hello", payload, 5)))
- {
- fprintf (stderr,
- "Decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == payload)
- {
- payload = NULL;
- }
- if (NULL != payload)
- {
- MHD_websocket_free (ws, payload);
- }
-
- MHD_websocket_stream_free (ws);
- }
- else
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
- else
- {
- fprintf (stderr,
- "Memory decode tests failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- /*
- ------------------------------------------------------------------------------
- memory leak test, when freeing while decoding
- ------------------------------------------------------------------------------
- */
- {
- disable_alloc = 0;
- struct MHD_WebSocketStream *ws;
- size_t streambuf_read_len = 0;
- char *payload = NULL;
- size_t payload_len = 0;
- int ret = 0;
-
- /* Regular test: Free while decoding of data frame */
- open_allocs = 0;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- ret = MHD_websocket_decode (ws,
- "\x81\x85\x00\x00\x00\x00Hel",
- 9,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != payload_len) ||
- (NULL != payload) ||
- (9 != streambuf_read_len) )
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- ret = MHD_websocket_stream_free (ws);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (0 != open_allocs)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u (memory leak detected)\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
- else
- {
- fprintf (stderr,
- "Memory test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /* Regular test: Free while decoding of control frame */
- open_allocs = 0;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- ret = MHD_websocket_decode (ws,
- "\x88\x85\x00\x00\x00\x00Hel",
- 9,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != payload_len) ||
- (NULL != payload) ||
- (9 != streambuf_read_len) )
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- ret = MHD_websocket_stream_free (ws);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (0 != open_allocs)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u (memory leak detected)\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
- else
- {
- fprintf (stderr,
- "Memory test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /* Regular test: Free while decoding of fragmented data frame */
- open_allocs = 0;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- ret = MHD_websocket_decode (ws,
- "\x01\x85\x00\x00\x00\x00Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != payload_len) ||
- (NULL != payload) ||
- (11 != streambuf_read_len) )
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- ret = MHD_websocket_stream_free (ws);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (0 != open_allocs)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u (memory leak detected)\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
- else
- {
- fprintf (stderr,
- "Memory test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: Free while decoding of continued fragmented data frame */
- open_allocs = 0;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- ret = MHD_websocket_decode (ws,
- "\x01\x85\x00\x00\x00\x00Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != payload_len) ||
- (NULL != payload) ||
- (11 != streambuf_read_len) )
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- ret = MHD_websocket_decode (ws,
- "\x80\x85\x00\x00\x00\x00Hel",
- 9,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != payload_len) ||
- (NULL != payload) ||
- (9 != streambuf_read_len) )
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- ret = MHD_websocket_stream_free (ws);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (0 != open_allocs)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u (memory leak detected)\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
- else
- {
- fprintf (stderr,
- "Memory test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: Free while decoding of control frame during fragmented data frame */
- open_allocs = 0;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws,
- MHD_WEBSOCKET_FLAG_SERVER
- |
- MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- ret = MHD_websocket_decode (ws,
- "\x01\x85\x00\x00\x00\x00Hello",
- 11,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != payload_len) ||
- (NULL != payload) ||
- (11 != streambuf_read_len) )
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- ret = MHD_websocket_decode (ws,
- "\x88\x85\x00\x00\x00\x00Hel",
- 9,
- &streambuf_read_len,
- &payload,
- &payload_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (0 != payload_len) ||
- (NULL != payload) ||
- (9 != streambuf_read_len) )
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- ret = MHD_websocket_stream_free (ws);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (0 != open_allocs)
- {
- fprintf (stderr,
- "Memory decode test failed in line %u (memory leak detected)\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
- else
- {
- fprintf (stderr,
- "Memory test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- if (NULL != buf1)
- {
- free (buf1);
- buf1 = NULL;
- }
- if (NULL != buf2)
- {
- free (buf2);
- buf2 = NULL;
- }
- return failed != 0 ? 0x04 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_encode_text()`
- */
-int
-test_encodes_text ()
-{
- int failed = 0;
- struct MHD_WebSocketStream *wss;
- struct MHD_WebSocketStream *wsc;
- int ret;
- char *buf1 = NULL, *buf2 = NULL;
- char *frame = NULL;
- size_t frame_len = 0;
- int utf8_step = 0;
-
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc,
- MHD_WEBSOCKET_FLAG_CLIENT,
- 0,
- malloc,
- realloc,
- free,
- NULL,
- test_rng))
- {
- fprintf (stderr,
- "No encode text tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- return 0x08;
- }
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0))
- {
- fprintf (stderr,
- "No encode text tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- return 0x08;
- }
-
- /*
- ------------------------------------------------------------------------------
- Encoding
- ------------------------------------------------------------------------------
- */
- /* Regular test: Some data without UTF-8, we are server */
- ret = MHD_websocket_encode_text (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Some data without UTF-8, we are client */
- ret = MHD_websocket_encode_text (wsc,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (15 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "blablabla",
- 9,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Some data with UTF-8, we are server */
- ret = MHD_websocket_encode_text (wss,
- "bla" "\xC3\xA4" "blabla",
- 11,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (13 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x0B" "bla" "\xC3\xA4" "blabla", 13)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Some data with UTF-8, we are client */
- ret = MHD_websocket_encode_text (wsc,
- "bla" "\xC3\xA4" "blabla",
- 11,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (17 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "bla" "\xC3\xA4" "blabla",
- 11,
- MHD_WEBSOCKET_STATUS_TEXT_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Edge test (success): Some data with NUL characters, we are server */
- ret = MHD_websocket_encode_text (wss,
- "bla" "\0\0\0" "bla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x09" "bla" "\0\0\0" "bla", 11)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: Some data with broken UTF-8, we are server */
- ret = MHD_websocket_encode_text (wss,
- "bla" "\xC3" "blabla",
- 10,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Fragmentation
- ------------------------------------------------------------------------------
- */
- /* Regular test: Some data without UTF-8 */
- ret = MHD_websocket_encode_text (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x81\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: First fragment without UTF-8 */
- ret = MHD_websocket_encode_text (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_FIRST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x01\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Middle fragment without UTF-8 */
- ret = MHD_websocket_encode_text (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x00\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment without UTF-8 */
- ret = MHD_websocket_encode_text (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): First fragment with UTF-8 on the edge */
- ret = MHD_websocket_encode_text (wss,
- "blablabl\xC3",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_FIRST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1 != utf8_step) ||
- (0 != memcmp (frame, "\x01\x09" "blablabl\xC3", 11)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Last fragment with UTF-8 on the edge */
- ret = MHD_websocket_encode_text (wss,
- "\xA4" "blablabla",
- 10,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (12 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0A" "\xA4" "blablabla", 12)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: Last fragment with UTF-8 on the edge (here with wrong old utf8_step) */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_NORMAL;
- ret = MHD_websocket_encode_text (wss,
- "\xA4" "blablabla",
- 10,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF2TAIL_1OF1 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1;
- ret = MHD_websocket_encode_text (wss,
- "\xA4" "blablabla",
- 10,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (12 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0A" "\xA4" "blablabla", 12)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL1_1OF2 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2;
- ret = MHD_websocket_encode_text (wss,
- "\xA0\x80" "blablabla",
- 11,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (13 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0B" "\xA0\x80" "blablabla", 13)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL2_1OF2 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2;
- ret = MHD_websocket_encode_text (wss,
- "\x80\x80" "blablabla",
- 11,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (13 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0B" "\x80\x80" "blablabla", 13)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL_1OF2 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2;
- ret = MHD_websocket_encode_text (wss,
- "\x80\x80" "blablabla",
- 11,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (13 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0B" "\x80\x80" "blablabla", 13)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL_2OF2 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2;
- ret = MHD_websocket_encode_text (wss,
- "\x80" " blablabla",
- 11,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (13 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0B" "\x80" " blablabla", 13)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL1_1OF3 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3;
- ret = MHD_websocket_encode_text (wss,
- "\x90\x80\x80" "blablabla",
- 12,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (14 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0C" "\x90\x80\x80" "blablabla", 14)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL2_1OF3 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3;
- ret = MHD_websocket_encode_text (wss,
- "\x80\x80\x80" "blablabla",
- 12,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (14 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0C" "\x80\x80\x80" "blablabla", 14)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL_1OF3 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3;
- ret = MHD_websocket_encode_text (wss,
- "\x80\x80\x80" "blablabla",
- 12,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (14 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0C" "\x80\x80\x80" "blablabla", 14)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL_2OF3 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3;
- ret = MHD_websocket_encode_text (wss,
- "\x80\x80" " blablabla",
- 12,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (14 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0C" "\x80\x80" " blablabla", 14)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL_3OF3 */
- utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3;
- ret = MHD_websocket_encode_text (wss,
- "\x80" " blablabla",
- 12,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (14 != frame_len) ||
- (NULL == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x0C" "\x80" " blablabla", 14)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Length checks
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): Text frame without data */
- ret = MHD_websocket_encode_text (wss,
- NULL,
- 0,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x00", 2)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Text frame with 1 byte of data */
- ret = MHD_websocket_encode_text (wss,
- "a",
- 1,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (3 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x01" "a", 3)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Text frame with 125 bytes of data */
- ret = MHD_websocket_encode_text (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 125,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (127 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x7D"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 127)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Text frame with 126 bytes of data */
- ret = MHD_websocket_encode_text (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 126,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (130 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x7E\x00\x7E"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 130)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Text frame with 65535 bytes of data */
- allocate_length_test_data (&buf1,
- &buf2,
- 65535,
- "\x81\x7E\xFF\xFF",
- 4);
- ret = MHD_websocket_encode_text (wss,
- buf2,
- 65535,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (65535 + 4 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, buf1, 65535 + 4)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Text frame with 65536 bytes of data */
- allocate_length_test_data (&buf1,
- &buf2,
- 65536,
- "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00",
- 10);
- ret = MHD_websocket_encode_text (wss,
- buf2,
- 65536,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (65536 + 10 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, buf1, 65536 + 10)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Text frame with 100 MB of data */
- allocate_length_test_data (&buf1,
- &buf2,
- 104857600,
- "\x81\x7F\x00\x00\x00\x00\x06\x40\x00\x00",
- 10);
- ret = MHD_websocket_encode_text (wss,
- buf2,
- 104857600,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (104857600 + 10 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, buf1, 104857600 + 10)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- if (NULL != buf1)
- {
- free (buf1);
- buf1 = NULL;
- }
- if (NULL != buf2)
- {
- free (buf2);
- buf2 = NULL;
- }
-#ifdef ENABLE_64BIT_TESTS
- /* Fail test: frame_len is greater than 0x7FFFFFFFFFFFFFFF
- (this is the maximum allowed payload size) */
- frame_len = 0;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- (uint64_t) 0x8000000000000000,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-#endif
-
- /*
- ------------------------------------------------------------------------------
- Wrong parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: `ws` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_text (NULL,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `payload_utf8` not passed, but `payload_utf8_len` != 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_text (wss,
- NULL,
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `payload_utf8` passed, but `payload_utf8_len` == 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 0,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (0 != memcmp (frame, "\x81\x00", 2)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `frame` not passed */
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- NULL,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: `frame_len` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- NULL,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `utf8_step` passed for non-fragmentation
- (is allowed and `utf8_step` will be filled then) */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- utf8_step = -99;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x81\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `utf8_step` passed for non-fragmentation with invalid UTF-8
- (is allowed and `utf8_step` will be filled then) */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- utf8_step = -99;
- ret = MHD_websocket_encode_text (wss,
- "ab\xC3",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) ||
- (MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1 != utf8_step) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `utf8_step` not passed for fragmentation #1 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_FIRST,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `utf8_step` not passed for fragmentation #2 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `utf8_step` not passed for fragmentation #3 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `utf8_step` passed for fragmentation #1 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- utf8_step = -99;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_FIRST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x01\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `utf8_step` passed for fragmentation #2 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- utf8_step = MHD_WEBSOCKET_UTF8STEP_NORMAL;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x00\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `utf8_step` passed for fragmentation #3 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- utf8_step = MHD_WEBSOCKET_UTF8STEP_NORMAL;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ||
- (0 != memcmp (frame, "\x80\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `fragmentation` has an invalid value */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- utf8_step = -99;
- ret = MHD_websocket_encode_text (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_LAST + 1,
- &frame,
- &frame_len,
- &utf8_step);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) ||
- (-99 != utf8_step) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- validity after temporary out-of-memory
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *wsx;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- /* Fail test: allocation while no memory available */
- disable_alloc = 1;
- ret = MHD_websocket_encode_text (wsx,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
- /* Regular test: allocation while memory is available again */
- disable_alloc = 0;
- ret = MHD_websocket_encode_text (wsx,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x81\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode text test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
-
- MHD_websocket_stream_free (wsx);
- }
- else
- {
- fprintf (stderr,
- "Couldn't perform memory test for text encoding in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- if (NULL != buf1)
- free (buf1);
- if (NULL != buf2)
- free (buf2);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- if (NULL != wss)
- MHD_websocket_stream_free (wss);
-
- return failed != 0 ? 0x08 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_encode_binary()`
- */
-int
-test_encodes_binary ()
-{
- int failed = 0;
- struct MHD_WebSocketStream *wss;
- struct MHD_WebSocketStream *wsc;
- int ret;
- char *buf1 = NULL, *buf2 = NULL;
- char *frame = NULL;
- size_t frame_len = 0;
-
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc,
- MHD_WEBSOCKET_FLAG_CLIENT,
- 0,
- malloc,
- realloc,
- free,
- NULL,
- test_rng))
- {
- fprintf (stderr,
- "No encode binary tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- return 0x10;
- }
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0))
- {
- fprintf (stderr,
- "No encode binary tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- return 0x10;
- }
-
- /*
- ------------------------------------------------------------------------------
- Encoding
- ------------------------------------------------------------------------------
- */
- /* Regular test: Some data, we are server */
- ret = MHD_websocket_encode_binary (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Some data, we are client */
- ret = MHD_websocket_encode_binary (wsc,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (15 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "blablabla",
- 9,
- MHD_WEBSOCKET_STATUS_BINARY_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Edge test (success): Some data with NUL characters, we are server */
- ret = MHD_websocket_encode_binary (wss,
- "bla" "\0\0\0" "bla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x09" "bla" "\0\0\0" "bla", 11)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Some data which looks like broken UTF-8, we are server */
- ret = MHD_websocket_encode_binary (wss,
- "bla" "\xC3" "blabla",
- 10,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (12 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x0A" "bla" "\xC3" "blabla", 12)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Fragmentation
- ------------------------------------------------------------------------------
- */
- /* Regular test: Some data */
- ret = MHD_websocket_encode_binary (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: First fragment */
- ret = MHD_websocket_encode_binary (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_FIRST,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x02\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Middle fragment */
- ret = MHD_websocket_encode_binary (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x00\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Last fragment */
- ret = MHD_websocket_encode_binary (wss,
- "blablabla",
- 9,
- MHD_WEBSOCKET_FRAGMENTATION_LAST,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x80\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Length checks
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): Binary frame without data */
- ret = MHD_websocket_encode_binary (wss,
- NULL,
- 0,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x00", 2)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Binary frame with 1 byte of data */
- ret = MHD_websocket_encode_binary (wss,
- "a",
- 1,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (3 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x01" "a", 3)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Binary frame with 125 bytes of data */
- ret = MHD_websocket_encode_binary (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 125,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (127 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x7D"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 127)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Binary frame with 126 bytes of data */
- ret = MHD_websocket_encode_binary (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 126,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (130 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x7E\x00\x7E"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 130)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Binary frame with 65535 bytes of data */
- allocate_length_test_data (&buf1,
- &buf2,
- 65535,
- "\x82\x7E\xFF\xFF",
- 4);
- ret = MHD_websocket_encode_binary (wss,
- buf2,
- 65535,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (65535 + 4 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, buf1, 65535 + 4)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Binary frame with 65536 bytes of data */
- allocate_length_test_data (&buf1,
- &buf2,
- 65536,
- "\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00",
- 10);
- ret = MHD_websocket_encode_binary (wss,
- buf2,
- 65536,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (65536 + 10 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, buf1, 65536 + 10)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Binary frame with 100 MB of data */
- allocate_length_test_data (&buf1,
- &buf2,
- 104857600,
- "\x82\x7F\x00\x00\x00\x00\x06\x40\x00\x00",
- 10);
- ret = MHD_websocket_encode_binary (wss,
- buf2,
- 104857600,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (104857600 + 10 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, buf1, 104857600 + 10)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- if (NULL != buf1)
- {
- free (buf1);
- buf1 = NULL;
- }
- if (NULL != buf2)
- {
- free (buf2);
- buf2 = NULL;
- }
-#ifdef ENABLE_64BIT_TESTS
- /* Fail test: `frame_len` is greater than 0x7FFFFFFFFFFFFFFF
- (this is the maximum allowed payload size) */
- frame_len = 0;
- ret = MHD_websocket_encode_binary (wss,
- "abc",
- (uint64_t) 0x8000000000000000,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-#endif
-
- /*
- ------------------------------------------------------------------------------
- Wrong parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: `ws` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_binary (NULL,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `payload` not passed, but `payload_len` != 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_binary (wss,
- NULL,
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `payload` passed, but `payload_len` == 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_binary (wss,
- "abc",
- 0,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (0 != memcmp (frame, "\x82\x00", 2)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `frame` not passed */
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_binary (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- NULL,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: `frame_len` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- ret = MHD_websocket_encode_binary (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `fragmentation` has an invalid value */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_binary (wss,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_LAST + 1,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- validity after temporary out-of-memory
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *wsx;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- /* Fail test: allocation while no memory available */
- disable_alloc = 1;
- ret = MHD_websocket_encode_binary (wsx,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
- /* Regular test: allocation while memory is available again */
- disable_alloc = 0;
- ret = MHD_websocket_encode_binary (wsx,
- "abc",
- 3,
- MHD_WEBSOCKET_FRAGMENTATION_NONE,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x82\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode binary test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
-
- MHD_websocket_stream_free (wsx);
- }
- else
- {
- fprintf (stderr,
- "Couldn't perform memory test for binary encoding in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- if (NULL != buf1)
- free (buf1);
- if (NULL != buf2)
- free (buf2);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- if (NULL != wss)
- MHD_websocket_stream_free (wss);
-
- return failed != 0 ? 0x10 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_encode_close()`
- */
-int
-test_encodes_close ()
-{
- int failed = 0;
- struct MHD_WebSocketStream *wss;
- struct MHD_WebSocketStream *wsc;
- int ret;
- char *buf1 = NULL, *buf2 = NULL;
- char *frame = NULL;
- size_t frame_len = 0;
-
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc,
- MHD_WEBSOCKET_FLAG_CLIENT,
- 0,
- malloc,
- realloc,
- free,
- NULL,
- test_rng))
- {
- fprintf (stderr,
- "No encode close tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- return 0x10;
- }
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wss,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0,
- malloc,
- realloc,
- free,
- NULL,
- test_rng))
- {
- fprintf (stderr,
- "No encode close tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- return 0x10;
- }
-
- /*
- ------------------------------------------------------------------------------
- Encoding
- ------------------------------------------------------------------------------
- */
- /* Regular test: Some data, we are server */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "blablabla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (13 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x0B\x03\xE8" "blablabla", 13)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Some data, we are client */
- ret = MHD_websocket_encode_close (wsc,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "blablabla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (17 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "\x03\xE8" "blablabla",
- 11,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Close reason without text, we are server */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (4 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x02\x03\xE8", 4)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Close reason without text, we are client */
- ret = MHD_websocket_encode_close (wsc,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (8 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "\x03\xE8",
- 2,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Close without reason, we are server */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_NO_REASON,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x00", 2)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Close without reason, we are client */
- ret = MHD_websocket_encode_close (wsc,
- MHD_WEBSOCKET_CLOSEREASON_NO_REASON,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (6 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Close with UTF-8 sequence in reason, we are client */
- ret = MHD_websocket_encode_close (wsc,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "bla" "\xC3\xA4" "blabla",
- 11,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (19 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "\x03\xE8" "bla" "\xC3\xA4" "blabla",
- 13,
- MHD_WEBSOCKET_STATUS_CLOSE_FRAME,
- MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Edge test (success): Close reason with NUL characters, we are server */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_GOING_AWAY,
- "bla" "\0\0\0" "bla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (13 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x0B\x03\xE9" "bla" "\0\0\0" "bla", 13)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: Some data with broken UTF-8, we are server */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "bla" "\xC3" "blabla",
- 10,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Length checks
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): Close frame without payload */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_NO_REASON,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x00", 2)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Close frame only reason code */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (4 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x02\x03\xE8", 4)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Close frame with 1 bytes of reason text */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "a",
- 1,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x03\x03\xE8" "a", 5)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Close frame with 123 bytes of reason text */
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456",
- 123,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (127 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x7D\x03\xE8"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456",
- 127)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (fail): Close frame with 124 bytes of reason text*/
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567",
- 124,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Wrong parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: `ws` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (NULL,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `payload` not passed, but `payload_len` != 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- NULL,
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `payload` passed, but `payload_len` == 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abc",
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (4 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (0 != memcmp (frame, "\x88\x02\x03\xE8", 4)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `frame` not passed */
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abc",
- 3,
- NULL,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: `frame_len` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abc",
- 3,
- &frame,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: no reason code passed, but reason text */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (wss,
- MHD_WEBSOCKET_CLOSEREASON_NO_REASON,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (fail): Invalid reason code */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (wss,
- 1,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (fail): Invalid reason code */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (wss,
- 999,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Custom reason code */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_close (wss,
- 2000,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (7 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (0 != memcmp (frame, "\x88\x05\x07\xD0" "abc", 7)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- validity after temporary out-of-memory
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *wsx;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- /* Fail test: allocation while no memory available */
- disable_alloc = 1;
- ret = MHD_websocket_encode_close (wsx,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
- /* Regular test: allocation while memory is available again */
- disable_alloc = 0;
- ret = MHD_websocket_encode_close (wsx,
- MHD_WEBSOCKET_CLOSEREASON_REGULAR,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (7 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x88\x05\x03\xE8" "abc", 7)))
- {
- fprintf (stderr,
- "Encode close test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
-
- MHD_websocket_stream_free (wsx);
- }
- else
- {
- fprintf (stderr,
- "Couldn't perform memory test for close encoding in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- if (NULL != buf1)
- free (buf1);
- if (NULL != buf2)
- free (buf2);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- if (NULL != wss)
- MHD_websocket_stream_free (wss);
-
- return failed != 0 ? 0x20 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_encode_ping()`
- */
-int
-test_encodes_ping ()
-{
- int failed = 0;
- struct MHD_WebSocketStream *wss;
- struct MHD_WebSocketStream *wsc;
- int ret;
- char *buf1 = NULL, *buf2 = NULL;
- char *frame = NULL;
- size_t frame_len = 0;
-
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc,
- MHD_WEBSOCKET_FLAG_CLIENT,
- 0,
- malloc,
- realloc,
- free,
- NULL,
- test_rng))
- {
- fprintf (stderr,
- "No encode ping tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- return 0x10;
- }
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0))
- {
- fprintf (stderr,
- "No encode ping tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- return 0x10;
- }
-
- /*
- ------------------------------------------------------------------------------
- Encoding
- ------------------------------------------------------------------------------
- */
- /* Regular test: Some data, we are server */
- ret = MHD_websocket_encode_ping (wss,
- "blablabla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Some data, we are client */
- ret = MHD_websocket_encode_ping (wsc,
- "blablabla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (15 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "blablabla",
- 9,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Ping without payload, we are server */
- ret = MHD_websocket_encode_ping (wss,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x00", 2)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Ping without payload, we are client */
- ret = MHD_websocket_encode_ping (wsc,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (6 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Ping with something like UTF-8 sequence in payload, we are client */
- ret = MHD_websocket_encode_ping (wsc,
- "bla" "\xC3\xA4" "blabla",
- 11,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (17 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "bla" "\xC3\xA4" "blabla",
- 11,
- MHD_WEBSOCKET_STATUS_PING_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Edge test (success): Ping payload with NUL characters, we are server */
- ret = MHD_websocket_encode_ping (wss,
- "bla" "\0\0\0" "bla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x09" "bla" "\0\0\0" "bla", 11)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Ping payload with with something which looks like broken UTF-8, we are server */
- ret = MHD_websocket_encode_ping (wss,
- "bla" "\xC3" "blabla",
- 10,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (12 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x0A" "bla" "\xC3" "blabla", 12)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Length checks
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): Ping frame without payload */
- ret = MHD_websocket_encode_ping (wss,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x00", 2)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Ping frame with one byte of payload */
- ret = MHD_websocket_encode_ping (wss,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x00", 2)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Ping frame with 125 bytes of payload */
- ret = MHD_websocket_encode_ping (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 125,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (127 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x7D"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 127)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (fail): Ping frame with 126 bytes of payload */
- ret = MHD_websocket_encode_ping (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 126,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Wrong parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: `ws` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_ping (NULL,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `payload` not passed, but `payload_len` != 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_ping (wss,
- NULL,
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `payload` passed, but `payload_len` == 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_ping (wss,
- "abc",
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (0 != memcmp (frame, "\x89\x00", 2)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `frame` not passed */
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_ping (wss,
- "abc",
- 3,
- NULL,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: `frame_len` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- ret = MHD_websocket_encode_ping (wss,
- "abc",
- 3,
- &frame,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- validity after temporary out-of-memory
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *wsx;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- /* Fail test: allocation while no memory available */
- disable_alloc = 1;
- ret = MHD_websocket_encode_ping (wsx,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
- /* Regular test: allocation while memory is available again */
- disable_alloc = 0;
- ret = MHD_websocket_encode_ping (wsx,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x89\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode ping test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
-
- MHD_websocket_stream_free (wsx);
- }
- else
- {
- fprintf (stderr,
- "Couldn't perform memory test for ping encoding in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- if (NULL != buf1)
- free (buf1);
- if (NULL != buf2)
- free (buf2);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- if (NULL != wss)
- MHD_websocket_stream_free (wss);
-
- return failed != 0 ? 0x40 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_encode_pong()`
- */
-int
-test_encodes_pong ()
-{
- int failed = 0;
- struct MHD_WebSocketStream *wss;
- struct MHD_WebSocketStream *wsc;
- int ret;
- char *buf1 = NULL, *buf2 = NULL;
- char *frame = NULL;
- size_t frame_len = 0;
-
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc,
- MHD_WEBSOCKET_FLAG_CLIENT,
- 0,
- malloc,
- realloc,
- free,
- NULL,
- test_rng))
- {
- fprintf (stderr,
- "No encode pong tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- return 0x10;
- }
- if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0))
- {
- fprintf (stderr,
- "No encode pong tests possible due to failed stream init in line %u\n",
- (unsigned int) __LINE__);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- return 0x10;
- }
-
- /*
- ------------------------------------------------------------------------------
- Encoding
- ------------------------------------------------------------------------------
- */
- /* Regular test: Some data, we are server */
- ret = MHD_websocket_encode_pong (wss,
- "blablabla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x09" "blablabla", 11)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Some data, we are client */
- ret = MHD_websocket_encode_pong (wsc,
- "blablabla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (15 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "blablabla",
- 9,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Pong without payload, we are server */
- ret = MHD_websocket_encode_pong (wss,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x00", 2)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Pong without payload, we are client */
- ret = MHD_websocket_encode_pong (wsc,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (6 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- NULL,
- 0,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Regular test: Pong with something like UTF-8 sequence in payload, we are client */
- ret = MHD_websocket_encode_pong (wsc,
- "bla" "\xC3\xA4" "blabla",
- 11,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (17 != frame_len) ||
- (NULL == frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- else
- {
- failed += test_decode_single (__LINE__,
- MHD_WEBSOCKET_FLAG_SERVER
- | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS,
- 0,
- 1,
- 0,
- frame,
- frame_len,
- "bla" "\xC3\xA4" "blabla",
- 11,
- MHD_WEBSOCKET_STATUS_PONG_FRAME,
- MHD_WEBSOCKET_VALIDITY_VALID,
- frame_len);
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsc, frame);
- frame = NULL;
- }
- /* Edge test (success): Pong payload with NUL characters, we are server */
- ret = MHD_websocket_encode_pong (wss,
- "bla" "\0\0\0" "bla",
- 9,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (11 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x09" "bla" "\0\0\0" "bla", 11)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: Pong payload with with something which looks like broken UTF-8, we are server */
- ret = MHD_websocket_encode_pong (wss,
- "bla" "\xC3" "blabla",
- 10,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (12 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x0A" "bla" "\xC3" "blabla", 12)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Length checks
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): Pong frame without payload */
- ret = MHD_websocket_encode_pong (wss,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x00", 2)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Pong frame with one byte of payload */
- ret = MHD_websocket_encode_pong (wss,
- NULL,
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x00", 2)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (success): Pong frame with 125 bytes of payload */
- ret = MHD_websocket_encode_pong (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 125,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (127 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x7D"
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678",
- 127)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Edge test (fail): Pong frame with 126 bytes of payload */
- ret = MHD_websocket_encode_pong (wss,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
- 126,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- Wrong parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: `ws` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_pong (NULL,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `payload` not passed, but `payload_len` != 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_pong (wss,
- NULL,
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Regular test: `payload` passed, but `payload_len` == 0 */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_pong (wss,
- "abc",
- 0,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (2 != frame_len) ||
- (NULL == frame) ||
- (((char *) (uintptr_t) 0xBAADF00D) == frame) ||
- (0 != memcmp (frame, "\x8A\x00", 2)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
- /* Fail test: `frame` not passed */
- frame_len = 0x87654321;
- ret = MHD_websocket_encode_pong (wss,
- "abc",
- 3,
- NULL,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (0 != frame_len) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: `frame_len` not passed */
- frame = (char *) (uintptr_t) 0xBAADF00D;
- ret = MHD_websocket_encode_pong (wss,
- "abc",
- 3,
- &frame,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (((char *) (uintptr_t) 0xBAADF00D) == frame)
- {
- frame = NULL;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wss, frame);
- frame = NULL;
- }
-
- /*
- ------------------------------------------------------------------------------
- validity after temporary out-of-memory
- ------------------------------------------------------------------------------
- */
- {
- struct MHD_WebSocketStream *wsx;
- if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx,
- MHD_WEBSOCKET_FLAG_SERVER,
- 0,
- test_malloc,
- test_realloc,
- test_free,
- NULL,
- NULL))
- {
- /* Fail test: allocation while no memory available */
- disable_alloc = 1;
- ret = MHD_websocket_encode_pong (wsx,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) ||
- (0 != frame_len) ||
- (NULL != frame) )
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
- /* Regular test: allocation while memory is available again */
- disable_alloc = 0;
- ret = MHD_websocket_encode_pong (wsx,
- "abc",
- 3,
- &frame,
- &frame_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (5 != frame_len) ||
- (NULL == frame) ||
- (0 != memcmp (frame, "\x8A\x03" "abc", 5)))
- {
- fprintf (stderr,
- "Encode pong test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- if (NULL != frame)
- {
- MHD_websocket_free (wsx, frame);
- frame = NULL;
- }
-
- MHD_websocket_stream_free (wsx);
- }
- else
- {
- fprintf (stderr,
- "Couldn't perform memory test for pong encoding in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- }
-
- if (NULL != buf1)
- free (buf1);
- if (NULL != buf2)
- free (buf2);
- if (NULL != wsc)
- MHD_websocket_stream_free (wsc);
- if (NULL != wss)
- MHD_websocket_stream_free (wss);
-
- return failed != 0 ? 0x80 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_split_close_reason()`
- */
-int
-test_split_close_reason ()
-{
- int failed = 0;
- const char *payload;
- unsigned short reason_code;
- const char *reason_utf8;
- size_t reason_utf8_len;
- int ret;
-
- /*
- ------------------------------------------------------------------------------
- Normal splits
- ------------------------------------------------------------------------------
- */
- /* Regular test: Reason code + Reason text */
- reason_code = 9999;
- reason_utf8 = (const char *) (intptr_t) 0xBAADF00D;
- reason_utf8_len = 12345;
- payload = "\x03\xE8" "abc";
- ret = MHD_websocket_split_close_reason (payload,
- 5,
- &reason_code,
- &reason_utf8,
- &reason_utf8_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) ||
- (3 != reason_utf8_len) ||
- (payload + 2 != reason_utf8) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: Reason code */
- reason_code = 9999;
- reason_utf8 = (const char *) (intptr_t) 0xBAADF00D;
- reason_utf8_len = 12345;
- payload = "\x03\xE8";
- ret = MHD_websocket_split_close_reason (payload,
- 2,
- &reason_code,
- &reason_utf8,
- &reason_utf8_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) ||
- (0 != reason_utf8_len) ||
- (NULL != reason_utf8) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: No payload */
- reason_code = 9999;
- reason_utf8 = (const char *) (intptr_t) 0xBAADF00D;
- reason_utf8_len = 12345;
- payload = NULL;
- ret = MHD_websocket_split_close_reason (payload,
- 0,
- &reason_code,
- &reason_utf8,
- &reason_utf8_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code) ||
- (0 != reason_utf8_len) ||
- (NULL != reason_utf8) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: `payload` is not NULL given, but `payload_len` == 0 */
- reason_code = 9999;
- reason_utf8 = (const char *) (intptr_t) 0xBAADF00D;
- reason_utf8_len = 12345;
- payload = "abc";
- ret = MHD_websocket_split_close_reason (payload,
- 0,
- &reason_code,
- &reason_utf8,
- &reason_utf8_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code) ||
- (0 != reason_utf8_len) ||
- (NULL != reason_utf8) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Wrong parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: `payload` not passed, but `payload_len` != 0 */
- reason_code = 9999;
- reason_utf8 = (const char *) (intptr_t) 0xBAADF00D;
- reason_utf8_len = 12345;
- payload = NULL;
- ret = MHD_websocket_split_close_reason (payload,
- 3,
- &reason_code,
- &reason_utf8,
- &reason_utf8_len);
- if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) ||
- (MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code) ||
- (0 != reason_utf8_len) ||
- (NULL != reason_utf8) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: `reason_code` not passed */
- reason_utf8 = (const char *) (intptr_t) 0xBAADF00D;
- reason_utf8_len = 12345;
- payload = "\x03\xE8" "abc";
- ret = MHD_websocket_split_close_reason (payload,
- 5,
- NULL,
- &reason_utf8,
- &reason_utf8_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (3 != reason_utf8_len) ||
- (payload + 2 != reason_utf8) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: `reason_utf8` not passed */
- reason_code = 9999;
- reason_utf8_len = 12345;
- payload = "\x03\xE8" "abc";
- ret = MHD_websocket_split_close_reason (payload,
- 5,
- &reason_code,
- NULL,
- &reason_utf8_len);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) ||
- (3 != reason_utf8_len) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: `reason_utf8_len` not passed */
- reason_code = 9999;
- reason_utf8 = (const char *) (intptr_t) 0xBAADF00D;
- payload = "\x03\xE8" "abc";
- ret = MHD_websocket_split_close_reason (payload,
- 5,
- &reason_code,
- &reason_utf8,
- NULL);
- if ((MHD_WEBSOCKET_STATUS_OK != ret) ||
- (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) ||
- (payload + 2 != reason_utf8) )
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: `reason_code`, `reason_utf8` and `reason_utf8_len` not passed */
- /* (this is not prohibited, although it doesn't really make sense) */
- payload = "\x03\xE8" "abc";
- ret = MHD_websocket_split_close_reason (payload,
- 5,
- NULL,
- NULL,
- NULL);
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "split close reason test failed in line %u\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- return failed != 0 ? 0x100 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_check_http_version()`
- */
-int
-test_check_http_version ()
-{
- int failed = 0;
- int ret;
-
- /*
- ------------------------------------------------------------------------------
- Version check with valid HTTP version syntax
- ------------------------------------------------------------------------------
- */
- /* Regular test: HTTP/1.1 */
- ret = MHD_websocket_check_http_version ("HTTP/1.1");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: HTTP/1.2 */
- ret = MHD_websocket_check_http_version ("HTTP/1.2");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: HTTP/1.10 */
- ret = MHD_websocket_check_http_version ("HTTP/1.10");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: HTTP/2.0 */
- ret = MHD_websocket_check_http_version ("HTTP/2.0");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: HTTP/3.0 */
- ret = MHD_websocket_check_http_version ("HTTP/3.0");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: HTTP/1.0 */
- ret = MHD_websocket_check_http_version ("HTTP/1.0");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: HTTP/0.9 */
- ret = MHD_websocket_check_http_version ("HTTP/0.9");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Version check edge cases
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): HTTP/123.45 */
- ret = MHD_websocket_check_http_version ("HTTP/123.45");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/1.45 */
- ret = MHD_websocket_check_http_version ("HTTP/1.45");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/01.1 */
- ret = MHD_websocket_check_http_version ("HTTP/01.1");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/0001.1 */
- ret = MHD_websocket_check_http_version ("HTTP/0001.1");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/1.01 */
- ret = MHD_websocket_check_http_version ("HTTP/1.01");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/1.0001 */
- ret = MHD_websocket_check_http_version ("HTTP/1.0001");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/0001.0001 */
- ret = MHD_websocket_check_http_version ("HTTP/0001.0001");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/2.000 */
- ret = MHD_websocket_check_http_version ("HTTP/2.000");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): HTTP/0.0 */
- ret = MHD_websocket_check_http_version ("HTTP/0.0");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): HTTP/00.0 */
- ret = MHD_websocket_check_http_version ("HTTP/00.0");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): HTTP/00.0 */
- ret = MHD_websocket_check_http_version ("HTTP/0.00");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Invalid version syntax
- ------------------------------------------------------------------------------
- */
- /* Fail test: (empty string) */
- ret = MHD_websocket_check_http_version ("");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: http/1.1 */
- ret = MHD_websocket_check_http_version ("http/1.1");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: "HTTP / 1.1" */
- ret = MHD_websocket_check_http_version ("HTTP / 1.1");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Missing parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: NULL as version */
- ret = MHD_websocket_check_http_version (NULL);
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_http_version test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- return failed != 0 ? 0x200 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_check_connection_header()`
- */
-int
-test_check_connection_header ()
-{
- int failed = 0;
- int ret;
-
- /*
- ------------------------------------------------------------------------------
- Check with valid Connection header syntax
- ------------------------------------------------------------------------------
- */
- /* Regular test: Upgrade */
- ret = MHD_websocket_check_connection_header ("Upgrade");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Regular test: keep-alive, Upgrade */
- ret = MHD_websocket_check_connection_header ("keep-alive, Upgrade");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: keep-alive */
- ret = MHD_websocket_check_connection_header ("keep-alive");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: close */
- ret = MHD_websocket_check_connection_header ("close");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Connection check edge cases
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): keep-alive,Upgrade */
- ret = MHD_websocket_check_connection_header ("keep-alive,Upgrade");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): Upgrade, keep-alive */
- ret = MHD_websocket_check_connection_header ("Upgrade, keep-alive");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): Upgrade,keep-alive */
- ret = MHD_websocket_check_connection_header ("Upgrade,keep-alive");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): Transfer-Encoding,Upgrade,keep-alive */
- ret = MHD_websocket_check_connection_header (
- "Transfer-Encoding,Upgrade,keep-alive");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): Transfer-Encoding , Upgrade , keep-alive */
- ret = MHD_websocket_check_connection_header (
- "Transfer-Encoding , Upgrade , keep-alive");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): upgrade */
- ret = MHD_websocket_check_connection_header ("upgrade");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): UPGRADE */
- ret = MHD_websocket_check_connection_header ("UPGRADE");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): All allowed token characters, then upgrade token */
- ret = MHD_websocket_check_connection_header (
- "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,Upgrade");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): Different, allowed whitespaces */
- ret = MHD_websocket_check_connection_header (" \tUpgrade \t");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_connection_header ("\rUpgrade");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_connection_header ("\nUpgrade");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_connection_header ("\vUpgrade");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_connection_header ("\fUpgrade");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Invalid header syntax
- ------------------------------------------------------------------------------
- */
- /* Fail test: (empty string) */
- ret = MHD_websocket_check_connection_header ("");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: (Disallowed) multiple word token with the term "Upgrade" in it */
- ret = MHD_websocket_check_connection_header ("Upgrade or Downgrade");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: Invalid characters */
- ret = MHD_websocket_check_connection_header ("\"Upgrade\"");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Missing parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: NULL as connection */
- ret = MHD_websocket_check_connection_header (NULL);
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_connection_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- return failed != 0 ? 0x400 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_check_upgrade_header()`
- */
-int
-test_check_upgrade_header ()
-{
- int failed = 0;
- int ret;
-
- /*
- ------------------------------------------------------------------------------
- Check with valid Upgrade header syntax
- ------------------------------------------------------------------------------
- */
- /* Regular test: websocket */
- ret = MHD_websocket_check_upgrade_header ("websocket");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: HTTP/2.0 */
- ret = MHD_websocket_check_upgrade_header ("HTTP/2.0");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Upgrade check edge cases
- ------------------------------------------------------------------------------
- */
- /* Edge test (success): websocket,HTTP/2.0 */
- ret = MHD_websocket_check_upgrade_header ("websocket,HTTP/2.0");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): websocket ,HTTP/2.0 */
- ret = MHD_websocket_check_upgrade_header (" websocket ,HTTP/2.0");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): HTTP/2.0, websocket */
- ret = MHD_websocket_check_upgrade_header ("HTTP/2.0, websocket ");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): websocket/13 */
- ret = MHD_websocket_check_upgrade_header ("websocket/13");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): WeBsOcKeT */
- ret = MHD_websocket_check_upgrade_header ("WeBsOcKeT");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): WEBSOCKET */
- ret = MHD_websocket_check_upgrade_header ("WEBSOCKET");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): All allowed token characters plus /, then websocket keyword */
- ret = MHD_websocket_check_upgrade_header (
- "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/,websocket");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (success): Different, allowed whitespaces */
- ret = MHD_websocket_check_upgrade_header (" \twebsocket \t");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_upgrade_header ("\rwebsocket");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_upgrade_header ("\nwebsocket");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_upgrade_header ("\vwebsocket");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): Different, disallowed whitespaces */
- ret = MHD_websocket_check_upgrade_header ("\fwebsocket");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Invalid header syntax
- ------------------------------------------------------------------------------
- */
- /* Fail test: (empty string) */
- ret = MHD_websocket_check_upgrade_header ("");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: (Disallowed) multiple word token with the term "websocket" in it */
- ret = MHD_websocket_check_upgrade_header ("websocket or something");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: Invalid characters */
- ret = MHD_websocket_check_upgrade_header ("\"websocket\"");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Missing parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: NULL as upgrade */
- ret = MHD_websocket_check_upgrade_header (NULL);
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_upgrade_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- return failed != 0 ? 0x800 : 0x00;
-}
-
-
-/**
- * Test procedure for `MHD_websocket_check_version_header()`
- */
-int
-test_check_version_header ()
-{
- int failed = 0;
- int ret;
-
- /*
- ------------------------------------------------------------------------------
- Check with valid Upgrade header syntax
- ------------------------------------------------------------------------------
- */
- /* Regular test: 13 */
- ret = MHD_websocket_check_version_header ("13");
- if (MHD_WEBSOCKET_STATUS_OK != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Version check edge cases
- ------------------------------------------------------------------------------
- */
- /* Edge test (fail): 14 */
- ret = MHD_websocket_check_version_header ("14");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): 12 */
- ret = MHD_websocket_check_version_header ("12");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): 0 */
- ret = MHD_websocket_check_version_header ("1");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): 1 */
- ret = MHD_websocket_check_version_header ("1");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): 130 */
- ret = MHD_websocket_check_version_header ("130");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Edge test (fail): " 13" */
- ret = MHD_websocket_check_version_header (" 13");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Invalid header syntax
- ------------------------------------------------------------------------------
- */
- /* Fail test: (empty string) */
- ret = MHD_websocket_check_version_header ("");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
- /* Fail test: Invalid characters */
- ret = MHD_websocket_check_version_header ("abc");
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- /*
- ------------------------------------------------------------------------------
- Missing parameters
- ------------------------------------------------------------------------------
- */
- /* Fail test: NULL as version */
- ret = MHD_websocket_check_version_header (NULL);
- if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret)
- {
- fprintf (stderr,
- "check_version_header test failed in line %u.\n",
- (unsigned int) __LINE__);
- ++failed;
- }
-
- return failed != 0 ? 0x1000 : 0x00;
-}
-
-
-int
-main (int argc, char *const *argv)
-{
- unsigned int errorCount = 0;
- (void) argc; (void) argv; /* Unused. Silent compiler warning. */
-
- /* seed random number generator */
- srand ((unsigned long) time (NULL));
-
- /* perform tests */
- errorCount += test_inits ();
- errorCount += test_accept ();
- errorCount += test_decodes ();
- errorCount += test_encodes_text ();
- errorCount += test_encodes_binary ();
- errorCount += test_encodes_close ();
- errorCount += test_encodes_ping ();
- errorCount += test_encodes_pong ();
- errorCount += test_split_close_reason ();
- errorCount += test_check_http_version ();
- errorCount += test_check_connection_header ();
- errorCount += test_check_upgrade_header ();
- errorCount += test_check_version_header ();
-
- /* output result */
- if (errorCount != 0)
- fprintf (stderr, "Error (code: %u)\n", errorCount);
-
- return errorCount != 0; /* 0 == pass */
-}
diff --git a/src/microhttpd_ws/test_websocket_browser.c b/src/microhttpd_ws/test_websocket_browser.c
@@ -1,567 +0,0 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2021 David Gausmann
-
- libmicrohttpd is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- libmicrohttpd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with libmicrohttpd; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-/**
- * @file test_websocket_browser.c
- * @brief Testcase for WebSocket decoding/encoding with external browser
- * @author David Gausmann
- */
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#else
-#include <winsock2.h>
-#endif
-#include "microhttpd.h"
-#include "microhttpd_ws.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <time.h>
-#include <errno.h>
-
-#define PORT 80
-
-#define PAGE \
- "<!DOCTYPE html>\n" \
- "<html>\n" \
- "<head>\n" \
- "<meta charset=\"UTF-8\">\n" \
- "<title>Websocket External Test with Webbrowser</title>\n" \
- "<script>\n" \
- "\n" \
- "let current_mode = 0;\n" \
- "let current_step = 0;\n" \
- "let sent_payload = null;\n" \
- "let charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_!@%&/\\\\';\n" \
- "let step_to_bytes = [ 0, 1, 2, 3, 122, 123, 124, 125, 126, 127, 128, 32766, 32767, 32768, 65534, 65535, 65536, 65537, 1048576, 10485760 ];\n" \
- "let url = 'ws' + (window.location.protocol === 'https:' ? 's' : '')" \
- " + ':/" "/' +\n" \
- " window.location.host + '/websocket';\n" \
- "let socket = null;\n" \
- "\n" \
- "window.onload = function (event) {\n" \
- " if (!window.WebSocket) {\n" \
- " document.write ('ERROR: The WebSocket class is not supported by your browser.<br>');\n" \
- " }\n" \
- " if (!window.fetch) {\n" \
- " document.write ('ERROR: The fetch-API is not supported by your browser.<br>');\n" \
- " }\n" \
- " document.write ('Starting tests.<br>');\n" \
- " runTest ();\n" \
- "}\n" \
- "\n" \
- "function runTest () {\n" \
- " switch (current_mode) {\n" \
- " case 0:\n" \
- " document.write ('TEXT');\n" \
- " break;\n" \
- " case 1:\n" \
- " document.write ('BINARY');\n" \
- " break;\n" \
- " }\n" \
- " document.write (', ' + step_to_bytes[current_step] + ' Bytes: ');\n" \
- " socket = new WebSocket(url);\n" \
- " socket.binaryType = 'arraybuffer';\n" \
- " socket.onopen = function (event) {\n" \
- " switch (current_mode) {\n" \
- " case 0:\n" \
- " sent_payload = randomText (step_to_bytes[current_step]);\n" \
- " socket.send (sent_payload);\n" \
- " break;\n" \
- " case 1:\n" \
- " sent_payload = randomBinary (step_to_bytes[current_step]);\n" \
- " socket.send (sent_payload);\n" \
- " break;\n" \
- " }\n" \
- " }\n" \
- "\n" \
- " socket.onclose = function (event) {\n" \
- " socket.onmessage = null;\n" \
- " socket.onclose = null;\n" \
- " socket.onerror = null;\n" \
- " document.write ('CLOSED unexpectedly.<br>');\n" \
- " notifyError ();\n" \
- " }\n" \
- "\n" \
- " socket.onerror = function (event) {\n" \
- " socket.onmessage = null;\n" \
- " socket.onclose = null;\n" \
- " socket.onerror = null;\n" \
- " document.write ('ERROR.<br>');\n" \
- " notifyError ();\n" \
- " }\n" \
- "\n" \
- " socket.onmessage = async function (event) {\n" \
- " if (compareData (event.data, sent_payload)) {\n" \
- " document.write ('SUCCESS.<br>');\n" \
- " socket.onmessage = null;\n" \
- " socket.onclose = null;\n" \
- " socket.onerror = null;\n" \
- " socket.close();\n" \
- " socket = null;\n" \
- " if (step_to_bytes.length <= ++current_step) {\n" \
- " current_step = 0;\n" \
- " if (1 < ++current_mode) {\n" \
- " document.write ('FINISHED ALL TESTS.<br>');\n" \
- " return;\n" \
- " }\n" \
- " }\n" \
- " runTest ();\n" \
- " }" \
- " }\n" \
- "}\n" \
- "\n" \
- "function compareData (data, data2) {\n" \
- " if (typeof (data) === 'string' && typeof (data2) === 'string') {\n" \
- " return (data === data2); \n" \
- " } \n" \
- " else if ((data instanceof ArrayBuffer) && (data2 instanceof ArrayBuffer)) {\n" \
- " let view1 = new Uint8Array (data);\n" \
- " let view2 = new Uint8Array (data2);\n" \
- " if (view1.length != view2.length)\n" \
- " return false;\n" \
- " for (let i = 0; i < view1.length; ++i) {\n" \
- " if (view1[i] !== view2[i])\n" \
- " return false;\n" \
- " }\n" \
- " return true;\n" \
- " }\n" \
- " else\n" \
- " {\n" \
- " return false;\n" \
- " }\n" \
- "}\n" \
- "\n" \
- "function randomText (length) {\n" \
- " let result = new Array (length);\n" \
- " for (let i = 0; i < length; ++i)\n" \
- " result [i] = charset [~~(Math.random () * charset.length)];\n" \
- " return result.join ('');\n" \
- "}\n" \
- "\n" \
- "function randomBinary (length) {\n" \
- " let buffer = new ArrayBuffer (length);\n" \
- " let view = new Uint8Array (buffer);\n" \
- " for (let i = 0; i < length; ++i)\n" \
- " view [i] = ~~(Math.random () * 256);\n" \
- " return buffer;\n" \
- "}\n" \
- "\n" \
- "function notifyError () {\n" \
- " fetch('error/' + (0 == current_mode ? 'text' : 'binary') + '/' + step_to_bytes[current_step]);\n" \
- "}\n" \
- "\n" \
- "</script>\n" \
- "</head>\n" \
- "<body>\n" \
- "</body>\n" \
- "</html>"
-
-#define PAGE_NOT_FOUND \
- "404 Not Found"
-
-#define PAGE_INVALID_WEBSOCKET_REQUEST \
- "Invalid WebSocket request!"
-
-static void
-send_all (MHD_socket fd,
- const char *buf,
- size_t len);
-
-static void
-make_blocking (MHD_socket fd);
-
-static void
-upgrade_handler (void *cls,
- struct MHD_Connection *connection,
- void *req_cls,
- const char *extra_in,
- size_t extra_in_size,
- MHD_socket fd,
- struct MHD_UpgradeResponseHandle *urh)
-{
- /* make the socket blocking (operating-system-dependent code) */
- make_blocking (fd);
-
- /* create a websocket stream for this connection */
- struct MHD_WebSocketStream *ws;
- int result = MHD_websocket_stream_init (&ws,
- 0,
- 0);
- if (0 != result)
- {
- /* Couldn't create the websocket stream.
- * So we close the socket and leave
- */
- MHD_upgrade_action (urh,
- MHD_UPGRADE_ACTION_CLOSE);
- return;
- }
-
- /* Let's wait for incoming data */
- const size_t buf_len = 256;
- char buf[buf_len];
- ssize_t got;
- while (MHD_WEBSOCKET_VALIDITY_VALID == MHD_websocket_stream_is_valid (ws))
- {
- got = recv (fd,
- buf,
- sizeof (buf),
- 0);
- if (0 >= got)
- {
- /* the TCP/IP socket has been closed */
- fprintf (stderr,
- "Error (The socket has been closed unexpectedly)\n");
- break;
- }
-
- /* parse the entire received data */
- size_t buf_offset = 0;
- while (buf_offset < (size_t) got)
- {
- size_t new_offset = 0;
- char *payload_data = NULL;
- size_t payload_len = 0;
- char *frame_data = NULL;
- size_t frame_len = 0;
- int status = MHD_websocket_decode (ws,
- buf + buf_offset,
- ((size_t) got) - buf_offset,
- &new_offset,
- &payload_data,
- &payload_len);
- if (0 > status)
- {
- /* an error occurred and the connection must be closed */
- printf ("Decoding failed: status=%d, passed=%u\n", status,
- ((size_t) got) - buf_offset);
- if (NULL != payload_data)
- {
- MHD_websocket_free (ws, payload_data);
- }
- break;
- }
- else
- {
- buf_offset += new_offset;
- if (0 < status)
- {
- /* the frame is complete */
- printf (
- "Decoding succeeded: type=%d, passed=%u, parsed=%u, payload_len=%d\n",
- status, ((size_t) got) - buf_offset, new_offset, payload_len);
- switch (status)
- {
- case MHD_WEBSOCKET_STATUS_TEXT_FRAME:
- case MHD_WEBSOCKET_STATUS_BINARY_FRAME:
- /* The client has sent some data. */
- if ((NULL != payload_data) || (0 == payload_len))
- {
- /* Send the received data back to the client */
- if (MHD_WEBSOCKET_STATUS_TEXT_FRAME == status)
- {
- result = MHD_websocket_encode_text (ws,
- payload_data,
- payload_len,
- 0,
- &frame_data,
- &frame_len,
- NULL);
- }
- else
- {
- result = MHD_websocket_encode_binary (ws,
- payload_data,
- payload_len,
- 0,
- &frame_data,
- &frame_len);
- }
- if (0 == result)
- {
- send_all (fd,
- frame_data,
- frame_len);
- }
- }
- else
- {
- /* should never happen */
- fprintf (stderr,
- "Error (Empty buffer with payload_len != 0)\n");
- }
- break;
-
- default:
- /* Other frame types are ignored
- * in this test script.
- */
- break;
- }
- }
- if (NULL != payload_data)
- {
- MHD_websocket_free (ws, payload_data);
- }
- if (NULL != frame_data)
- {
- MHD_websocket_free (ws, frame_data);
- }
- }
- }
- }
-
- /* free the websocket stream */
- MHD_websocket_stream_free (ws);
-
- /* close the socket when it is not needed anymore */
- MHD_upgrade_action (urh,
- MHD_UPGRADE_ACTION_CLOSE);
-}
-
-
-/* This helper function is used for the case that
- * we need to resend some data
- */
-static void
-send_all (MHD_socket fd,
- const char *buf,
- size_t len)
-{
- ssize_t ret;
- size_t off;
-
- for (off = 0; off < len; off += ret)
- {
- ret = send (fd,
- &buf[off],
- (int) (len - off),
- 0);
- if (0 > ret)
- {
- if (EAGAIN == errno)
- {
- ret = 0;
- continue;
- }
- break;
- }
- if (0 == ret)
- break;
- }
-}
-
-
-/* This helper function contains operating-system-dependent code and
- * is used to make a socket blocking.
- */
-static void
-make_blocking (MHD_socket fd)
-{
-#ifndef _WIN32
- int flags;
-
- flags = fcntl (fd, F_GETFL);
- if (-1 == flags)
- return;
- if ((flags & ~O_NONBLOCK) != flags)
- if (-1 == fcntl (fd, F_SETFL, flags & ~O_NONBLOCK))
- abort ();
-#else
- unsigned long flags = 0;
-
- ioctlsocket (fd, FIONBIO, &flags);
-#endif
-}
-
-
-static enum MHD_Result
-access_handler (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **req_cls)
-{
- static int aptr;
- struct MHD_Response *response;
- int ret;
-
- (void) cls; /* Unused. Silent compiler warning. */
- (void) upload_data; /* Unused. Silent compiler warning. */
- (void) upload_data_size; /* Unused. Silent compiler warning. */
-
- if (0 != strcmp (method, "GET"))
- return MHD_NO; /* unexpected method */
- if (&aptr != *req_cls)
- {
- /* do never respond on first call */
- *req_cls = &aptr;
- return MHD_YES;
- }
- *req_cls = NULL; /* reset when done */
-
- if (0 == strcmp (url, "/"))
- {
- /* Default page for visiting the server */
- struct MHD_Response *response = MHD_create_response_from_buffer (
- strlen (PAGE),
- PAGE,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
- }
- else if (0 == strncmp (url, "/error/", 7))
- {
- /* Report error */
- fprintf (stderr, "Error in test (%s)\n", url + 7);
-
- struct MHD_Response *response = MHD_create_response_from_buffer (
- 0,
- "",
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
- }
- else if (0 == strcmp (url, "/websocket"))
- {
- char is_valid = 1;
- const char *value = NULL;
- char sec_websocket_accept[29];
-
- if (0 != MHD_websocket_check_http_version (version))
- {
- is_valid = 0;
- }
- value = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_CONNECTION);
- if (0 != MHD_websocket_check_connection_header (value))
- {
- is_valid = 0;
- }
- value = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_UPGRADE);
- if (0 != MHD_websocket_check_upgrade_header (value))
- {
- is_valid = 0;
- }
- value = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION);
- if (0 != MHD_websocket_check_version_header (value))
- {
- is_valid = 0;
- }
- value = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY);
- if (0 != MHD_websocket_create_accept_header (value, sec_websocket_accept))
- {
- is_valid = 0;
- }
-
- if (1 == is_valid)
- {
- /* upgrade the connection */
- response = MHD_create_response_for_upgrade (&upgrade_handler,
- NULL);
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_UPGRADE,
- "websocket");
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT,
- sec_websocket_accept);
- ret = MHD_queue_response (connection,
- MHD_HTTP_SWITCHING_PROTOCOLS,
- response);
- MHD_destroy_response (response);
- }
- else
- {
- /* return error page */
- struct MHD_Response *response = MHD_create_response_from_buffer (
- strlen (PAGE_INVALID_WEBSOCKET_REQUEST),
- PAGE_INVALID_WEBSOCKET_REQUEST,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection,
- MHD_HTTP_BAD_REQUEST,
- response);
- MHD_destroy_response (response);
- }
- }
- else
- {
- struct MHD_Response *response = MHD_create_response_from_buffer (
- strlen (PAGE_NOT_FOUND),
- PAGE_NOT_FOUND,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection,
- MHD_HTTP_NOT_FOUND,
- response);
- MHD_destroy_response (response);
- }
-
- return ret;
-}
-
-
-int
-main (int argc,
- char *const *argv)
-{
- (void) argc; /* Unused. Silent compiler warning. */
- (void) argv; /* Unused. Silent compiler warning. */
- struct MHD_Daemon *daemon;
-
- daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD
- | MHD_USE_THREAD_PER_CONNECTION
- | MHD_ALLOW_UPGRADE
- | MHD_USE_ERROR_LOG,
- PORT, NULL, NULL,
- &access_handler, NULL,
- MHD_OPTION_END);
-
- if (NULL == daemon)
- {
- fprintf (stderr, "Error (Couldn't start daemon for testing)\n");
- return 1;
- }
- printf ("The server is listening now.\n");
- printf ("Access the server now with a websocket-capable webbrowser.\n\n");
- printf ("Press return to close.\n");
-
- (void) getc (stdin);
-
- MHD_stop_daemon (daemon);
-
- return 0;
-}