From patchwork Thu Nov 13 03:57:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Changqing Li X-Patchwork-Id: 75179 Return-Path: Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42FC8CCFA18 for ; Thu, 13 Nov 2025 03:59:05 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.16243.1763006270687594769 for ; Wed, 12 Nov 2025 19:59:00 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=l2/rOfVM; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=3412a7ece4=changqing.li@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AD1E6nT154250 for ; Thu, 13 Nov 2025 03:57:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=content-transfer-encoding:content-type:date:from:message-id :mime-version:subject:to; s=PPS06212021; bh=TNo2H9STPVJIy8/xt5Bl 5tcDfLXdS1Uo/iVFXydb+KU=; b=l2/rOfVMbWP06F+t3Myb54YxJbzl0ZtBJaMx 9P2nLZkOvEeZmboVLtLCorzNUFxd/pji9/gdi3mP9Lo2od4fvrNJOMlo6bqW0utX IMdkIx5vJcQ3GiGeDoOKOHQ5FbSCGGih3VBe8oH3z8v9OXRdSB2rmpRGJlLqt7hz UbOEYdWoZoH3rwV9MztwHn63venPjJypxmvN4RP8XDFnjN2zOHDj1+d4BzEja7d4 Yh0bKig6R4laeYg/p081WaLLxcO+h2F9VYpzYgPEniqxT0F6/p6ido+Rtl38DpC8 7MsdNleesemXY2p07yePnGKUwselWjRCA/v6206BvYYH2Wgubw== Received: from ala-exchng01.corp.ad.wrs.com ([128.224.246.36]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4acwphs2se-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 13 Nov 2025 03:57:41 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 12 Nov 2025 19:57:39 -0800 Received: from pek-lpg-core6.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 12 Nov 2025 19:57:39 -0800 From: To: Subject: [kirkstone][PATCH] libmicrohttpd: fix CVE-2025-59777, CVE-2025-62689 Date: Thu, 13 Nov 2025 11:57:38 +0800 Message-ID: <20251113035738.2837998-1-changqing.li@windriver.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Proofpoint-GUID: hO2RuZ6hAzgQqzHiznp0LIa0IP1fVdsy X-Proofpoint-ORIG-GUID: hO2RuZ6hAzgQqzHiznp0LIa0IP1fVdsy X-Authority-Analysis: v=2.4 cv=TKtIilla c=1 sm=1 tr=0 ts=69155736 cx=c_pps a=AbJuCvi4Y3V6hpbCNWx0WA==:117 a=AbJuCvi4Y3V6hpbCNWx0WA==:17 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=PYnjg3YJAAAA:8 a=cXER5rsiAAAA:8 a=mDV3o1hIAAAA:8 a=t7CeM3EgAAAA:8 a=3Vru7Ui4N18Ht7k6oywA:9 a=e6gHQ2zWfcreqHeh:21 a=3ZKOabzyN94A:10 a=4uWEtD8DuY3znTzooXTq:22 a=FdTzh2GWekK77mhwV6Dw:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTEzMDAyMyBTYWx0ZWRfX20yyhHfDfeI5 +VX4wTead+GlWSVW240n6xQhYohek8cl/DEWo6momqjvggadsat8iImi0zJrk52DunpGmCIFD6k 1xXISZ3JXmNzeprsJlG7YszVe1MQEWr04uaqFOYt0zD4Xe3z17yJN+BHTlf+qCLM21kODjaXoZy s/xIbgxpSBVTaeVzmQWkVZ+fnbbuQP+2Y5gyKxU15ERvJEv7LhYyTWPAI+XM0WZeKgAqae3BXgY E/ZWnvF3IEfVJDELGQC2D8j/56TZshJ9FnOra6irt7XR5s5ROQctP1fYtxtoANbAA2oB8mzeJ4w snbSqSGMms8llF+xQkkEQZyxcpDC1Q8ni827w9xhdrMFMdyouOJZ3amQYdzzx5POkrtTMf4IROx vLTIrGWypw4WbPwZpieggIFXOblbBA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-12_06,2025-11-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 clxscore=1015 bulkscore=0 spamscore=0 adultscore=0 suspectscore=0 priorityscore=1501 malwarescore=0 impostorscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511130023 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 13 Nov 2025 03:59:05 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/226223 From: Changqing Li Refer: https://nvd.nist.gov/vuln/detail/CVE-2025-59777 https://nvd.nist.gov/vuln/detail/CVE-2025-62689 Signed-off-by: Changqing Li --- ...0001-Remove-broken-experimental-code.patch | 14475 ++++++++++++++++ .../libmicrohttpd/libmicrohttpd_0.9.76.bb | 3 +- 2 files changed, 14477 insertions(+), 1 deletion(-) create mode 100644 meta/recipes-support/libmicrohttpd/files/0001-Remove-broken-experimental-code.patch diff --git a/meta/recipes-support/libmicrohttpd/files/0001-Remove-broken-experimental-code.patch b/meta/recipes-support/libmicrohttpd/files/0001-Remove-broken-experimental-code.patch new file mode 100644 index 0000000000..b30e0c69d6 --- /dev/null +++ b/meta/recipes-support/libmicrohttpd/files/0001-Remove-broken-experimental-code.patch @@ -0,0 +1,14475 @@ +From 34a71b9ba76f868f2f16732c9b5ec1798e62c046 Mon Sep 17 00:00:00 2001 +From: Changqing Li +Date: Thu, 13 Nov 2025 11:19:30 +0800 +Subject: [PATCH] Remove broken experimental code + +Upstream-Status: Backport [https://git.gnunet.org/libmicrohttpd.git/commit/?id=ff13abc1c1d7d2b30d69d5c0bd4a237e1801c50b +https://git.gnunet.org/libmicrohttpd.git/commit/?id=ba8f88fcb47cfb0de5237d47f9487cd1f350cbe9] + +CVE: CVE-2025-59777,CVE-2025-62689 + +Signed-off-by: Changqing Li +--- + configure.ac | 1 - + src/Makefile.am | 5 - + src/microhttpd_ws/Makefile.am | 39 - + src/microhttpd_ws/Makefile.in | 1305 ---- + src/microhttpd_ws/mhd_websocket.c | 2443 ------- + src/microhttpd_ws/sha1.c | 378 - + src/microhttpd_ws/sha1.h | 110 - + src/microhttpd_ws/test_websocket.c | 10105 --------------------------- + 8 files changed, 14386 deletions(-) + delete mode 100644 src/microhttpd_ws/Makefile.am + delete mode 100644 src/microhttpd_ws/Makefile.in + delete mode 100644 src/microhttpd_ws/mhd_websocket.c + delete mode 100644 src/microhttpd_ws/sha1.c + delete mode 100644 src/microhttpd_ws/sha1.h + delete mode 100644 src/microhttpd_ws/test_websocket.c + +diff --git a/configure.ac b/configure.ac +index d485915..837a838 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3424,7 +3424,6 @@ src/Makefile + src/include/Makefile + src/lib/Makefile + src/microhttpd/Makefile +-src/microhttpd_ws/Makefile + src/examples/Makefile + src/testcurl/Makefile + src/testcurl/https/Makefile +diff --git a/src/Makefile.am b/src/Makefile.am +index 0d2f49b..bb3cdcb 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -10,11 +10,6 @@ endif + + SUBDIRS = include microhttpd $(curltests) $(zzuftests) . + +-# Finally (last!) also build experimental lib... +-if HAVE_EXPERIMENTAL +-SUBDIRS += microhttpd_ws lib +-endif +- + if BUILD_EXAMPLES + SUBDIRS += examples + endif +diff --git a/src/microhttpd_ws/Makefile.am b/src/microhttpd_ws/Makefile.am +deleted file mode 100644 +index 1661250..0000000 +--- a/src/microhttpd_ws/Makefile.am ++++ /dev/null +@@ -1,39 +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) +- +-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/Makefile.in b/src/microhttpd_ws/Makefile.in +deleted file mode 100644 +index 7310753..0000000 +--- a/src/microhttpd_ws/Makefile.in ++++ /dev/null +@@ -1,1305 +0,0 @@ +-# Makefile.in generated by automake 1.16.5 from Makefile.am. +-# @configure_input@ +- +-# Copyright (C) 1994-2021 Free Software Foundation, Inc. +- +-# This Makefile.in is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +-# PARTICULAR PURPOSE. +- +-@SET_MAKE@ +- +- +-VPATH = @srcdir@ +-am__is_gnu_make = { \ +- if test -z '$(MAKELEVEL)'; then \ +- false; \ +- elif test -n '$(MAKE_HOST)'; then \ +- true; \ +- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ +- true; \ +- else \ +- false; \ +- fi; \ +-} +-am__make_running_with_option = \ +- case $${target_option-} in \ +- ?) ;; \ +- *) echo "am__make_running_with_option: internal error: invalid" \ +- "target option '$${target_option-}' specified" >&2; \ +- exit 1;; \ +- esac; \ +- has_opt=no; \ +- sane_makeflags=$$MAKEFLAGS; \ +- if $(am__is_gnu_make); then \ +- sane_makeflags=$$MFLAGS; \ +- else \ +- case $$MAKEFLAGS in \ +- *\\[\ \ ]*) \ +- bs=\\; \ +- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ +- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ +- esac; \ +- fi; \ +- skip_next=no; \ +- strip_trailopt () \ +- { \ +- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ +- }; \ +- for flg in $$sane_makeflags; do \ +- test $$skip_next = yes && { skip_next=no; continue; }; \ +- case $$flg in \ +- *=*|--*) continue;; \ +- -*I) strip_trailopt 'I'; skip_next=yes;; \ +- -*I?*) strip_trailopt 'I';; \ +- -*O) strip_trailopt 'O'; skip_next=yes;; \ +- -*O?*) strip_trailopt 'O';; \ +- -*l) strip_trailopt 'l'; skip_next=yes;; \ +- -*l?*) strip_trailopt 'l';; \ +- -[dEDm]) skip_next=yes;; \ +- -[JT]) skip_next=yes;; \ +- esac; \ +- case $$flg in \ +- *$$target_option*) has_opt=yes; break;; \ +- esac; \ +- done; \ +- test $$has_opt = yes +-am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +-am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +-pkgdatadir = $(datadir)/@PACKAGE@ +-pkgincludedir = $(includedir)/@PACKAGE@ +-pkglibdir = $(libdir)/@PACKAGE@ +-pkglibexecdir = $(libexecdir)/@PACKAGE@ +-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +-install_sh_DATA = $(install_sh) -c -m 644 +-install_sh_PROGRAM = $(install_sh) -c +-install_sh_SCRIPT = $(install_sh) -c +-INSTALL_HEADER = $(INSTALL_DATA) +-transform = $(program_transform_name) +-NORMAL_INSTALL = : +-PRE_INSTALL = : +-POST_INSTALL = : +-NORMAL_UNINSTALL = : +-PRE_UNINSTALL = : +-POST_UNINSTALL = : +-build_triplet = @build@ +-host_triplet = @host@ +-check_PROGRAMS = test_websocket$(EXEEXT) +-subdir = src/microhttpd_ws +-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ +- $(top_srcdir)/m4/ax_append_compile_flags.m4 \ +- $(top_srcdir)/m4/ax_append_flag.m4 \ +- $(top_srcdir)/m4/ax_append_link_flags.m4 \ +- $(top_srcdir)/m4/ax_check_compile_flag.m4 \ +- $(top_srcdir)/m4/ax_check_link_flag.m4 \ +- $(top_srcdir)/m4/ax_count_cpus.m4 \ +- $(top_srcdir)/m4/ax_have_epoll.m4 \ +- $(top_srcdir)/m4/ax_pthread.m4 \ +- $(top_srcdir)/m4/ax_require_defined.m4 \ +- $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/host-cpu-c-abi.m4 \ +- $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ +- $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ +- $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ +- $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ +- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ +- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ +- $(top_srcdir)/m4/mhd_check_func.m4 \ +- $(top_srcdir)/m4/mhd_shutdown_socket_trigger.m4 \ +- $(top_srcdir)/m4/mhd_sys_extentions.m4 $(top_srcdir)/m4/nls.m4 \ +- $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ +- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/search_h.m4 \ +- $(top_srcdir)/m4/tsearch.m4 $(top_srcdir)/acinclude.m4 \ +- $(top_srcdir)/configure.ac +-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ +- $(ACLOCAL_M4) +-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +-mkinstalldirs = $(install_sh) -d +-CONFIG_HEADER = $(top_builddir)/MHD_config.h +-CONFIG_CLEAN_FILES = +-CONFIG_CLEAN_VPATH_FILES = +-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +-am__vpath_adj = case $$p in \ +- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ +- *) f=$$p;; \ +- esac; +-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +-am__install_max = 40 +-am__nobase_strip_setup = \ +- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +-am__nobase_strip = \ +- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +-am__nobase_list = $(am__nobase_strip_setup); \ +- for p in $$list; do echo "$$p $$p"; done | \ +- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ +- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ +- if (++n[$$2] == $(am__install_max)) \ +- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ +- END { for (dir in files) print dir, files[dir] }' +-am__base_list = \ +- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ +- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +-am__uninstall_files_from_dir = { \ +- test -z "$$files" \ +- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ +- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ +- $(am__cd) "$$dir" && rm -f $$files; }; \ +- } +-am__installdirs = "$(DESTDIR)$(libdir)" +-LTLIBRARIES = $(lib_LTLIBRARIES) +-am__DEPENDENCIES_1 = +-libmicrohttpd_ws_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +-am_libmicrohttpd_ws_la_OBJECTS = libmicrohttpd_ws_la-sha1.lo \ +- libmicrohttpd_ws_la-mhd_websocket.lo +-libmicrohttpd_ws_la_OBJECTS = $(am_libmicrohttpd_ws_la_OBJECTS) +-AM_V_lt = $(am__v_lt_@AM_V@) +-am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +-am__v_lt_0 = --silent +-am__v_lt_1 = +-libmicrohttpd_ws_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ +- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ +- $(libmicrohttpd_ws_la_CFLAGS) $(CFLAGS) \ +- $(libmicrohttpd_ws_la_LDFLAGS) $(LDFLAGS) -o $@ +-am_test_websocket_OBJECTS = test_websocket.$(OBJEXT) +-test_websocket_OBJECTS = $(am_test_websocket_OBJECTS) +-test_websocket_DEPENDENCIES = \ +- $(top_builddir)/src/microhttpd_ws/libmicrohttpd_ws.la \ +- $(top_builddir)/src/microhttpd/libmicrohttpd.la +-AM_V_P = $(am__v_P_@AM_V@) +-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +-am__v_P_0 = false +-am__v_P_1 = : +-AM_V_GEN = $(am__v_GEN_@AM_V@) +-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +-am__v_GEN_0 = @echo " GEN " $@; +-am__v_GEN_1 = +-AM_V_at = $(am__v_at_@AM_V@) +-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +-am__v_at_0 = @ +-am__v_at_1 = +-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +-depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +-am__maybe_remake_depfiles = depfiles +-am__depfiles_remade = \ +- ./$(DEPDIR)/libmicrohttpd_ws_la-mhd_websocket.Plo \ +- ./$(DEPDIR)/libmicrohttpd_ws_la-sha1.Plo \ +- ./$(DEPDIR)/test_websocket.Po +-am__mv = mv -f +-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ +- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ +- $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ +- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ +- $(AM_CFLAGS) $(CFLAGS) +-AM_V_CC = $(am__v_CC_@AM_V@) +-am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +-am__v_CC_0 = @echo " CC " $@; +-am__v_CC_1 = +-CCLD = $(CC) +-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ +- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ +- $(AM_LDFLAGS) $(LDFLAGS) -o $@ +-AM_V_CCLD = $(am__v_CCLD_@AM_V@) +-am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +-am__v_CCLD_0 = @echo " CCLD " $@; +-am__v_CCLD_1 = +-SOURCES = $(libmicrohttpd_ws_la_SOURCES) $(test_websocket_SOURCES) +-DIST_SOURCES = $(libmicrohttpd_ws_la_SOURCES) \ +- $(test_websocket_SOURCES) +-RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ +- ctags-recursive dvi-recursive html-recursive info-recursive \ +- install-data-recursive install-dvi-recursive \ +- install-exec-recursive install-html-recursive \ +- install-info-recursive install-pdf-recursive \ +- install-ps-recursive install-recursive installcheck-recursive \ +- installdirs-recursive pdf-recursive ps-recursive \ +- tags-recursive uninstall-recursive +-am__can_run_installinfo = \ +- case $$AM_UPDATE_INFO_DIR in \ +- n|no|NO) false;; \ +- *) (install-info --version) >/dev/null 2>&1;; \ +- esac +-DATA = $(noinst_DATA) +-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ +- distclean-recursive maintainer-clean-recursive +-am__recursive_targets = \ +- $(RECURSIVE_TARGETS) \ +- $(RECURSIVE_CLEAN_TARGETS) \ +- $(am__extra_recursive_targets) +-AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ +- check recheck distdir distdir-am +-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +-# Read a list of newline-separated strings from the standard input, +-# and print each of them once, without duplicates. Input order is +-# *not* preserved. +-am__uniquify_input = $(AWK) '\ +- BEGIN { nonempty = 0; } \ +- { items[$$0] = 1; nonempty = 1; } \ +- END { if (nonempty) { for (i in items) print i; }; } \ +-' +-# Make sure the list of sources is unique. This is necessary because, +-# e.g., the same source file might be shared among _SOURCES variables +-# for different programs/libraries. +-am__define_uniq_tagged_files = \ +- list='$(am__tagged_files)'; \ +- unique=`for i in $$list; do \ +- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +- done | $(am__uniquify_input)` +-am__tty_colors_dummy = \ +- mgn= red= grn= lgn= blu= brg= std=; \ +- am__color_tests=no +-am__tty_colors = { \ +- $(am__tty_colors_dummy); \ +- if test "X$(AM_COLOR_TESTS)" = Xno; then \ +- am__color_tests=no; \ +- elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ +- am__color_tests=yes; \ +- elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ +- am__color_tests=yes; \ +- fi; \ +- if test $$am__color_tests = yes; then \ +- red=''; \ +- grn=''; \ +- lgn=''; \ +- blu=''; \ +- mgn=''; \ +- brg=''; \ +- std=''; \ +- fi; \ +-} +-am__recheck_rx = ^[ ]*:recheck:[ ]* +-am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +-am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +-# A command that, given a newline-separated list of test names on the +-# standard input, print the name of the tests that are to be re-run +-# upon "make recheck". +-am__list_recheck_tests = $(AWK) '{ \ +- recheck = 1; \ +- while ((rc = (getline line < ($$0 ".trs"))) != 0) \ +- { \ +- if (rc < 0) \ +- { \ +- if ((getline line2 < ($$0 ".log")) < 0) \ +- recheck = 0; \ +- break; \ +- } \ +- else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ +- { \ +- recheck = 0; \ +- break; \ +- } \ +- else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ +- { \ +- break; \ +- } \ +- }; \ +- if (recheck) \ +- print $$0; \ +- close ($$0 ".trs"); \ +- close ($$0 ".log"); \ +-}' +-# A command that, given a newline-separated list of test names on the +-# standard input, create the global log from their .trs and .log files. +-am__create_global_log = $(AWK) ' \ +-function fatal(msg) \ +-{ \ +- print "fatal: making $@: " msg | "cat >&2"; \ +- exit 1; \ +-} \ +-function rst_section(header) \ +-{ \ +- print header; \ +- len = length(header); \ +- for (i = 1; i <= len; i = i + 1) \ +- printf "="; \ +- printf "\n\n"; \ +-} \ +-{ \ +- copy_in_global_log = 1; \ +- global_test_result = "RUN"; \ +- while ((rc = (getline line < ($$0 ".trs"))) != 0) \ +- { \ +- if (rc < 0) \ +- fatal("failed to read from " $$0 ".trs"); \ +- if (line ~ /$(am__global_test_result_rx)/) \ +- { \ +- sub("$(am__global_test_result_rx)", "", line); \ +- sub("[ ]*$$", "", line); \ +- global_test_result = line; \ +- } \ +- else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ +- copy_in_global_log = 0; \ +- }; \ +- if (copy_in_global_log) \ +- { \ +- rst_section(global_test_result ": " $$0); \ +- while ((rc = (getline line < ($$0 ".log"))) != 0) \ +- { \ +- if (rc < 0) \ +- fatal("failed to read from " $$0 ".log"); \ +- print line; \ +- }; \ +- printf "\n"; \ +- }; \ +- close ($$0 ".trs"); \ +- close ($$0 ".log"); \ +-}' +-# Restructured Text title. +-am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +-# Solaris 10 'make', and several other traditional 'make' implementations, +-# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +-# by disabling -e (using the XSI extension "set +e") if it's set. +-am__sh_e_setup = case $$- in *e*) set +e;; esac +-# Default flags passed to test drivers. +-am__common_driver_flags = \ +- --color-tests "$$am__color_tests" \ +- --enable-hard-errors "$$am__enable_hard_errors" \ +- --expect-failure "$$am__expect_failure" +-# To be inserted before the command running the test. Creates the +-# directory for the log if needed. Stores in $dir the directory +-# containing $f, in $tst the test, in $log the log. Executes the +-# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +-# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +-# will run the test scripts (or their associated LOG_COMPILER, if +-# thy have one). +-am__check_pre = \ +-$(am__sh_e_setup); \ +-$(am__vpath_adj_setup) $(am__vpath_adj) \ +-$(am__tty_colors); \ +-srcdir=$(srcdir); export srcdir; \ +-case "$@" in \ +- */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ +- *) am__odir=.;; \ +-esac; \ +-test "x$$am__odir" = x"." || test -d "$$am__odir" \ +- || $(MKDIR_P) "$$am__odir" || exit $$?; \ +-if test -f "./$$f"; then dir=./; \ +-elif test -f "$$f"; then dir=; \ +-else dir="$(srcdir)/"; fi; \ +-tst=$$dir$$f; log='$@'; \ +-if test -n '$(DISABLE_HARD_ERRORS)'; then \ +- am__enable_hard_errors=no; \ +-else \ +- am__enable_hard_errors=yes; \ +-fi; \ +-case " $(XFAIL_TESTS) " in \ +- *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ +- am__expect_failure=yes;; \ +- *) \ +- am__expect_failure=no;; \ +-esac; \ +-$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +-# A shell command to get the names of the tests scripts with any registered +-# extension removed (i.e., equivalently, the names of the test logs, with +-# the '.log' extension removed). The result is saved in the shell variable +-# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +-# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +-# since that might cause problem with VPATH rewrites for suffix-less tests. +-# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +-am__set_TESTS_bases = \ +- bases='$(TEST_LOGS)'; \ +- bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ +- bases=`echo $$bases` +-AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +-RECHECK_LOGS = $(TEST_LOGS) +-TEST_SUITE_LOG = test-suite.log +-TEST_EXTENSIONS = @EXEEXT@ .test +-LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver +-LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +-am__set_b = \ +- case '$@' in \ +- */*) \ +- case '$*' in \ +- */*) b='$*';; \ +- *) b=`echo '$@' | sed 's/\.log$$//'`; \ +- esac;; \ +- *) \ +- b='$*';; \ +- esac +-am__test_logs1 = $(TESTS:=.log) +-am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +-TEST_LOGS = $(am__test_logs2:.test.log=.log) +-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver +-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ +- $(TEST_LOG_FLAGS) +-DIST_SUBDIRS = $(SUBDIRS) +-am__DIST_COMMON = $(srcdir)/Makefile.in \ +- $(top_srcdir)/build-aux/depcomp \ +- $(top_srcdir)/build-aux/test-driver +-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +-am__relativize = \ +- dir0=`pwd`; \ +- sed_first='s,^\([^/]*\)/.*$$,\1,'; \ +- sed_rest='s,^[^/]*/*,,'; \ +- sed_last='s,^.*/\([^/]*\)$$,\1,'; \ +- sed_butlast='s,/*[^/]*$$,,'; \ +- while test -n "$$dir1"; do \ +- first=`echo "$$dir1" | sed -e "$$sed_first"`; \ +- if test "$$first" != "."; then \ +- if test "$$first" = ".."; then \ +- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ +- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ +- else \ +- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ +- if test "$$first2" = "$$first"; then \ +- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ +- else \ +- dir2="../$$dir2"; \ +- fi; \ +- dir0="$$dir0"/"$$first"; \ +- fi; \ +- fi; \ +- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ +- done; \ +- reldir="$$dir2" +-ACLOCAL = @ACLOCAL@ +-AMTAR = @AMTAR@ +-AM_ASAN_OPTIONS = @AM_ASAN_OPTIONS@ +-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +-AM_LSAN_OPTIONS = @AM_LSAN_OPTIONS@ +-AM_TESTS_ENVIRONMENT = @AM_TESTS_ENVIRONMENT@ +-AM_UBSAN_OPTIONS = @AM_UBSAN_OPTIONS@ +-AR = @AR@ +-AS = @AS@ +-AUTOCONF = @AUTOCONF@ +-AUTOHEADER = @AUTOHEADER@ +-AUTOMAKE = @AUTOMAKE@ +-AWK = @AWK@ +-CC = @CC@ +-CCDEPMODE = @CCDEPMODE@ +-CFLAGS = @CFLAGS@ +-CPP = @CPP@ +-CPPFLAGS = @CPPFLAGS@ +-CPU_COUNT = @CPU_COUNT@ +-CSCOPE = @CSCOPE@ +-CTAGS = @CTAGS@ +-CYGPATH_W = @CYGPATH_W@ +-DEFS = @DEFS@ +-DEPDIR = @DEPDIR@ +-DLLTOOL = @DLLTOOL@ +-DSYMUTIL = @DSYMUTIL@ +-DUMPBIN = @DUMPBIN@ +-ECHO_C = @ECHO_C@ +-ECHO_N = @ECHO_N@ +-ECHO_T = @ECHO_T@ +-EGREP = @EGREP@ +-EMPTY_VAR = @EMPTY_VAR@ +-ETAGS = @ETAGS@ +-EXEEXT = @EXEEXT@ +-FGREP = @FGREP@ +-GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +-GMSGFMT = @GMSGFMT@ +-GMSGFMT_015 = @GMSGFMT_015@ +-GNULIB_MDA_LFIND = @GNULIB_MDA_LFIND@ +-GNULIB_MDA_LSEARCH = @GNULIB_MDA_LSEARCH@ +-GNULIB_TSEARCH = @GNULIB_TSEARCH@ +-GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +-GNUTLS_CPPFLAGS = @GNUTLS_CPPFLAGS@ +-GNUTLS_LDFLAGS = @GNUTLS_LDFLAGS@ +-GNUTLS_LIBS = @GNUTLS_LIBS@ +-GREP = @GREP@ +-HAVE_CURL_BINARY = @HAVE_CURL_BINARY@ +-HAVE_MAKEINFO_BINARY = @HAVE_MAKEINFO_BINARY@ +-HAVE_TSEARCH = @HAVE_TSEARCH@ +-HAVE_TWALK = @HAVE_TWALK@ +-HEAVY_TESTS_NOTPARALLEL = @HEAVY_TESTS_NOTPARALLEL@ +-HIDDEN_VISIBILITY_CFLAGS = @HIDDEN_VISIBILITY_CFLAGS@ +-INSTALL = @INSTALL@ +-INSTALL_DATA = @INSTALL_DATA@ +-INSTALL_PROGRAM = @INSTALL_PROGRAM@ +-INSTALL_SCRIPT = @INSTALL_SCRIPT@ +-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +-INTLLIBS = @INTLLIBS@ +-INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +-LD = @LD@ +-LDFLAGS = @LDFLAGS@ +-LIBCURL = @LIBCURL@ +-LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +-LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +-LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +-LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +-LIBICONV = @LIBICONV@ +-LIBINTL = @LIBINTL@ +-LIBOBJS = @LIBOBJS@ +-LIBS = @LIBS@ +-LIBTOOL = @LIBTOOL@ +-LIB_VERSION_AGE = @LIB_VERSION_AGE@ +-LIB_VERSION_CURRENT = @LIB_VERSION_CURRENT@ +-LIB_VERSION_REVISION = @LIB_VERSION_REVISION@ +-LIPO = @LIPO@ +-LN_S = @LN_S@ +-LTLIBICONV = @LTLIBICONV@ +-LTLIBINTL = @LTLIBINTL@ +-LTLIBOBJS = @LTLIBOBJS@ +-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +-MAKEINFO = @MAKEINFO@ +-MANIFEST_TOOL = @MANIFEST_TOOL@ +-MHD_LIBDEPS = @MHD_LIBDEPS@ +-MHD_LIBDEPS_PKGCFG = @MHD_LIBDEPS_PKGCFG@ +-MHD_LIB_CFLAGS = @MHD_LIB_CFLAGS@ +-MHD_LIB_CPPFLAGS = @MHD_LIB_CPPFLAGS@ +-MHD_LIB_LDFLAGS = @MHD_LIB_LDFLAGS@ +-MHD_PLUGIN_INSTALL_PREFIX = @MHD_PLUGIN_INSTALL_PREFIX@ +-MHD_REQ_PRIVATE = @MHD_REQ_PRIVATE@ +-MHD_TLS_LIBDEPS = @MHD_TLS_LIBDEPS@ +-MHD_TLS_LIB_CFLAGS = @MHD_TLS_LIB_CFLAGS@ +-MHD_TLS_LIB_CPPFLAGS = @MHD_TLS_LIB_CPPFLAGS@ +-MHD_TLS_LIB_LDFLAGS = @MHD_TLS_LIB_LDFLAGS@ +-MHD_W32_DLL_SUFF = @MHD_W32_DLL_SUFF@ +-MKDIR_P = @MKDIR_P@ +-MSGFMT = @MSGFMT@ +-MSGMERGE = @MSGMERGE@ +-MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +-MS_LIB_TOOL = @MS_LIB_TOOL@ +-NM = @NM@ +-NMEDIT = @NMEDIT@ +-OBJDUMP = @OBJDUMP@ +-OBJEXT = @OBJEXT@ +-OTOOL = @OTOOL@ +-OTOOL64 = @OTOOL64@ +-PACKAGE = @PACKAGE@ +-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +-PACKAGE_NAME = @PACKAGE_NAME@ +-PACKAGE_STRING = @PACKAGE_STRING@ +-PACKAGE_TARNAME = @PACKAGE_TARNAME@ +-PACKAGE_URL = @PACKAGE_URL@ +-PACKAGE_VERSION = @PACKAGE_VERSION@ +-PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +-PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +-PACKAGE_VERSION_SUBMINOR = @PACKAGE_VERSION_SUBMINOR@ +-PATH_SEPARATOR = @PATH_SEPARATOR@ +-PKG_CONFIG = @PKG_CONFIG@ +-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +-POSUB = @POSUB@ +-PTHREAD_CC = @PTHREAD_CC@ +-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +-PTHREAD_CXX = @PTHREAD_CXX@ +-PTHREAD_LIBS = @PTHREAD_LIBS@ +-RANLIB = @RANLIB@ +-RC = @RC@ +-REPLACE_TSEARCH = @REPLACE_TSEARCH@ +-SED = @SED@ +-SET_MAKE = @SET_MAKE@ +-SHELL = @SHELL@ +-STRIP = @STRIP@ +-USE_NLS = @USE_NLS@ +-VERSION = @VERSION@ +-W32CRT = @W32CRT@ +-XGETTEXT = @XGETTEXT@ +-XGETTEXT_015 = @XGETTEXT_015@ +-XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +-_libcurl_config = @_libcurl_config@ +-abs_builddir = @abs_builddir@ +-abs_srcdir = @abs_srcdir@ +-abs_top_builddir = @abs_top_builddir@ +-abs_top_srcdir = @abs_top_srcdir@ +-ac_configure_args = @ac_configure_args@ +-ac_ct_AR = @ac_ct_AR@ +-ac_ct_CC = @ac_ct_CC@ +-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +-am__include = @am__include@ +-am__leading_dot = @am__leading_dot@ +-am__quote = @am__quote@ +-am__tar = @am__tar@ +-am__untar = @am__untar@ +-ax_pthread_config = @ax_pthread_config@ +-bindir = @bindir@ +-build = @build@ +-build_alias = @build_alias@ +-build_cpu = @build_cpu@ +-build_os = @build_os@ +-build_vendor = @build_vendor@ +-builddir = @builddir@ +-datadir = @datadir@ +-datarootdir = @datarootdir@ +-docdir = @docdir@ +-dvidir = @dvidir@ +-exec_prefix = @exec_prefix@ +-have_socat = @have_socat@ +-have_zzuf = @have_zzuf@ +-host = @host@ +-host_alias = @host_alias@ +-host_cpu = @host_cpu@ +-host_os = @host_os@ +-host_vendor = @host_vendor@ +-htmldir = @htmldir@ +-includedir = @includedir@ +-infodir = @infodir@ +-install_sh = @install_sh@ +-libdir = @libdir@ +-libexecdir = @libexecdir@ +-localedir = @localedir@ +-localstatedir = @localstatedir@ +-lt_cv_objdir = @lt_cv_objdir@ +-mandir = @mandir@ +-mkdir_p = @mkdir_p@ +-oldincludedir = @oldincludedir@ +-pdfdir = @pdfdir@ +-prefix = @prefix@ +-program_transform_name = @program_transform_name@ +-psdir = @psdir@ +-runstatedir = @runstatedir@ +-sbindir = @sbindir@ +-sharedstatedir = @sharedstatedir@ +-srcdir = @srcdir@ +-sysconfdir = @sysconfdir@ +-target_alias = @target_alias@ +-top_build_prefix = @top_build_prefix@ +-top_builddir = @top_builddir@ +-top_srcdir = @top_srcdir@ +- +-# 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) +-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) +-test_websocket_SOURCES = \ +- test_websocket.c +- +-test_websocket_LDADD = \ +- $(top_builddir)/src/microhttpd_ws/libmicrohttpd_ws.la \ +- $(top_builddir)/src/microhttpd/libmicrohttpd.la +- +-all: all-recursive +- +-.SUFFIXES: +-.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +- @for dep in $?; do \ +- case '$(am__configure_deps)' in \ +- *$$dep*) \ +- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ +- && { if test -f $@; then exit 0; else break; fi; }; \ +- exit 1;; \ +- esac; \ +- done; \ +- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/microhttpd_ws/Makefile'; \ +- $(am__cd) $(top_srcdir) && \ +- $(AUTOMAKE) --gnu src/microhttpd_ws/Makefile +-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status +- @case '$?' in \ +- *config.status*) \ +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ +- *) \ +- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ +- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ +- esac; +- +-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +- +-$(top_srcdir)/configure: $(am__configure_deps) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +-$(ACLOCAL_M4): $(am__aclocal_m4_deps) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +-$(am__aclocal_m4_deps): +- +-clean-checkPROGRAMS: +- @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ +- echo " rm -f" $$list; \ +- rm -f $$list || exit $$?; \ +- test -n "$(EXEEXT)" || exit 0; \ +- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ +- echo " rm -f" $$list; \ +- rm -f $$list +- +-install-libLTLIBRARIES: $(lib_LTLIBRARIES) +- @$(NORMAL_INSTALL) +- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ +- list2=; for p in $$list; do \ +- if test -f $$p; then \ +- list2="$$list2 $$p"; \ +- else :; fi; \ +- done; \ +- test -z "$$list2" || { \ +- echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ +- $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ +- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ +- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ +- } +- +-uninstall-libLTLIBRARIES: +- @$(NORMAL_UNINSTALL) +- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ +- for p in $$list; do \ +- $(am__strip_dir) \ +- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ +- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ +- done +- +-clean-libLTLIBRARIES: +- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) +- @list='$(lib_LTLIBRARIES)'; \ +- locs=`for p in $$list; do echo $$p; done | \ +- sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ +- sort -u`; \ +- test -z "$$locs" || { \ +- echo rm -f $${locs}; \ +- rm -f $${locs}; \ +- } +- +-libmicrohttpd_ws.la: $(libmicrohttpd_ws_la_OBJECTS) $(libmicrohttpd_ws_la_DEPENDENCIES) $(EXTRA_libmicrohttpd_ws_la_DEPENDENCIES) +- $(AM_V_CCLD)$(libmicrohttpd_ws_la_LINK) -rpath $(libdir) $(libmicrohttpd_ws_la_OBJECTS) $(libmicrohttpd_ws_la_LIBADD) $(LIBS) +- +-test_websocket$(EXEEXT): $(test_websocket_OBJECTS) $(test_websocket_DEPENDENCIES) $(EXTRA_test_websocket_DEPENDENCIES) +- @rm -f test_websocket$(EXEEXT) +- $(AM_V_CCLD)$(LINK) $(test_websocket_OBJECTS) $(test_websocket_LDADD) $(LIBS) +- +-mostlyclean-compile: +- -rm -f *.$(OBJEXT) +- +-distclean-compile: +- -rm -f *.tab.c +- +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmicrohttpd_ws_la-mhd_websocket.Plo@am__quote@ # am--include-marker +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmicrohttpd_ws_la-sha1.Plo@am__quote@ # am--include-marker +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_websocket.Po@am__quote@ # am--include-marker +- +-$(am__depfiles_remade): +- @$(MKDIR_P) $(@D) +- @echo '# dummy' >$@-t && $(am__mv) $@-t $@ +- +-am--depfiles: $(am__depfiles_remade) +- +-.c.o: +-@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +-@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +- +-.c.obj: +-@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +-@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +- +-.c.lo: +-@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +-@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +- +-libmicrohttpd_ws_la-sha1.lo: sha1.c +-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmicrohttpd_ws_la_CPPFLAGS) $(CPPFLAGS) $(libmicrohttpd_ws_la_CFLAGS) $(CFLAGS) -MT libmicrohttpd_ws_la-sha1.lo -MD -MP -MF $(DEPDIR)/libmicrohttpd_ws_la-sha1.Tpo -c -o libmicrohttpd_ws_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c +-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmicrohttpd_ws_la-sha1.Tpo $(DEPDIR)/libmicrohttpd_ws_la-sha1.Plo +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1.c' object='libmicrohttpd_ws_la-sha1.lo' libtool=yes @AMDEPBACKSLASH@ +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmicrohttpd_ws_la_CPPFLAGS) $(CPPFLAGS) $(libmicrohttpd_ws_la_CFLAGS) $(CFLAGS) -c -o libmicrohttpd_ws_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c +- +-libmicrohttpd_ws_la-mhd_websocket.lo: mhd_websocket.c +-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmicrohttpd_ws_la_CPPFLAGS) $(CPPFLAGS) $(libmicrohttpd_ws_la_CFLAGS) $(CFLAGS) -MT libmicrohttpd_ws_la-mhd_websocket.lo -MD -MP -MF $(DEPDIR)/libmicrohttpd_ws_la-mhd_websocket.Tpo -c -o libmicrohttpd_ws_la-mhd_websocket.lo `test -f 'mhd_websocket.c' || echo '$(srcdir)/'`mhd_websocket.c +-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmicrohttpd_ws_la-mhd_websocket.Tpo $(DEPDIR)/libmicrohttpd_ws_la-mhd_websocket.Plo +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mhd_websocket.c' object='libmicrohttpd_ws_la-mhd_websocket.lo' libtool=yes @AMDEPBACKSLASH@ +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmicrohttpd_ws_la_CPPFLAGS) $(CPPFLAGS) $(libmicrohttpd_ws_la_CFLAGS) $(CFLAGS) -c -o libmicrohttpd_ws_la-mhd_websocket.lo `test -f 'mhd_websocket.c' || echo '$(srcdir)/'`mhd_websocket.c +- +-mostlyclean-libtool: +- -rm -f *.lo +- +-clean-libtool: +- -rm -rf .libs _libs +- +-# This directory's subdirectories are mostly independent; you can cd +-# into them and run 'make' without going through this Makefile. +-# To change the values of 'make' variables: instead of editing Makefiles, +-# (1) if the variable is set in 'config.status', edit 'config.status' +-# (which will cause the Makefiles to be regenerated when you run 'make'); +-# (2) otherwise, pass the desired values on the 'make' command line. +-$(am__recursive_targets): +- @fail=; \ +- if $(am__make_keepgoing); then \ +- failcom='fail=yes'; \ +- else \ +- failcom='exit 1'; \ +- fi; \ +- dot_seen=no; \ +- target=`echo $@ | sed s/-recursive//`; \ +- case "$@" in \ +- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ +- *) list='$(SUBDIRS)' ;; \ +- esac; \ +- for subdir in $$list; do \ +- echo "Making $$target in $$subdir"; \ +- if test "$$subdir" = "."; then \ +- dot_seen=yes; \ +- local_target="$$target-am"; \ +- else \ +- local_target="$$target"; \ +- fi; \ +- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ +- || eval $$failcom; \ +- done; \ +- if test "$$dot_seen" = "no"; then \ +- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ +- fi; test -z "$$fail" +- +-ID: $(am__tagged_files) +- $(am__define_uniq_tagged_files); mkid -fID $$unique +-tags: tags-recursive +-TAGS: tags +- +-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +- set x; \ +- here=`pwd`; \ +- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ +- include_option=--etags-include; \ +- empty_fix=.; \ +- else \ +- include_option=--include; \ +- empty_fix=; \ +- fi; \ +- list='$(SUBDIRS)'; for subdir in $$list; do \ +- if test "$$subdir" = .; then :; else \ +- test ! -f $$subdir/TAGS || \ +- set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ +- fi; \ +- done; \ +- $(am__define_uniq_tagged_files); \ +- shift; \ +- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ +- test -n "$$unique" || unique=$$empty_fix; \ +- if test $$# -gt 0; then \ +- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +- "$$@" $$unique; \ +- else \ +- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +- $$unique; \ +- fi; \ +- fi +-ctags: ctags-recursive +- +-CTAGS: ctags +-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +- $(am__define_uniq_tagged_files); \ +- test -z "$(CTAGS_ARGS)$$unique" \ +- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ +- $$unique +- +-GTAGS: +- here=`$(am__cd) $(top_builddir) && pwd` \ +- && $(am__cd) $(top_srcdir) \ +- && gtags -i $(GTAGS_ARGS) "$$here" +-cscopelist: cscopelist-recursive +- +-cscopelist-am: $(am__tagged_files) +- list='$(am__tagged_files)'; \ +- case "$(srcdir)" in \ +- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ +- *) sdir=$(subdir)/$(srcdir) ;; \ +- esac; \ +- for i in $$list; do \ +- if test -f "$$i"; then \ +- echo "$(subdir)/$$i"; \ +- else \ +- echo "$$sdir/$$i"; \ +- fi; \ +- done >> $(top_builddir)/cscope.files +- +-distclean-tags: +- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +- +-# Recover from deleted '.trs' file; this should ensure that +-# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +-# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +-# to avoid problems with "make -n". +-.log.trs: +- rm -f $< $@ +- $(MAKE) $(AM_MAKEFLAGS) $< +- +-# Leading 'am--fnord' is there to ensure the list of targets does not +-# expand to empty, as could happen e.g. with make check TESTS=''. +-am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +-am--force-recheck: +- @: +- +-$(TEST_SUITE_LOG): $(TEST_LOGS) +- @$(am__set_TESTS_bases); \ +- am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ +- redo_bases=`for i in $$bases; do \ +- am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ +- done`; \ +- if test -n "$$redo_bases"; then \ +- redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ +- redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ +- if $(am__make_dryrun); then :; else \ +- rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ +- fi; \ +- fi; \ +- if test -n "$$am__remaking_logs"; then \ +- echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ +- "recursion detected" >&2; \ +- elif test -n "$$redo_logs"; then \ +- am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ +- fi; \ +- if $(am__make_dryrun); then :; else \ +- st=0; \ +- errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ +- for i in $$redo_bases; do \ +- test -f $$i.trs && test -r $$i.trs \ +- || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ +- test -f $$i.log && test -r $$i.log \ +- || { echo "$$errmsg $$i.log" >&2; st=1; }; \ +- done; \ +- test $$st -eq 0 || exit 1; \ +- fi +- @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ +- ws='[ ]'; \ +- results=`for b in $$bases; do echo $$b.trs; done`; \ +- test -n "$$results" || results=/dev/null; \ +- all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ +- pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ +- fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ +- skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ +- xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ +- xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ +- error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ +- if test `expr $$fail + $$xpass + $$error` -eq 0; then \ +- success=true; \ +- else \ +- success=false; \ +- fi; \ +- br='==================='; br=$$br$$br$$br$$br; \ +- result_count () \ +- { \ +- if test x"$$1" = x"--maybe-color"; then \ +- maybe_colorize=yes; \ +- elif test x"$$1" = x"--no-color"; then \ +- maybe_colorize=no; \ +- else \ +- echo "$@: invalid 'result_count' usage" >&2; exit 4; \ +- fi; \ +- shift; \ +- desc=$$1 count=$$2; \ +- if test $$maybe_colorize = yes && test $$count -gt 0; then \ +- color_start=$$3 color_end=$$std; \ +- else \ +- color_start= color_end=; \ +- fi; \ +- echo "$${color_start}# $$desc $$count$${color_end}"; \ +- }; \ +- create_testsuite_report () \ +- { \ +- result_count $$1 "TOTAL:" $$all "$$brg"; \ +- result_count $$1 "PASS: " $$pass "$$grn"; \ +- result_count $$1 "SKIP: " $$skip "$$blu"; \ +- result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ +- result_count $$1 "FAIL: " $$fail "$$red"; \ +- result_count $$1 "XPASS:" $$xpass "$$red"; \ +- result_count $$1 "ERROR:" $$error "$$mgn"; \ +- }; \ +- { \ +- echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ +- $(am__rst_title); \ +- create_testsuite_report --no-color; \ +- echo; \ +- echo ".. contents:: :depth: 2"; \ +- echo; \ +- for b in $$bases; do echo $$b; done \ +- | $(am__create_global_log); \ +- } >$(TEST_SUITE_LOG).tmp || exit 1; \ +- mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ +- if $$success; then \ +- col="$$grn"; \ +- else \ +- col="$$red"; \ +- test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ +- fi; \ +- echo "$${col}$$br$${std}"; \ +- echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ +- echo "$${col}$$br$${std}"; \ +- create_testsuite_report --maybe-color; \ +- echo "$$col$$br$$std"; \ +- if $$success; then :; else \ +- echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ +- if test -n "$(PACKAGE_BUGREPORT)"; then \ +- echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ +- fi; \ +- echo "$$col$$br$$std"; \ +- fi; \ +- $$success || exit 1 +- +-check-TESTS: $(check_PROGRAMS) +- @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list +- @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list +- @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) +- @set +e; $(am__set_TESTS_bases); \ +- log_list=`for i in $$bases; do echo $$i.log; done`; \ +- trs_list=`for i in $$bases; do echo $$i.trs; done`; \ +- log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ +- $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ +- exit $$?; +-recheck: all $(check_PROGRAMS) +- @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) +- @set +e; $(am__set_TESTS_bases); \ +- bases=`for i in $$bases; do echo $$i; done \ +- | $(am__list_recheck_tests)` || exit 1; \ +- log_list=`for i in $$bases; do echo $$i.log; done`; \ +- log_list=`echo $$log_list`; \ +- $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ +- am__force_recheck=am--force-recheck \ +- TEST_LOGS="$$log_list"; \ +- exit $$? +-test_websocket.log: test_websocket$(EXEEXT) +- @p='test_websocket$(EXEEXT)'; \ +- b='test_websocket'; \ +- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ +- --log-file $$b.log --trs-file $$b.trs \ +- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ +- "$$tst" $(AM_TESTS_FD_REDIRECT) +-.test.log: +- @p='$<'; \ +- $(am__set_b); \ +- $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +- --log-file $$b.log --trs-file $$b.trs \ +- $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +- "$$tst" $(AM_TESTS_FD_REDIRECT) +-@am__EXEEXT_TRUE@.test$(EXEEXT).log: +-@am__EXEEXT_TRUE@ @p='$<'; \ +-@am__EXEEXT_TRUE@ $(am__set_b); \ +-@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +-@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +-@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +-@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +-distdir: $(BUILT_SOURCES) +- $(MAKE) $(AM_MAKEFLAGS) distdir-am +- +-distdir-am: $(DISTFILES) +- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- list='$(DISTFILES)'; \ +- dist_files=`for file in $$list; do echo $$file; done | \ +- sed -e "s|^$$srcdirstrip/||;t" \ +- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ +- case $$dist_files in \ +- */*) $(MKDIR_P) `echo "$$dist_files" | \ +- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ +- sort -u` ;; \ +- esac; \ +- for file in $$dist_files; do \ +- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ +- if test -d $$d/$$file; then \ +- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ +- if test -d "$(distdir)/$$file"; then \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ +- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ +- else \ +- test -f "$(distdir)/$$file" \ +- || cp -p $$d/$$file "$(distdir)/$$file" \ +- || exit 1; \ +- fi; \ +- done +- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ +- if test "$$subdir" = .; then :; else \ +- $(am__make_dryrun) \ +- || test -d "$(distdir)/$$subdir" \ +- || $(MKDIR_P) "$(distdir)/$$subdir" \ +- || exit 1; \ +- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ +- $(am__relativize); \ +- new_distdir=$$reldir; \ +- dir1=$$subdir; dir2="$(top_distdir)"; \ +- $(am__relativize); \ +- new_top_distdir=$$reldir; \ +- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ +- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ +- ($(am__cd) $$subdir && \ +- $(MAKE) $(AM_MAKEFLAGS) \ +- top_distdir="$$new_top_distdir" \ +- distdir="$$new_distdir" \ +- am__remove_distdir=: \ +- am__skip_length_check=: \ +- am__skip_mode_fix=: \ +- distdir) \ +- || exit 1; \ +- fi; \ +- done +-check-am: all-am +- $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) +- $(MAKE) $(AM_MAKEFLAGS) check-TESTS +-check: check-recursive +-all-am: Makefile $(LTLIBRARIES) $(DATA) +-install-checkPROGRAMS: install-libLTLIBRARIES +- +-installdirs: installdirs-recursive +-installdirs-am: +- for dir in "$(DESTDIR)$(libdir)"; do \ +- test -z "$$dir" || $(MKDIR_P) "$$dir"; \ +- done +-install: install-recursive +-install-exec: install-exec-recursive +-install-data: install-data-recursive +-uninstall: uninstall-recursive +- +-install-am: all-am +- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +- +-installcheck: installcheck-recursive +-install-strip: +- if test -z '$(STRIP)'; then \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- install; \ +- else \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ +- fi +-mostlyclean-generic: +- -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) +- -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) +- -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) +- -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) +- +-clean-generic: +- +-distclean-generic: +- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) +- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) +- +-maintainer-clean-generic: +- @echo "This command is intended for maintainers to use" +- @echo "it deletes files that may require special tools to rebuild." +-clean: clean-recursive +- +-clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ +- clean-libtool mostlyclean-am +- +-distclean: distclean-recursive +- -rm -f ./$(DEPDIR)/libmicrohttpd_ws_la-mhd_websocket.Plo +- -rm -f ./$(DEPDIR)/libmicrohttpd_ws_la-sha1.Plo +- -rm -f ./$(DEPDIR)/test_websocket.Po +- -rm -f Makefile +-distclean-am: clean-am distclean-compile distclean-generic \ +- distclean-tags +- +-dvi: dvi-recursive +- +-dvi-am: +- +-html: html-recursive +- +-html-am: +- +-info: info-recursive +- +-info-am: +- +-install-data-am: +- +-install-dvi: install-dvi-recursive +- +-install-dvi-am: +- +-install-exec-am: install-libLTLIBRARIES +- +-install-html: install-html-recursive +- +-install-html-am: +- +-install-info: install-info-recursive +- +-install-info-am: +- +-install-man: +- +-install-pdf: install-pdf-recursive +- +-install-pdf-am: +- +-install-ps: install-ps-recursive +- +-install-ps-am: +- +-installcheck-am: +- +-maintainer-clean: maintainer-clean-recursive +- -rm -f ./$(DEPDIR)/libmicrohttpd_ws_la-mhd_websocket.Plo +- -rm -f ./$(DEPDIR)/libmicrohttpd_ws_la-sha1.Plo +- -rm -f ./$(DEPDIR)/test_websocket.Po +- -rm -f Makefile +-maintainer-clean-am: distclean-am maintainer-clean-generic +- +-mostlyclean: mostlyclean-recursive +- +-mostlyclean-am: mostlyclean-compile mostlyclean-generic \ +- mostlyclean-libtool +- +-pdf: pdf-recursive +- +-pdf-am: +- +-ps: ps-recursive +- +-ps-am: +- +-uninstall-am: uninstall-libLTLIBRARIES +- +-.MAKE: $(am__recursive_targets) check-am install-am install-strip +- +-.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ +- am--depfiles check check-TESTS check-am clean \ +- clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ +- clean-libtool cscopelist-am ctags ctags-am distclean \ +- distclean-compile distclean-generic distclean-libtool \ +- distclean-tags distdir dvi dvi-am html html-am info info-am \ +- install install-am install-data install-data-am install-dvi \ +- install-dvi-am install-exec install-exec-am install-html \ +- install-html-am install-info install-info-am \ +- install-libLTLIBRARIES install-man install-pdf install-pdf-am \ +- install-ps install-ps-am install-strip installcheck \ +- installcheck-am installdirs installdirs-am maintainer-clean \ +- maintainer-clean-generic mostlyclean mostlyclean-compile \ +- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ +- recheck tags tags-am uninstall uninstall-am \ +- uninstall-libLTLIBRARIES +- +-.PRECIOUS: Makefile +- +- +-# Tell versions [3.59,3.63) of GNU make to not export all variables. +-# Otherwise a system limit (for SysV at least) may be exceeded. +-.NOEXPORT: +diff --git a/src/microhttpd_ws/mhd_websocket.c b/src/microhttpd_ws/mhd_websocket.c +deleted file mode 100644 +index 935deee..0000000 +--- a/src/microhttpd_ws/mhd_websocket.c ++++ /dev/null +@@ -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 +deleted file mode 100644 +index 1e9da5c..0000000 +--- a/src/microhttpd_ws/sha1.c ++++ /dev/null +@@ -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 . +-*/ +- +-/** +- * @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 +-#ifdef HAVE_MEMORY_H +-#include +-#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 +deleted file mode 100644 +index 851a442..0000000 +--- a/src/microhttpd_ws/sha1.h ++++ /dev/null +@@ -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 . +-*/ +- +-/** +- * @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 +-#ifdef HAVE_STDDEF_H +-#include /* 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 +deleted file mode 100644 +index 00fd8e0..0000000 +--- a/src/microhttpd_ws/test_websocket.c ++++ /dev/null +@@ -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 +-#include +-#include +-#include +-#include +- +-#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 keyowrd */ +- 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 */ +-} +-- +2.34.1 + diff --git a/meta/recipes-support/libmicrohttpd/libmicrohttpd_0.9.76.bb b/meta/recipes-support/libmicrohttpd/libmicrohttpd_0.9.76.bb index ad3c34ab9e..1c859825b9 100644 --- a/meta/recipes-support/libmicrohttpd/libmicrohttpd_0.9.76.bb +++ b/meta/recipes-support/libmicrohttpd/libmicrohttpd_0.9.76.bb @@ -6,7 +6,8 @@ SECTION = "net" DEPENDS = "file" -SRC_URI = "${GNU_MIRROR}/libmicrohttpd/${BPN}-${PV}.tar.gz" +SRC_URI = "${GNU_MIRROR}/libmicrohttpd/${BPN}-${PV}.tar.gz \ + file://0001-Remove-broken-experimental-code.patch" SRC_URI[sha256sum] = "f0b1547b5a42a6c0f724e8e1c1cb5ce9c4c35fb495e7d780b9930d35011ceb4c" inherit autotools lib_package pkgconfig gettext