From 4a14c689e55acb3a1c7b3e04d4b1c938c36f4968 Mon Sep 17 00:00:00 2001 From: Knutwurst <36196269+knutwurst@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:28:20 +0200 Subject: [PATCH] Vendor web server dependency for standalone workspace --- Makefile | 6 +- README.md | 16 +- vendor/etahen/include/microhttpd.h | 6525 ++++++++++++++++++++++++++++ vendor/etahen/lib/libmicrohttpd.a | Bin 0 -> 409986 bytes 4 files changed, 6538 insertions(+), 9 deletions(-) create mode 100644 vendor/etahen/include/microhttpd.h create mode 100644 vendor/etahen/lib/libmicrohttpd.a diff --git a/Makefile b/Makefile index e16893d..cba1fc0 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ PS5_HOST ?= ps5 PS5_PORT ?= 9021 PATCHDL_HTTP_PORT ?= 12880 -ETAHEN_SOURCE_DIR ?= ../Source Code +ETAHEN_DEPS_DIR ?= vendor/etahen ifdef PS5_PAYLOAD_SDK include $(PS5_PAYLOAD_SDK)/toolchain/prospero.mk @@ -17,8 +17,8 @@ SRCS := src/main.c src/patchdl_assets.c src/patchdl_websrv.c WEB_ASSETS := web/index.html web/styles.css web/app.js GEN_SRCS := $(patsubst web/%,gen/web/%.c,$(WEB_ASSETS)) -CFLAGS := -g -O2 -Wall -Werror -Isrc -I"$(ETAHEN_SOURCE_DIR)/include" -DPATCHDL_HTTP_PORT=$(PATCHDL_HTTP_PORT) -LDADD := -L"$(ETAHEN_SOURCE_DIR)/lib" -lmicrohttpd -lkernel_sys +CFLAGS := -g -O2 -Wall -Werror -Isrc -I"$(ETAHEN_DEPS_DIR)/include" -DPATCHDL_HTTP_PORT=$(PATCHDL_HTTP_PORT) +LDADD := -L"$(ETAHEN_DEPS_DIR)/lib" -lmicrohttpd -lkernel_sys all: $(BIN) diff --git a/README.md b/README.md index 65a1a58..26b25ef 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ Makefile src/ Embedded web server entrypoint and API stubs. +vendor/etahen/ + Vendored libmicrohttpd header and static library required for standalone + builds. + web/ Static web UI prototype for the future embedded PatchDL web server. ``` @@ -72,12 +76,12 @@ patchdl-ps5.elf 12881 ## Building PatchDL builds against `ps5-payload-dev/sdk` and reuses etaHEN's checked-in -`libmicrohttpd.a` plus header files. By default, the Makefile expects etaHEN's -source tree next to this repository: +`libmicrohttpd.a` plus header files. The required etaHEN build dependency is +vendored in this repository: ```text -../Source Code/include -../Source Code/lib +vendor/etahen/include/microhttpd.h +vendor/etahen/lib/libmicrohttpd.a ``` If the SDK is unpacked into `.toolchains/ps5-payload-sdk/ps5-payload-sdk`, the @@ -97,11 +101,11 @@ make clean all Override paths and ports as needed: ```sh -make ETAHEN_SOURCE_DIR="/path/to/etaHEN/Source Code" PATCHDL_HTTP_PORT=12881 +make ETAHEN_DEPS_DIR="vendor/etahen" PATCHDL_HTTP_PORT=12881 ``` Deploy with an ELF loader listening on the PS5: ```sh -PS5_HOST=ps5 PS5_PORT=9021 scripts/build_ps5.sh test +PS5_HOST=192.168.178.90 PS5_PORT=9021 scripts/build_ps5.sh test ``` diff --git a/vendor/etahen/include/microhttpd.h b/vendor/etahen/include/microhttpd.h new file mode 100644 index 0000000..ca27b6c --- /dev/null +++ b/vendor/etahen/include/microhttpd.h @@ -0,0 +1,6525 @@ +/* + This file is part of libmicrohttpd + Copyright (C) 2006-2021 Christian Grothoff (and other contributing authors) + Copyright (C) 2014-2023 Evgeny Grin (Karlson2k) + + 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.h + * @brief public interface to libmicrohttpd + * @author Christian Grothoff + * @author Karlson2k (Evgeny Grin) + * @author Chris GauthierDickey + * + * All symbols defined in this header start with MHD. MHD is a small + * HTTP daemon library. As such, it does not have any API for logging + * errors (you can only enable or disable logging to stderr). Also, + * it may not support all of the HTTP features directly, where + * applicable, portions of HTTP may have to be handled by clients of + * the library. + * + * The library is supposed to handle everything that it must handle + * (because the API would not allow clients to do this), such as basic + * connection management; however, detailed interpretations of headers + * -- such as range requests -- and HTTP methods are left to clients. + * The library does understand HEAD and will only send the headers of + * the response and not the body, even if the client supplied a body. + * The library also understands headers that control connection + * management (specifically, "Connection: close" and "Expect: 100 + * continue" are understood and handled automatically). + * + * MHD understands POST data and is able to decode certain formats + * (at the moment only "application/x-www-form-urlencoded" and + * "multipart/formdata"). Unsupported encodings and large POST + * submissions may require the application to manually process + * the stream, which is provided to the main application (and thus can be + * processed, just not conveniently by MHD). + * + * The header file defines various constants used by the HTTP protocol. + * This does not mean that MHD actually interprets all of these + * values. The provided constants are exported as a convenience + * for users of the library. MHD does not verify that transmitted + * HTTP headers are part of the standard specification; users of the + * library are free to define their own extensions of the HTTP + * standard and use those with MHD. + * + * All functions are guaranteed to be completely reentrant and + * thread-safe (with the exception of #MHD_set_connection_value, + * which must only be used in a particular context). + * + * + * @defgroup event event-loop control + * MHD API to start and stop the HTTP server and manage the event loop. + * @defgroup response generation of responses + * MHD API used to generate responses. + * @defgroup request handling of requests + * MHD API used to access information about requests. + * @defgroup authentication HTTP authentication + * MHD API related to basic and digest HTTP authentication. + * @defgroup logging logging + * MHD API to mange logging and error handling + * @defgroup specialized misc. specialized functions + * This group includes functions that do not fit into any particular + * category and that are rarely used. + */ + +#ifndef MHD_MICROHTTPD_H +#define MHD_MICROHTTPD_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Current version of the library in packed BCD form. + * @note Version number components are coded as Simple Binary-Coded Decimal + * (also called Natural BCD or BCD 8421). While they are hexadecimal numbers, + * they are parsed as decimal numbers. + * Example: 0x01093001 = 1.9.30-1. + */ +#define MHD_VERSION 0x01000100 + +/* If generic headers don't work on your platform, include headers + which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t', + 'uint8_t', 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t', + 'struct sockaddr', 'socklen_t', 'fd_set' and "#define MHD_PLATFORM_H" before + including "microhttpd.h". Then the following "standard" + includes won't be used (which might be a good idea, especially + on platforms where they do not exist). + */ +#ifndef MHD_PLATFORM_H +#if defined(_WIN32) && ! defined(__CYGWIN__) && \ + ! defined(_CRT_DECLARE_NONSTDC_NAMES) +/* Declare POSIX-compatible names */ +#define _CRT_DECLARE_NONSTDC_NAMES 1 +#endif /* _WIN32 && ! __CYGWIN__ && ! _CRT_DECLARE_NONSTDC_NAMES */ +#include +#include +#include +#if ! defined(_WIN32) || defined(__CYGWIN__) +#include +#include +#include +#else /* _WIN32 && ! __CYGWIN__ */ +#include +#if defined(_MSC_FULL_VER) && ! defined(_SSIZE_T_DEFINED) +#define _SSIZE_T_DEFINED +typedef intptr_t ssize_t; +#endif /* !_SSIZE_T_DEFINED */ +#endif /* _WIN32 && ! __CYGWIN__ */ +#endif + +#if defined(__CYGWIN__) && ! defined(_SYS_TYPES_FD_SET) +/* Do not define __USE_W32_SOCKETS under Cygwin! */ +#error Cygwin with winsock fd_set is not supported +#endif + +#ifdef __has_attribute +#if __has_attribute (flag_enum) +#define _MHD_FLAGS_ENUM __attribute__((flag_enum)) +#endif /* flag_enum */ +#if __has_attribute (enum_extensibility) +#define _MHD_FIXED_ENUM __attribute__((enum_extensibility (closed))) +#endif /* enum_extensibility */ +#endif /* __has_attribute */ + +#ifndef _MHD_FLAGS_ENUM +#define _MHD_FLAGS_ENUM +#endif /* _MHD_FLAGS_ENUM */ +#ifndef _MHD_FIXED_ENUM +#define _MHD_FIXED_ENUM +#endif /* _MHD_FIXED_ENUM */ + +#define _MHD_FIXED_FLAGS_ENUM _MHD_FIXED_ENUM _MHD_FLAGS_ENUM + +/** + * Operational results from MHD calls. + */ +enum MHD_Result +{ + /** + * MHD result code for "NO". + */ + MHD_NO = 0, + + /** + * MHD result code for "YES". + */ + MHD_YES = 1 + +} _MHD_FIXED_ENUM; + +/** + * Constant used to indicate unknown size (use when + * creating a response). + */ +#ifdef UINT64_MAX +#define MHD_SIZE_UNKNOWN UINT64_MAX +#else +#define MHD_SIZE_UNKNOWN ((uint64_t) -1LL) +#endif + +#define MHD_CONTENT_READER_END_OF_STREAM ((ssize_t) -1) +#define MHD_CONTENT_READER_END_WITH_ERROR ((ssize_t) -2) + +#ifndef _MHD_EXTERN +#if defined(_WIN32) && defined(MHD_W32LIB) +#define _MHD_EXTERN extern +#elif defined(_WIN32) && defined(MHD_W32DLL) +/* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */ +#define _MHD_EXTERN __declspec(dllimport) +#else +#define _MHD_EXTERN extern +#endif +#endif + +#ifndef MHD_SOCKET_DEFINED +/** + * MHD_socket is type for socket FDs + */ +#if ! defined(_WIN32) || defined(_SYS_TYPES_FD_SET) +#define MHD_POSIX_SOCKETS 1 +typedef int MHD_socket; +#define MHD_INVALID_SOCKET (-1) +#else /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */ +#define MHD_WINSOCK_SOCKETS 1 +#include +typedef SOCKET MHD_socket; +#define MHD_INVALID_SOCKET (INVALID_SOCKET) +#endif /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */ +#define MHD_SOCKET_DEFINED 1 +#endif /* MHD_SOCKET_DEFINED */ + +/** + * Define MHD_NO_DEPRECATION before including "microhttpd.h" to disable deprecation messages + */ +#ifdef MHD_NO_DEPRECATION +#define _MHD_DEPR_MACRO(msg) +#define _MHD_NO_DEPR_IN_MACRO 1 +#define _MHD_DEPR_IN_MACRO(msg) +#define _MHD_NO_DEPR_FUNC 1 +#define _MHD_DEPR_FUNC(msg) +#endif /* MHD_NO_DEPRECATION */ + +#ifndef _MHD_DEPR_MACRO +#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1500 +/* VS 2008 or later */ +/* Stringify macros */ +#define _MHD_INSTRMACRO(a) #a +#define _MHD_STRMACRO(a) _MHD_INSTRMACRO (a) +/* deprecation message */ +#define _MHD_DEPR_MACRO(msg) \ + __pragma(message (__FILE__ "(" _MHD_STRMACRO ( __LINE__) "): warning: " msg)) +#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg) +#elif defined(__clang__) || defined(__GNUC_PATCHLEVEL__) +/* clang or GCC since 3.0 */ +#define _MHD_GCC_PRAG(x) _Pragma(#x) +#if (defined(__clang__) && \ + (__clang_major__ + 0 >= 5 || \ + (! defined(__apple_build_version__) && \ + (__clang_major__ + 0 > 3 || \ + (__clang_major__ + 0 == 3 && __clang_minor__ >= 3))))) || \ + __GNUC__ + 0 > 4 || (__GNUC__ + 0 == 4 && __GNUC_MINOR__ + 0 >= 8) +/* clang >= 3.3 (or XCode's clang >= 5.0) or + GCC >= 4.8 */ +#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG (GCC warning msg) +#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg) +#else /* older clang or GCC */ +/* clang < 3.3, XCode's clang < 5.0, 3.0 <= GCC < 4.8 */ +#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG (message msg) +#if (defined(__clang__) && \ + (__clang_major__ + 0 > 2 || \ + (__clang_major__ + 0 == 2 && __clang_minor__ >= 9))) /* clang >= 2.9 */ +/* clang handles inline pragmas better than GCC */ +#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg) +#endif /* clang >= 2.9 */ +#endif /* older clang or GCC */ +/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */ +#endif /* clang || GCC >= 3.0 */ +#endif /* !_MHD_DEPR_MACRO */ + +#ifndef _MHD_DEPR_MACRO +#define _MHD_DEPR_MACRO(msg) +#endif /* !_MHD_DEPR_MACRO */ + +#ifndef _MHD_DEPR_IN_MACRO +#define _MHD_NO_DEPR_IN_MACRO 1 +#define _MHD_DEPR_IN_MACRO(msg) +#endif /* !_MHD_DEPR_IN_MACRO */ + +#ifndef _MHD_DEPR_FUNC +#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1400 +/* VS 2005 or later */ +#define _MHD_DEPR_FUNC(msg) __declspec(deprecated (msg)) +#elif defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1310 +/* VS .NET 2003 deprecation does not support custom messages */ +#define _MHD_DEPR_FUNC(msg) __declspec(deprecated) +#elif (__GNUC__ + 0 >= 5) || (defined(__clang__) && \ + (__clang_major__ + 0 > 2 || \ + (__clang_major__ + 0 == 2 && __clang_minor__ >= 9))) +/* GCC >= 5.0 or clang >= 2.9 */ +#define _MHD_DEPR_FUNC(msg) __attribute__((deprecated (msg))) +#elif defined(__clang__) || __GNUC__ + 0 > 3 || \ + (__GNUC__ + 0 == 3 && __GNUC_MINOR__ + 0 >= 1) +/* 3.1 <= GCC < 5.0 or clang < 2.9 */ +/* old GCC-style deprecation does not support custom messages */ +#define _MHD_DEPR_FUNC(msg) __attribute__((__deprecated__)) +/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */ +#endif /* clang < 2.9 || GCC >= 3.1 */ +#endif /* !_MHD_DEPR_FUNC */ + +#ifndef _MHD_DEPR_FUNC +#define _MHD_NO_DEPR_FUNC 1 +#define _MHD_DEPR_FUNC(msg) +#endif /* !_MHD_DEPR_FUNC */ + +/** + * Not all architectures and `printf()`'s support the `long long` type. + * This gives the ability to replace `long long` with just a `long`, + * standard `int` or a `short`. + */ +#ifndef MHD_LONG_LONG +/** + * @deprecated use #MHD_UNSIGNED_LONG_LONG instead! + */ +#define MHD_LONG_LONG long long +#define MHD_UNSIGNED_LONG_LONG unsigned long long +#else /* MHD_LONG_LONG */ +_MHD_DEPR_MACRO ( \ + "Macro MHD_LONG_LONG is deprecated, use MHD_UNSIGNED_LONG_LONG") +#endif +/** + * Format string for printing a variable of type #MHD_LONG_LONG. + * You should only redefine this if you also define #MHD_LONG_LONG. + */ +#ifndef MHD_LONG_LONG_PRINTF +/** + * @deprecated use #MHD_UNSIGNED_LONG_LONG_PRINTF instead! + */ +#define MHD_LONG_LONG_PRINTF "ll" +#define MHD_UNSIGNED_LONG_LONG_PRINTF "%llu" +#else /* MHD_LONG_LONG_PRINTF */ +_MHD_DEPR_MACRO ( \ + "Macro MHD_LONG_LONG_PRINTF is deprecated, use MHD_UNSIGNED_LONG_LONG_PRINTF") +#endif + + +/** + * @defgroup httpcode HTTP response codes. + * These are the status codes defined for HTTP responses. + * See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml + * Registry export date: 2023-09-29 + * @{ + */ + +/* 100 "Continue". RFC9110, Section 15.2.1. */ +#define MHD_HTTP_CONTINUE 100 +/* 101 "Switching Protocols". RFC9110, Section 15.2.2. */ +#define MHD_HTTP_SWITCHING_PROTOCOLS 101 +/* 102 "Processing". RFC2518. */ +#define MHD_HTTP_PROCESSING 102 +/* 103 "Early Hints". RFC8297. */ +#define MHD_HTTP_EARLY_HINTS 103 + +/* 200 "OK". RFC9110, Section 15.3.1. */ +#define MHD_HTTP_OK 200 +/* 201 "Created". RFC9110, Section 15.3.2. */ +#define MHD_HTTP_CREATED 201 +/* 202 "Accepted". RFC9110, Section 15.3.3. */ +#define MHD_HTTP_ACCEPTED 202 +/* 203 "Non-Authoritative Information". RFC9110, Section 15.3.4. */ +#define MHD_HTTP_NON_AUTHORITATIVE_INFORMATION 203 +/* 204 "No Content". RFC9110, Section 15.3.5. */ +#define MHD_HTTP_NO_CONTENT 204 +/* 205 "Reset Content". RFC9110, Section 15.3.6. */ +#define MHD_HTTP_RESET_CONTENT 205 +/* 206 "Partial Content". RFC9110, Section 15.3.7. */ +#define MHD_HTTP_PARTIAL_CONTENT 206 +/* 207 "Multi-Status". RFC4918. */ +#define MHD_HTTP_MULTI_STATUS 207 +/* 208 "Already Reported". RFC5842. */ +#define MHD_HTTP_ALREADY_REPORTED 208 + +/* 226 "IM Used". RFC3229. */ +#define MHD_HTTP_IM_USED 226 + +/* 300 "Multiple Choices". RFC9110, Section 15.4.1. */ +#define MHD_HTTP_MULTIPLE_CHOICES 300 +/* 301 "Moved Permanently". RFC9110, Section 15.4.2. */ +#define MHD_HTTP_MOVED_PERMANENTLY 301 +/* 302 "Found". RFC9110, Section 15.4.3. */ +#define MHD_HTTP_FOUND 302 +/* 303 "See Other". RFC9110, Section 15.4.4. */ +#define MHD_HTTP_SEE_OTHER 303 +/* 304 "Not Modified". RFC9110, Section 15.4.5. */ +#define MHD_HTTP_NOT_MODIFIED 304 +/* 305 "Use Proxy". RFC9110, Section 15.4.6. */ +#define MHD_HTTP_USE_PROXY 305 +/* 306 "Switch Proxy". Not used! RFC9110, Section 15.4.7. */ +#define MHD_HTTP_SWITCH_PROXY 306 +/* 307 "Temporary Redirect". RFC9110, Section 15.4.8. */ +#define MHD_HTTP_TEMPORARY_REDIRECT 307 +/* 308 "Permanent Redirect". RFC9110, Section 15.4.9. */ +#define MHD_HTTP_PERMANENT_REDIRECT 308 + +/* 400 "Bad Request". RFC9110, Section 15.5.1. */ +#define MHD_HTTP_BAD_REQUEST 400 +/* 401 "Unauthorized". RFC9110, Section 15.5.2. */ +#define MHD_HTTP_UNAUTHORIZED 401 +/* 402 "Payment Required". RFC9110, Section 15.5.3. */ +#define MHD_HTTP_PAYMENT_REQUIRED 402 +/* 403 "Forbidden". RFC9110, Section 15.5.4. */ +#define MHD_HTTP_FORBIDDEN 403 +/* 404 "Not Found". RFC9110, Section 15.5.5. */ +#define MHD_HTTP_NOT_FOUND 404 +/* 405 "Method Not Allowed". RFC9110, Section 15.5.6. */ +#define MHD_HTTP_METHOD_NOT_ALLOWED 405 +/* 406 "Not Acceptable". RFC9110, Section 15.5.7. */ +#define MHD_HTTP_NOT_ACCEPTABLE 406 +/* 407 "Proxy Authentication Required". RFC9110, Section 15.5.8. */ +#define MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED 407 +/* 408 "Request Timeout". RFC9110, Section 15.5.9. */ +#define MHD_HTTP_REQUEST_TIMEOUT 408 +/* 409 "Conflict". RFC9110, Section 15.5.10. */ +#define MHD_HTTP_CONFLICT 409 +/* 410 "Gone". RFC9110, Section 15.5.11. */ +#define MHD_HTTP_GONE 410 +/* 411 "Length Required". RFC9110, Section 15.5.12. */ +#define MHD_HTTP_LENGTH_REQUIRED 411 +/* 412 "Precondition Failed". RFC9110, Section 15.5.13. */ +#define MHD_HTTP_PRECONDITION_FAILED 412 +/* 413 "Content Too Large". RFC9110, Section 15.5.14. */ +#define MHD_HTTP_CONTENT_TOO_LARGE 413 +/* 414 "URI Too Long". RFC9110, Section 15.5.15. */ +#define MHD_HTTP_URI_TOO_LONG 414 +/* 415 "Unsupported Media Type". RFC9110, Section 15.5.16. */ +#define MHD_HTTP_UNSUPPORTED_MEDIA_TYPE 415 +/* 416 "Range Not Satisfiable". RFC9110, Section 15.5.17. */ +#define MHD_HTTP_RANGE_NOT_SATISFIABLE 416 +/* 417 "Expectation Failed". RFC9110, Section 15.5.18. */ +#define MHD_HTTP_EXPECTATION_FAILED 417 + + +/* 421 "Misdirected Request". RFC9110, Section 15.5.20. */ +#define MHD_HTTP_MISDIRECTED_REQUEST 421 +/* 422 "Unprocessable Content". RFC9110, Section 15.5.21. */ +#define MHD_HTTP_UNPROCESSABLE_CONTENT 422 +/* 423 "Locked". RFC4918. */ +#define MHD_HTTP_LOCKED 423 +/* 424 "Failed Dependency". RFC4918. */ +#define MHD_HTTP_FAILED_DEPENDENCY 424 +/* 425 "Too Early". RFC8470. */ +#define MHD_HTTP_TOO_EARLY 425 +/* 426 "Upgrade Required". RFC9110, Section 15.5.22. */ +#define MHD_HTTP_UPGRADE_REQUIRED 426 + +/* 428 "Precondition Required". RFC6585. */ +#define MHD_HTTP_PRECONDITION_REQUIRED 428 +/* 429 "Too Many Requests". RFC6585. */ +#define MHD_HTTP_TOO_MANY_REQUESTS 429 + +/* 431 "Request Header Fields Too Large". RFC6585. */ +#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE 431 + +/* 451 "Unavailable For Legal Reasons". RFC7725. */ +#define MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS 451 + +/* 500 "Internal Server Error". RFC9110, Section 15.6.1. */ +#define MHD_HTTP_INTERNAL_SERVER_ERROR 500 +/* 501 "Not Implemented". RFC9110, Section 15.6.2. */ +#define MHD_HTTP_NOT_IMPLEMENTED 501 +/* 502 "Bad Gateway". RFC9110, Section 15.6.3. */ +#define MHD_HTTP_BAD_GATEWAY 502 +/* 503 "Service Unavailable". RFC9110, Section 15.6.4. */ +#define MHD_HTTP_SERVICE_UNAVAILABLE 503 +/* 504 "Gateway Timeout". RFC9110, Section 15.6.5. */ +#define MHD_HTTP_GATEWAY_TIMEOUT 504 +/* 505 "HTTP Version Not Supported". RFC9110, Section 15.6.6. */ +#define MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED 505 +/* 506 "Variant Also Negotiates". RFC2295. */ +#define MHD_HTTP_VARIANT_ALSO_NEGOTIATES 506 +/* 507 "Insufficient Storage". RFC4918. */ +#define MHD_HTTP_INSUFFICIENT_STORAGE 507 +/* 508 "Loop Detected". RFC5842. */ +#define MHD_HTTP_LOOP_DETECTED 508 + +/* 510 "Not Extended". (OBSOLETED) RFC2774; status-change-http-experiments-to-historic. */ +#define MHD_HTTP_NOT_EXTENDED 510 +/* 511 "Network Authentication Required". RFC6585. */ +#define MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED 511 + + +/* Not registered non-standard codes */ +/* 449 "Reply With". MS IIS extension. */ +#define MHD_HTTP_RETRY_WITH 449 + +/* 450 "Blocked by Windows Parental Controls". MS extension. */ +#define MHD_HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS 450 + +/* 509 "Bandwidth Limit Exceeded". Apache extension. */ +#define MHD_HTTP_BANDWIDTH_LIMIT_EXCEEDED 509 + +/* Deprecated names and codes */ +/** @deprecated */ +#define MHD_HTTP_METHOD_NOT_ACCEPTABLE _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_NOT_ACCEPTABLE" \ + ) 406 + +/** @deprecated */ +#define MHD_HTTP_REQUEST_ENTITY_TOO_LARGE _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_REQUEST_ENTITY_TOO_LARGE is deprecated, use MHD_HTTP_CONTENT_TOO_LARGE"\ + ) 413 + +/** @deprecated */ +#define MHD_HTTP_PAYLOAD_TOO_LARGE _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_PAYLOAD_TOO_LARGE is deprecated use MHD_HTTP_CONTENT_TOO_LARGE" \ + ) 413 + +/** @deprecated */ +#define MHD_HTTP_REQUEST_URI_TOO_LONG _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_REQUEST_URI_TOO_LONG is deprecated, use MHD_HTTP_URI_TOO_LONG" \ + ) 414 + +/** @deprecated */ +#define MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE is deprecated, use MHD_HTTP_RANGE_NOT_SATISFIABLE" \ + ) 416 + +/** @deprecated */ +#define MHD_HTTP_UNPROCESSABLE_ENTITY _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_UNPROCESSABLE_ENTITY is deprecated, use MHD_HTTP_UNPROCESSABLE_CONTENT" \ + ) 422 + +/** @deprecated */ +#define MHD_HTTP_UNORDERED_COLLECTION _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_UNORDERED_COLLECTION is deprecated as it was removed from RFC" \ + ) 425 + +/** @deprecated */ +#define MHD_HTTP_NO_RESPONSE _MHD_DEPR_IN_MACRO (\ + "Value MHD_HTTP_NO_RESPONSE is deprecated as it is nginx internal code for logs only"\ + ) 444 + + +/** @} */ /* end of group httpcode */ + +/** + * Returns the string reason phrase for a response code. + * + * If message string is not available for a status code, + * "Unknown" string will be returned. + */ +_MHD_EXTERN const char * +MHD_get_reason_phrase_for (unsigned int code); + + +/** + * Returns the length of the string reason phrase for a response code. + * + * If message string is not available for a status code, + * 0 is returned. + */ +_MHD_EXTERN size_t +MHD_get_reason_phrase_len_for (unsigned int code); + +/** + * Flag to be or-ed with MHD_HTTP status code for + * SHOUTcast. This will cause the response to begin + * with the SHOUTcast "ICY" line instead of "HTTP/1.x". + * @ingroup specialized + */ +#define MHD_ICY_FLAG ((uint32_t) (((uint32_t) 1) << 31)) + +/** + * @defgroup headers HTTP headers + * The standard headers found in HTTP requests and responses. + * See: https://www.iana.org/assignments/http-fields/http-fields.xhtml + * Registry export date: 2023-10-02 + * @{ + */ + +/* Main HTTP headers. */ +/* Permanent. RFC9110, Section 12.5.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_ACCEPT "Accept" +/* Deprecated. RFC9110, Section 12.5.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset" +/* Permanent. RFC9110, Section 12.5.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding" +/* Permanent. RFC9110, Section 12.5.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language" +/* Permanent. RFC9110, Section 14.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges" +/* Permanent. RFC9111, Section 5.1: HTTP Caching */ +#define MHD_HTTP_HEADER_AGE "Age" +/* Permanent. RFC9110, Section 10.2.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_ALLOW "Allow" +/* Permanent. RFC9110, Section 11.6.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info" +/* Permanent. RFC9110, Section 11.6.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_AUTHORIZATION "Authorization" +/* Permanent. RFC9111, Section 5.2 */ +#define MHD_HTTP_HEADER_CACHE_CONTROL "Cache-Control" +/* Permanent. RFC9112, Section 9.6: HTTP/1.1 */ +#define MHD_HTTP_HEADER_CLOSE "Close" +/* Permanent. RFC9110, Section 7.6.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONNECTION "Connection" +/* Permanent. RFC9110, Section 8.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding" +/* Permanent. RFC9110, Section 8.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONTENT_LANGUAGE "Content-Language" +/* Permanent. RFC9110, Section 8.6: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONTENT_LENGTH "Content-Length" +/* Permanent. RFC9110, Section 8.7: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONTENT_LOCATION "Content-Location" +/* Permanent. RFC9110, Section 14.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONTENT_RANGE "Content-Range" +/* Permanent. RFC9110, Section 8.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONTENT_TYPE "Content-Type" +/* Permanent. RFC9110, Section 6.6.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_DATE "Date" +/* Permanent. RFC9110, Section 8.8.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_ETAG "ETag" +/* Permanent. RFC9110, Section 10.1.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_EXPECT "Expect" +/* Permanent. RFC9111, Section 5.3: HTTP Caching */ +#define MHD_HTTP_HEADER_EXPIRES "Expires" +/* Permanent. RFC9110, Section 10.1.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_FROM "From" +/* Permanent. RFC9110, Section 7.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_HOST "Host" +/* Permanent. RFC9110, Section 13.1.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_IF_MATCH "If-Match" +/* Permanent. RFC9110, Section 13.1.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since" +/* Permanent. RFC9110, Section 13.1.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_IF_NONE_MATCH "If-None-Match" +/* Permanent. RFC9110, Section 13.1.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_IF_RANGE "If-Range" +/* Permanent. RFC9110, Section 13.1.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since" +/* Permanent. RFC9110, Section 8.8.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_LAST_MODIFIED "Last-Modified" +/* Permanent. RFC9110, Section 10.2.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_LOCATION "Location" +/* Permanent. RFC9110, Section 7.6.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_MAX_FORWARDS "Max-Forwards" +/* Permanent. RFC9112, Appendix B.1: HTTP/1.1 */ +#define MHD_HTTP_HEADER_MIME_VERSION "MIME-Version" +/* Deprecated. RFC9111, Section 5.4: HTTP Caching */ +#define MHD_HTTP_HEADER_PRAGMA "Pragma" +/* Permanent. RFC9110, Section 11.7.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate" +/* Permanent. RFC9110, Section 11.7.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info" +/* Permanent. RFC9110, Section 11.7.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization" +/* Permanent. RFC9110, Section 14.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_RANGE "Range" +/* Permanent. RFC9110, Section 10.1.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_REFERER "Referer" +/* Permanent. RFC9110, Section 10.2.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_RETRY_AFTER "Retry-After" +/* Permanent. RFC9110, Section 10.2.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_SERVER "Server" +/* Permanent. RFC9110, Section 10.1.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_TE "TE" +/* Permanent. RFC9110, Section 6.6.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_TRAILER "Trailer" +/* Permanent. RFC9112, Section 6.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding" +/* Permanent. RFC9110, Section 7.8: HTTP Semantics */ +#define MHD_HTTP_HEADER_UPGRADE "Upgrade" +/* Permanent. RFC9110, Section 10.1.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_USER_AGENT "User-Agent" +/* Permanent. RFC9110, Section 12.5.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_VARY "Vary" +/* Permanent. RFC9110, Section 7.6.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_VIA "Via" +/* Permanent. RFC9110, Section 11.6.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate" +/* Permanent. RFC9110, Section 12.5.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_ASTERISK "*" + +/* Additional HTTP headers. */ +/* Permanent. RFC 3229: Delta encoding in HTTP */ +#define MHD_HTTP_HEADER_A_IM "A-IM" +/* Permanent. RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) */ +#define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions" +/* Permanent. RFC 8942, Section 3.1: HTTP Client Hints */ +#define MHD_HTTP_HEADER_ACCEPT_CH "Accept-CH" +/* Permanent. RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */ +#define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features" +/* Permanent. RFC 5789: PATCH Method for HTTP */ +#define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch" +/* Permanent. Linked Data Platform 1.0 */ +#define MHD_HTTP_HEADER_ACCEPT_POST "Accept-Post" +/* Permanent. RFC-ietf-httpbis-message-signatures-19, Section 5.1: HTTP Message Signatures */ +#define MHD_HTTP_HEADER_ACCEPT_SIGNATURE "Accept-Signature" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS \ + "Access-Control-Allow-Credentials" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS \ + "Access-Control-Allow-Headers" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_METHODS \ + "Access-Control-Allow-Methods" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \ + "Access-Control-Allow-Origin" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS \ + "Access-Control-Expose-Headers" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_MAX_AGE "Access-Control-Max-Age" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_HEADERS \ + "Access-Control-Request-Headers" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_METHOD \ + "Access-Control-Request-Method" +/* Permanent. RFC 7639, Section 2: The ALPN HTTP Header Field */ +#define MHD_HTTP_HEADER_ALPN "ALPN" +/* Permanent. RFC 7838: HTTP Alternative Services */ +#define MHD_HTTP_HEADER_ALT_SVC "Alt-Svc" +/* Permanent. RFC 7838: HTTP Alternative Services */ +#define MHD_HTTP_HEADER_ALT_USED "Alt-Used" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_ALTERNATES "Alternates" +/* Permanent. RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */ +#define MHD_HTTP_HEADER_APPLY_TO_REDIRECT_REF "Apply-To-Redirect-Ref" +/* Permanent. RFC 8053, Section 4: HTTP Authentication Extensions for Interactive Clients */ +#define MHD_HTTP_HEADER_AUTHENTICATION_CONTROL "Authentication-Control" +/* Permanent. RFC9211: The Cache-Status HTTP Response Header Field */ +#define MHD_HTTP_HEADER_CACHE_STATUS "Cache-Status" +/* Permanent. RFC 8607, Section 5.1: Calendaring Extensions to WebDAV (CalDAV): Managed Attachments */ +#define MHD_HTTP_HEADER_CAL_MANAGED_ID "Cal-Managed-ID" +/* Permanent. RFC 7809, Section 7.1: Calendaring Extensions to WebDAV (CalDAV): Time Zones by Reference */ +#define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones" +/* Permanent. RFC9297 */ +#define MHD_HTTP_HEADER_CAPSULE_PROTOCOL "Capsule-Protocol" +/* Permanent. RFC9213: Targeted HTTP Cache Control */ +#define MHD_HTTP_HEADER_CDN_CACHE_CONTROL "CDN-Cache-Control" +/* Permanent. RFC 8586: Loop Detection in Content Delivery Networks (CDNs) */ +#define MHD_HTTP_HEADER_CDN_LOOP "CDN-Loop" +/* Permanent. RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */ +#define MHD_HTTP_HEADER_CERT_NOT_AFTER "Cert-Not-After" +/* Permanent. RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */ +#define MHD_HTTP_HEADER_CERT_NOT_BEFORE "Cert-Not-Before" +/* Permanent. Clear Site Data */ +#define MHD_HTTP_HEADER_CLEAR_SITE_DATA "Clear-Site-Data" +/* Permanent. RFC9440, Section 2: Client-Cert HTTP Header Field */ +#define MHD_HTTP_HEADER_CLIENT_CERT "Client-Cert" +/* Permanent. RFC9440, Section 2: Client-Cert HTTP Header Field */ +#define MHD_HTTP_HEADER_CLIENT_CERT_CHAIN "Client-Cert-Chain" +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 2: Digest Fields */ +#define MHD_HTTP_HEADER_CONTENT_DIGEST "Content-Digest" +/* Permanent. RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP) */ +#define MHD_HTTP_HEADER_CONTENT_DISPOSITION "Content-Disposition" +/* Permanent. The HTTP Distribution and Replication Protocol */ +#define MHD_HTTP_HEADER_CONTENT_ID "Content-ID" +/* Permanent. Content Security Policy Level 3 */ +#define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY "Content-Security-Policy" +/* Permanent. Content Security Policy Level 3 */ +#define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY_REPORT_ONLY \ + "Content-Security-Policy-Report-Only" +/* Permanent. RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_COOKIE "Cookie" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY \ + "Cross-Origin-Embedder-Policy" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY_REPORT_ONLY \ + "Cross-Origin-Embedder-Policy-Report-Only" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY "Cross-Origin-Opener-Policy" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY_REPORT_ONLY \ + "Cross-Origin-Opener-Policy-Report-Only" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_RESOURCE_POLICY \ + "Cross-Origin-Resource-Policy" +/* Permanent. RFC 5323: Web Distributed Authoring and Versioning (WebDAV) SEARCH */ +#define MHD_HTTP_HEADER_DASL "DASL" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_DAV "DAV" +/* Permanent. RFC 3229: Delta encoding in HTTP */ +#define MHD_HTTP_HEADER_DELTA_BASE "Delta-Base" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_DEPTH "Depth" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_DESTINATION "Destination" +/* Permanent. The HTTP Distribution and Replication Protocol */ +#define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID" +/* Permanent. RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */ +#define MHD_HTTP_HEADER_DPOP "DPoP" +/* Permanent. RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */ +#define MHD_HTTP_HEADER_DPOP_NONCE "DPoP-Nonce" +/* Permanent. RFC 8470: Using Early Data in HTTP */ +#define MHD_HTTP_HEADER_EARLY_DATA "Early-Data" +/* Permanent. RFC9163: Expect-CT Extension for HTTP */ +#define MHD_HTTP_HEADER_EXPECT_CT "Expect-CT" +/* Permanent. RFC 7239: Forwarded HTTP Extension */ +#define MHD_HTTP_HEADER_FORWARDED "Forwarded" +/* Permanent. RFC 7486, Section 6.1.1: HTTP Origin-Bound Authentication (HOBA) */ +#define MHD_HTTP_HEADER_HOBAREG "Hobareg" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_IF "If" +/* Permanent. RFC 6338: Scheduling Extensions to CalDAV */ +#define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match" +/* Permanent. RFC 3229: Delta encoding in HTTP */ +#define MHD_HTTP_HEADER_IM "IM" +/* Permanent. RFC 8473: Token Binding over HTTP */ +#define MHD_HTTP_HEADER_INCLUDE_REFERRED_TOKEN_BINDING_ID \ + "Include-Referred-Token-Binding-ID" +/* Permanent. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_KEEP_ALIVE "Keep-Alive" +/* Permanent. RFC 3253: Versioning Extensions to WebDAV: (Web Distributed Authoring and Versioning) */ +#define MHD_HTTP_HEADER_LABEL "Label" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_LAST_EVENT_ID "Last-Event-ID" +/* Permanent. RFC 8288: Web Linking */ +#define MHD_HTTP_HEADER_LINK "Link" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_LOCK_TOKEN "Lock-Token" +/* Permanent. RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */ +#define MHD_HTTP_HEADER_MEMENTO_DATETIME "Memento-Datetime" +/* Permanent. RFC 2227: Simple Hit-Metering and Usage-Limiting for HTTP */ +#define MHD_HTTP_HEADER_METER "Meter" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_NEGOTIATE "Negotiate" +/* Permanent. Network Error Logging */ +#define MHD_HTTP_HEADER_NEL "NEL" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_ENTITYID "OData-EntityId" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_ISOLATION "OData-Isolation" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_MAXVERSION "OData-MaxVersion" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_VERSION "OData-Version" +/* Permanent. RFC 8053, Section 3: HTTP Authentication Extensions for Interactive Clients */ +#define MHD_HTTP_HEADER_OPTIONAL_WWW_AUTHENTICATE "Optional-WWW-Authenticate" +/* Permanent. RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */ +#define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type" +/* Permanent. RFC 6454: The Web Origin Concept */ +#define MHD_HTTP_HEADER_ORIGIN "Origin" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_ORIGIN_AGENT_CLUSTER "Origin-Agent-Cluster" +/* Permanent. RFC 8613, Section 11.1: Object Security for Constrained RESTful Environments (OSCORE) */ +#define MHD_HTTP_HEADER_OSCORE "OSCORE" +/* Permanent. OASIS Project Specification 01; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_OSLC_CORE_VERSION "OSLC-Core-Version" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_OVERWRITE "Overwrite" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_PING_FROM "Ping-From" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_PING_TO "Ping-To" +/* Permanent. RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */ +#define MHD_HTTP_HEADER_POSITION "Position" +/* Permanent. RFC 7240: Prefer Header for HTTP */ +#define MHD_HTTP_HEADER_PREFER "Prefer" +/* Permanent. RFC 7240: Prefer Header for HTTP */ +#define MHD_HTTP_HEADER_PREFERENCE_APPLIED "Preference-Applied" +/* Permanent. RFC9218: Extensible Prioritization Scheme for HTTP */ +#define MHD_HTTP_HEADER_PRIORITY "Priority" +/* Permanent. RFC9209: The Proxy-Status HTTP Response Header Field */ +#define MHD_HTTP_HEADER_PROXY_STATUS "Proxy-Status" +/* Permanent. RFC 7469: Public Key Pinning Extension for HTTP */ +#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins" +/* Permanent. RFC 7469: Public Key Pinning Extension for HTTP */ +#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY \ + "Public-Key-Pins-Report-Only" +/* Permanent. RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */ +#define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_REFRESH "Refresh" +/* Permanent. RFC 8555, Section 6.5.1: Automatic Certificate Management Environment (ACME) */ +#define MHD_HTTP_HEADER_REPLAY_NONCE "Replay-Nonce" +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 3: Digest Fields */ +#define MHD_HTTP_HEADER_REPR_DIGEST "Repr-Digest" +/* Permanent. RFC 6638: Scheduling Extensions to CalDAV */ +#define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply" +/* Permanent. RFC 6338: Scheduling Extensions to CalDAV */ +#define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_SEC_PURPOSE "Sec-Purpose" +/* Permanent. RFC 8473: Token Binding over HTTP */ +#define MHD_HTTP_HEADER_SEC_TOKEN_BINDING "Sec-Token-Binding" +/* Permanent. RFC 6455: The WebSocket Protocol */ +#define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept" +/* Permanent. RFC 6455: The WebSocket Protocol */ +#define MHD_HTTP_HEADER_SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions" +/* Permanent. RFC 6455: The WebSocket Protocol */ +#define MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY "Sec-WebSocket-Key" +/* Permanent. RFC 6455: The WebSocket Protocol */ +#define MHD_HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol" +/* Permanent. RFC 6455: The WebSocket Protocol */ +#define MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version" +/* Permanent. Server Timing */ +#define MHD_HTTP_HEADER_SERVER_TIMING "Server-Timing" +/* Permanent. RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_SET_COOKIE "Set-Cookie" +/* Permanent. RFC-ietf-httpbis-message-signatures-19, Section 4.2: HTTP Message Signatures */ +#define MHD_HTTP_HEADER_SIGNATURE "Signature" +/* Permanent. RFC-ietf-httpbis-message-signatures-19, Section 4.1: HTTP Message Signatures */ +#define MHD_HTTP_HEADER_SIGNATURE_INPUT "Signature-Input" +/* Permanent. RFC 5023: The Atom Publishing Protocol */ +#define MHD_HTTP_HEADER_SLUG "SLUG" +/* Permanent. Simple Object Access Protocol (SOAP) 1.1 */ +#define MHD_HTTP_HEADER_SOAPACTION "SoapAction" +/* Permanent. RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV */ +#define MHD_HTTP_HEADER_STATUS_URI "Status-URI" +/* Permanent. RFC 6797: HTTP Strict Transport Security (HSTS) */ +#define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security" +/* Permanent. RFC 8594: The Sunset HTTP Header Field */ +#define MHD_HTTP_HEADER_SUNSET "Sunset" +/* Permanent. Edge Architecture Specification */ +#define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability" +/* Permanent. Edge Architecture Specification */ +#define MHD_HTTP_HEADER_SURROGATE_CONTROL "Surrogate-Control" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_TCN "TCN" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_TIMEOUT "Timeout" +/* Permanent. RFC 8030, Section 5.4: Generic Event Delivery Using HTTP Push */ +#define MHD_HTTP_HEADER_TOPIC "Topic" +/* Permanent. Trace Context */ +#define MHD_HTTP_HEADER_TRACEPARENT "Traceparent" +/* Permanent. Trace Context */ +#define MHD_HTTP_HEADER_TRACESTATE "Tracestate" +/* Permanent. RFC 8030, Section 5.2: Generic Event Delivery Using HTTP Push */ +#define MHD_HTTP_HEADER_TTL "TTL" +/* Permanent. RFC 8030, Section 5.3: Generic Event Delivery Using HTTP Push */ +#define MHD_HTTP_HEADER_URGENCY "Urgency" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary" +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */ +#define MHD_HTTP_HEADER_WANT_CONTENT_DIGEST "Want-Content-Digest" +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */ +#define MHD_HTTP_HEADER_WANT_REPR_DIGEST "Want-Repr-Digest" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_X_CONTENT_TYPE_OPTIONS "X-Content-Type-Options" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options" +/* Provisional. AMP-Cache-Transform HTTP request header */ +#define MHD_HTTP_HEADER_AMP_CACHE_TRANSFORM "AMP-Cache-Transform" +/* Provisional. OSLC Configuration Management Version 1.0. Part 3: Configuration Specification */ +#define MHD_HTTP_HEADER_CONFIGURATION_CONTEXT "Configuration-Context" +/* Provisional. RFC 6017: Electronic Data Interchange - Internet Integration (EDIINT) Features Header Field */ +#define MHD_HTTP_HEADER_EDIINT_FEATURES "EDIINT-Features" +/* Provisional. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ISOLATION "Isolation" +/* Provisional. Permissions Policy */ +#define MHD_HTTP_HEADER_PERMISSIONS_POLICY "Permissions-Policy" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_CLIENT_ID "Repeatability-Client-ID" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_FIRST_SENT "Repeatability-First-Sent" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_REQUEST_ID "Repeatability-Request-ID" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_RESULT "Repeatability-Result" +/* Provisional. Reporting API */ +#define MHD_HTTP_HEADER_REPORTING_ENDPOINTS "Reporting-Endpoints" +/* Provisional. Global Privacy Control (GPC) */ +#define MHD_HTTP_HEADER_SEC_GPC "Sec-GPC" +/* Provisional. Resource Timing Level 1 */ +#define MHD_HTTP_HEADER_TIMING_ALLOW_ORIGIN "Timing-Allow-Origin" +/* Deprecated. PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_PEP_INFO "C-PEP-Info" +/* Deprecated. White Paper: Joint Electronic Payment Initiative */ +#define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info" +/* Deprecated. White Paper: Joint Electronic Payment Initiative */ +#define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL "Access-Control" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_EXT "C-Ext" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_MAN "C-Man" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_OPT "C-Opt" +/* Obsoleted. PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_PEP "C-PEP" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1; RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base" +/* Obsoleted. RFC 2616, Section 14.15: Hypertext Transfer Protocol -- HTTP/1.1; RFC 7231, Appendix B: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content */ +#define MHD_HTTP_HEADER_CONTENT_MD5 "Content-MD5" +/* Obsoleted. HTML 4.01 Specification */ +#define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type" +/* Obsoleted. HTML 4.01 Specification */ +#define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version" +/* Obsoleted. RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_COOKIE2 "Cookie2" +/* Obsoleted. HTML 4.01 Specification */ +#define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From" +/* Obsoleted. RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */ +#define MHD_HTTP_HEADER_DIGEST "Digest" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_EXT "Ext" +/* Obsoleted. Implementation of OPS Over HTTP */ +#define MHD_HTTP_HEADER_GETPROFILE "GetProfile" +/* Obsoleted. RFC 7540, Section 3.2.1: Hypertext Transfer Protocol Version 2 (HTTP/2) */ +#define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_MAN "Man" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_METHOD_CHECK "Method-Check" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_METHOD_CHECK_EXPIRES "Method-Check-Expires" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_OPT "Opt" +/* Obsoleted. The Platform for Privacy Preferences 1.0 (P3P1.0) Specification */ +#define MHD_HTTP_HEADER_P3P "P3P" +/* Obsoleted. PEP - an Extension Mechanism for HTTP */ +#define MHD_HTTP_HEADER_PEP "PEP" +/* Obsoleted. PEP - an Extension Mechanism for HTTP */ +#define MHD_HTTP_HEADER_PEP_INFO "Pep-Info" +/* Obsoleted. PICS Label Distribution Label Syntax and Communication Protocols */ +#define MHD_HTTP_HEADER_PICS_LABEL "PICS-Label" +/* Obsoleted. Implementation of OPS Over HTTP */ +#define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject" +/* Obsoleted. PICS Label Distribution Label Syntax and Communication Protocols */ +#define MHD_HTTP_HEADER_PROTOCOL "Protocol" +/* Obsoleted. PICS Label Distribution Label Syntax and Communication Protocols */ +#define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request" +/* Obsoleted. Notification for Proxy Caches */ +#define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features" +/* Obsoleted. Notification for Proxy Caches */ +#define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_PUBLIC "Public" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_REFERER_ROOT "Referer-Root" +/* Obsoleted. RFC 2310: The Safe Response Header Field; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_SAFE "Safe" +/* Obsoleted. RFC 2660: The Secure HyperText Transfer Protocol; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme" +/* Obsoleted. RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_SET_COOKIE2 "Set-Cookie2" +/* Obsoleted. Implementation of OPS Over HTTP */ +#define MHD_HTTP_HEADER_SETPROFILE "SetProfile" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_URI "URI" +/* Obsoleted. RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */ +#define MHD_HTTP_HEADER_WANT_DIGEST "Want-Digest" +/* Obsoleted. RFC9111, Section 5.5: HTTP Caching */ +#define MHD_HTTP_HEADER_WARNING "Warning" + +/* Headers removed from the registry. Do not use! */ +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_COMPLIANCE "Compliance" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_COST "Cost" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_MESSAGE_ID "Message-ID" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_NON_COMPLIANCE "Non-Compliance" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_OPTIONAL "Optional" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_RESOLUTION_HINT "Resolution-Hint" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_RESOLVER_LOCATION "Resolver-Location" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_SUBOK "SubOK" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_SUBST "Subst" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_TITLE "Title" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_COLOR "UA-Color" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_MEDIA "UA-Media" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_PIXELS "UA-Pixels" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_RESOLUTION "UA-Resolution" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_WINDOWPIXELS "UA-Windowpixels" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_VERSION "Version" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT "X-Device-Accept" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_CHARSET "X-Device-Accept-Charset" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_ENCODING "X-Device-Accept-Encoding" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_LANGUAGE "X-Device-Accept-Language" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_USER_AGENT "X-Device-User-Agent" + +/** @} */ /* end of group headers */ + +/** + * @defgroup versions HTTP versions + * These strings should be used to match against the first line of the + * HTTP header. + * @{ + */ +#define MHD_HTTP_VERSION_1_0 "HTTP/1.0" +#define MHD_HTTP_VERSION_1_1 "HTTP/1.1" + +/** @} */ /* end of group versions */ + +/** + * @defgroup methods HTTP methods + * HTTP methods (as strings). + * See: https://www.iana.org/assignments/http-methods/http-methods.xml + * Registry export date: 2023-10-02 + * @{ + */ + +/* Main HTTP methods. */ +/* Safe. Idempotent. RFC9110, Section 9.3.1. */ +#define MHD_HTTP_METHOD_GET "GET" +/* Safe. Idempotent. RFC9110, Section 9.3.2. */ +#define MHD_HTTP_METHOD_HEAD "HEAD" +/* Not safe. Not idempotent. RFC9110, Section 9.3.3. */ +#define MHD_HTTP_METHOD_POST "POST" +/* Not safe. Idempotent. RFC9110, Section 9.3.4. */ +#define MHD_HTTP_METHOD_PUT "PUT" +/* Not safe. Idempotent. RFC9110, Section 9.3.5. */ +#define MHD_HTTP_METHOD_DELETE "DELETE" +/* Not safe. Not idempotent. RFC9110, Section 9.3.6. */ +#define MHD_HTTP_METHOD_CONNECT "CONNECT" +/* Safe. Idempotent. RFC9110, Section 9.3.7. */ +#define MHD_HTTP_METHOD_OPTIONS "OPTIONS" +/* Safe. Idempotent. RFC9110, Section 9.3.8. */ +#define MHD_HTTP_METHOD_TRACE "TRACE" + +/* Additional HTTP methods. */ +/* Not safe. Idempotent. RFC3744, Section 8.1. */ +#define MHD_HTTP_METHOD_ACL "ACL" +/* Not safe. Idempotent. RFC3253, Section 12.6. */ +#define MHD_HTTP_METHOD_BASELINE_CONTROL "BASELINE-CONTROL" +/* Not safe. Idempotent. RFC5842, Section 4. */ +#define MHD_HTTP_METHOD_BIND "BIND" +/* Not safe. Idempotent. RFC3253, Section 4.4, Section 9.4. */ +#define MHD_HTTP_METHOD_CHECKIN "CHECKIN" +/* Not safe. Idempotent. RFC3253, Section 4.3, Section 8.8. */ +#define MHD_HTTP_METHOD_CHECKOUT "CHECKOUT" +/* Not safe. Idempotent. RFC4918, Section 9.8. */ +#define MHD_HTTP_METHOD_COPY "COPY" +/* Not safe. Idempotent. RFC3253, Section 8.2. */ +#define MHD_HTTP_METHOD_LABEL "LABEL" +/* Not safe. Idempotent. RFC2068, Section 19.6.1.2. */ +#define MHD_HTTP_METHOD_LINK "LINK" +/* Not safe. Not idempotent. RFC4918, Section 9.10. */ +#define MHD_HTTP_METHOD_LOCK "LOCK" +/* Not safe. Idempotent. RFC3253, Section 11.2. */ +#define MHD_HTTP_METHOD_MERGE "MERGE" +/* Not safe. Idempotent. RFC3253, Section 13.5. */ +#define MHD_HTTP_METHOD_MKACTIVITY "MKACTIVITY" +/* Not safe. Idempotent. RFC4791, Section 5.3.1; RFC8144, Section 2.3. */ +#define MHD_HTTP_METHOD_MKCALENDAR "MKCALENDAR" +/* Not safe. Idempotent. RFC4918, Section 9.3; RFC5689, Section 3; RFC8144, Section 2.3. */ +#define MHD_HTTP_METHOD_MKCOL "MKCOL" +/* Not safe. Idempotent. RFC4437, Section 6. */ +#define MHD_HTTP_METHOD_MKREDIRECTREF "MKREDIRECTREF" +/* Not safe. Idempotent. RFC3253, Section 6.3. */ +#define MHD_HTTP_METHOD_MKWORKSPACE "MKWORKSPACE" +/* Not safe. Idempotent. RFC4918, Section 9.9. */ +#define MHD_HTTP_METHOD_MOVE "MOVE" +/* Not safe. Idempotent. RFC3648, Section 7. */ +#define MHD_HTTP_METHOD_ORDERPATCH "ORDERPATCH" +/* Not safe. Not idempotent. RFC5789, Section 2. */ +#define MHD_HTTP_METHOD_PATCH "PATCH" +/* Safe. Idempotent. RFC9113, Section 3.4. */ +#define MHD_HTTP_METHOD_PRI "PRI" +/* Safe. Idempotent. RFC4918, Section 9.1; RFC8144, Section 2.1. */ +#define MHD_HTTP_METHOD_PROPFIND "PROPFIND" +/* Not safe. Idempotent. RFC4918, Section 9.2; RFC8144, Section 2.2. */ +#define MHD_HTTP_METHOD_PROPPATCH "PROPPATCH" +/* Not safe. Idempotent. RFC5842, Section 6. */ +#define MHD_HTTP_METHOD_REBIND "REBIND" +/* Safe. Idempotent. RFC3253, Section 3.6; RFC8144, Section 2.1. */ +#define MHD_HTTP_METHOD_REPORT "REPORT" +/* Safe. Idempotent. RFC5323, Section 2. */ +#define MHD_HTTP_METHOD_SEARCH "SEARCH" +/* Not safe. Idempotent. RFC5842, Section 5. */ +#define MHD_HTTP_METHOD_UNBIND "UNBIND" +/* Not safe. Idempotent. RFC3253, Section 4.5. */ +#define MHD_HTTP_METHOD_UNCHECKOUT "UNCHECKOUT" +/* Not safe. Idempotent. RFC2068, Section 19.6.1.3. */ +#define MHD_HTTP_METHOD_UNLINK "UNLINK" +/* Not safe. Idempotent. RFC4918, Section 9.11. */ +#define MHD_HTTP_METHOD_UNLOCK "UNLOCK" +/* Not safe. Idempotent. RFC3253, Section 7.1. */ +#define MHD_HTTP_METHOD_UPDATE "UPDATE" +/* Not safe. Idempotent. RFC4437, Section 7. */ +#define MHD_HTTP_METHOD_UPDATEREDIRECTREF "UPDATEREDIRECTREF" +/* Not safe. Idempotent. RFC3253, Section 3.5. */ +#define MHD_HTTP_METHOD_VERSION_CONTROL "VERSION-CONTROL" +/* Not safe. Not idempotent. RFC9110, Section 18.2. */ +#define MHD_HTTP_METHOD_ASTERISK "*" + +/** @} */ /* end of group methods */ + +/** + * @defgroup postenc HTTP POST encodings + * See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 + * @{ + */ +#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED \ + "application/x-www-form-urlencoded" +#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA "multipart/form-data" + +/** @} */ /* end of group postenc */ + + +/** + * @brief Handle for the daemon (listening on a socket for HTTP traffic). + * @ingroup event + */ +struct MHD_Daemon; + +/** + * @brief Handle for a connection / HTTP request. + * + * With HTTP/1.1, multiple requests can be run over the same + * connection. However, MHD will only show one request per TCP + * connection to the client at any given time. + * @ingroup request + */ +struct MHD_Connection; + +/** + * @brief Handle for a response. + * @ingroup response + */ +struct MHD_Response; + +/** + * @brief Handle for POST processing. + * @ingroup response + */ +struct MHD_PostProcessor; + + +/** + * @brief Flags for the `struct MHD_Daemon`. + * + * Note that MHD will run automatically in background thread(s) only + * if #MHD_USE_INTERNAL_POLLING_THREAD is used. Otherwise caller (application) + * must use #MHD_run() or #MHD_run_from_select() to have MHD processed + * network connections and data. + * + * Starting the daemon may also fail if a particular option is not + * implemented or not supported on the target platform (i.e. no + * support for TLS, epoll or IPv6). + */ +enum MHD_FLAG +{ + /** + * No options selected. + */ + MHD_NO_FLAG = 0, + + /** + * Print errors messages to custom error logger or to `stderr` if + * custom error logger is not set. + * @sa ::MHD_OPTION_EXTERNAL_LOGGER + */ + MHD_USE_ERROR_LOG = 1, + + /** + * Run in debug mode. If this flag is used, the library should + * print error messages and warnings to `stderr`. + */ + MHD_USE_DEBUG = 1, + + /** + * Run in HTTPS mode. The modern protocol is called TLS. + */ + MHD_USE_TLS = 2, + + /** @deprecated */ + MHD_USE_SSL = 2, +#if 0 + /* let's do this later once versions that define MHD_USE_TLS a more widely deployed. */ +#define MHD_USE_SSL \ + _MHD_DEPR_IN_MACRO ("Value MHD_USE_SSL is deprecated, use MHD_USE_TLS") \ + MHD_USE_TLS +#endif + + /** + * Run using one thread per connection. + * Must be used only with #MHD_USE_INTERNAL_POLLING_THREAD. + * + * If #MHD_USE_ITC is also not used, closed and expired connections may only + * be cleaned up internally when a new connection is received. + * Consider adding of #MHD_USE_ITC flag to have faster internal cleanups + * at very minor increase in system resources usage. + */ + MHD_USE_THREAD_PER_CONNECTION = 4, + + /** + * Run using an internal thread (or thread pool) for sockets sending + * and receiving and data processing. Without this flag MHD will not + * run automatically in background thread(s). + * If this flag is set, #MHD_run() and #MHD_run_from_select() couldn't + * be used. + * This flag is set explicitly by #MHD_USE_POLL_INTERNAL_THREAD and + * by #MHD_USE_EPOLL_INTERNAL_THREAD. + * When this flag is not set, MHD run in "external" polling mode. + */ + MHD_USE_INTERNAL_POLLING_THREAD = 8, + + /** @deprecated */ + MHD_USE_SELECT_INTERNALLY = 8, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_SELECT_INTERNALLY \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_SELECT_INTERNALLY is deprecated, use MHD_USE_INTERNAL_POLLING_THREAD instead") \ + MHD_USE_INTERNAL_POLLING_THREAD +#endif /* 0 */ + + /** + * Run using the IPv6 protocol (otherwise, MHD will just support + * IPv4). If you want MHD to support IPv4 and IPv6 using a single + * socket, pass #MHD_USE_DUAL_STACK, otherwise, if you only pass + * this option, MHD will try to bind to IPv6-only (resulting in + * no IPv4 support). + */ + MHD_USE_IPv6 = 16, + + /** + * Be pedantic about the protocol (as opposed to as tolerant as + * possible). + * This flag is equivalent to setting 1 as #MHD_OPTION_CLIENT_DISCIPLINE_LVL + * value. + * @sa #MHD_OPTION_CLIENT_DISCIPLINE_LVL + */ + MHD_USE_PEDANTIC_CHECKS = 32, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_PEDANTIC_CHECKS \ + _MHD_DEPR_IN_MACRO ( \ + "Flag MHD_USE_PEDANTIC_CHECKS is deprecated, " \ + "use option MHD_OPTION_CLIENT_DISCIPLINE_LVL instead") \ + 32 +#endif /* 0 */ + + /** + * Use `poll()` instead of `select()` for polling sockets. + * This allows sockets with `fd >= FD_SETSIZE`. + * This option is not compatible with an "external" polling mode + * (as there is no API to get the file descriptors for the external + * poll() from MHD) and must also not be used in combination + * with #MHD_USE_EPOLL. + * @sa ::MHD_FEATURE_POLL, #MHD_USE_POLL_INTERNAL_THREAD + */ + MHD_USE_POLL = 64, + + /** + * Run using an internal thread (or thread pool) doing `poll()`. + * @sa ::MHD_FEATURE_POLL, #MHD_USE_POLL, #MHD_USE_INTERNAL_POLLING_THREAD + */ + MHD_USE_POLL_INTERNAL_THREAD = MHD_USE_POLL | MHD_USE_INTERNAL_POLLING_THREAD, + + /** @deprecated */ + MHD_USE_POLL_INTERNALLY = MHD_USE_POLL | MHD_USE_INTERNAL_POLLING_THREAD, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_POLL_INTERNALLY \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_POLL_INTERNALLY is deprecated, use MHD_USE_POLL_INTERNAL_THREAD instead") \ + MHD_USE_POLL_INTERNAL_THREAD +#endif /* 0 */ + + /** + * Suppress (automatically) adding the 'Date:' header to HTTP responses. + * This option should ONLY be used on systems that do not have a clock + * and that DO provide other mechanisms for cache control. See also + * RFC 2616, section 14.18 (exception 3). + */ + MHD_USE_SUPPRESS_DATE_NO_CLOCK = 128, + + /** @deprecated */ + MHD_SUPPRESS_DATE_NO_CLOCK = 128, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_SUPPRESS_DATE_NO_CLOCK \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_SUPPRESS_DATE_NO_CLOCK is deprecated, use MHD_USE_SUPPRESS_DATE_NO_CLOCK instead") \ + MHD_USE_SUPPRESS_DATE_NO_CLOCK +#endif /* 0 */ + + /** + * Run without a listen socket. This option only makes sense if + * #MHD_add_connection is to be used exclusively to connect HTTP + * clients to the HTTP server. This option is incompatible with + * using a thread pool; if it is used, #MHD_OPTION_THREAD_POOL_SIZE + * is ignored. + */ + MHD_USE_NO_LISTEN_SOCKET = 256, + + /** + * Use `epoll()` instead of `select()` or `poll()` for the event loop. + * This option is only available on some systems; using the option on + * systems without epoll will cause #MHD_start_daemon to fail. Using + * this option is not supported with #MHD_USE_THREAD_PER_CONNECTION. + * @sa ::MHD_FEATURE_EPOLL + */ + MHD_USE_EPOLL = 512, + + /** @deprecated */ + MHD_USE_EPOLL_LINUX_ONLY = 512, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_EPOLL_LINUX_ONLY \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_EPOLL_LINUX_ONLY is deprecated, use MHD_USE_EPOLL") \ + MHD_USE_EPOLL +#endif /* 0 */ + + /** + * Run using an internal thread (or thread pool) doing `epoll` polling. + * This option is only available on certain platforms; using the option on + * platform without `epoll` support will cause #MHD_start_daemon to fail. + * @sa ::MHD_FEATURE_EPOLL, #MHD_USE_EPOLL, #MHD_USE_INTERNAL_POLLING_THREAD + */ + MHD_USE_EPOLL_INTERNAL_THREAD = MHD_USE_EPOLL + | MHD_USE_INTERNAL_POLLING_THREAD, + + /** @deprecated */ + MHD_USE_EPOLL_INTERNALLY = MHD_USE_EPOLL | MHD_USE_INTERNAL_POLLING_THREAD, + /** @deprecated */ + MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY = MHD_USE_EPOLL + | MHD_USE_INTERNAL_POLLING_THREAD, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_EPOLL_INTERNALLY \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_EPOLL_INTERNALLY is deprecated, use MHD_USE_EPOLL_INTERNAL_THREAD") \ + MHD_USE_EPOLL_INTERNAL_THREAD + /** @deprecated */ +#define MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY is deprecated, use MHD_USE_EPOLL_INTERNAL_THREAD") \ + MHD_USE_EPOLL_INTERNAL_THREAD +#endif /* 0 */ + + /** + * Use inter-thread communication channel. + * #MHD_USE_ITC can be used with #MHD_USE_INTERNAL_POLLING_THREAD + * and is ignored with any "external" sockets polling. + * It's required for use of #MHD_quiesce_daemon + * or #MHD_add_connection. + * This option is enforced by #MHD_ALLOW_SUSPEND_RESUME or + * #MHD_USE_NO_LISTEN_SOCKET. + * #MHD_USE_ITC is always used automatically on platforms + * where select()/poll()/other ignore shutdown of listen + * socket. + */ + MHD_USE_ITC = 1024, + + /** @deprecated */ + MHD_USE_PIPE_FOR_SHUTDOWN = 1024, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_PIPE_FOR_SHUTDOWN \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_PIPE_FOR_SHUTDOWN is deprecated, use MHD_USE_ITC") \ + MHD_USE_ITC +#endif /* 0 */ + + /** + * Use a single socket for IPv4 and IPv6. + */ + MHD_USE_DUAL_STACK = MHD_USE_IPv6 | 2048, + + /** + * Enable `turbo`. Disables certain calls to `shutdown()`, + * enables aggressive non-blocking optimistic reads and + * other potentially unsafe optimizations. + * Most effects only happen with #MHD_USE_EPOLL. + */ + MHD_USE_TURBO = 4096, + + /** @deprecated */ + MHD_USE_EPOLL_TURBO = 4096, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_EPOLL_TURBO \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_EPOLL_TURBO is deprecated, use MHD_USE_TURBO") \ + MHD_USE_TURBO +#endif /* 0 */ + + /** + * Enable suspend/resume functions, which also implies setting up + * ITC to signal resume. + */ + MHD_ALLOW_SUSPEND_RESUME = 8192 | MHD_USE_ITC, + + /** @deprecated */ + MHD_USE_SUSPEND_RESUME = 8192 | MHD_USE_ITC, +#if 0 /* Will be marked for real deprecation later. */ +#define MHD_USE_SUSPEND_RESUME \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_USE_SUSPEND_RESUME is deprecated, use MHD_ALLOW_SUSPEND_RESUME instead") \ + MHD_ALLOW_SUSPEND_RESUME +#endif /* 0 */ + + /** + * Enable TCP_FASTOPEN option. This option is only available on Linux with a + * kernel >= 3.6. On other systems, using this option cases #MHD_start_daemon + * to fail. + */ + MHD_USE_TCP_FASTOPEN = 16384, + + /** + * You need to set this option if you want to use HTTP "Upgrade". + * "Upgrade" may require usage of additional internal resources, + * which we do not want to use unless necessary. + */ + MHD_ALLOW_UPGRADE = 32768, + + /** + * Automatically use best available polling function. + * Choice of polling function is also depend on other daemon options. + * If #MHD_USE_INTERNAL_POLLING_THREAD is specified then epoll, poll() or + * select() will be used (listed in decreasing preference order, first + * function available on system will be used). + * If #MHD_USE_THREAD_PER_CONNECTION is specified then poll() or select() + * will be used. + * If those flags are not specified then epoll or select() will be + * used (as the only suitable for MHD_get_fdset()) + */ + MHD_USE_AUTO = 65536, + + /** + * Run using an internal thread (or thread pool) with best available on + * system polling function. + * This is combination of #MHD_USE_AUTO and #MHD_USE_INTERNAL_POLLING_THREAD + * flags. + */ + MHD_USE_AUTO_INTERNAL_THREAD = MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, + + /** + * Flag set to enable post-handshake client authentication + * (only useful in combination with #MHD_USE_TLS). + */ + MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT = 1U << 17, + + /** + * Flag set to enable TLS 1.3 early data. This has + * security implications, be VERY careful when using this. + */ + MHD_USE_INSECURE_TLS_EARLY_DATA = 1U << 18, + + /** + * Indicates that MHD daemon will be used by application in single-threaded + * mode only. When this flag is set then application must call any MHD + * function only within a single thread. + * This flag turns off some internal thread-safety and allows MHD making + * some of the internal optimisations suitable only for single-threaded + * environment. + * Not compatible with #MHD_USE_INTERNAL_POLLING_THREAD. + * @note Available since #MHD_VERSION 0x00097707 + */ + MHD_USE_NO_THREAD_SAFETY = 1U << 19 + +}; + + +/** + * Type of a callback function used for logging by MHD. + * + * @param cls closure + * @param fm format string (`printf()`-style) + * @param ap arguments to @a fm + * @ingroup logging + */ +typedef void +(*MHD_LogCallback)(void *cls, + const char *fm, + va_list ap); + + +/** + * Function called to lookup the pre shared key (@a psk) for a given + * HTTP connection based on the @a username. + * + * @param cls closure + * @param connection the HTTPS connection + * @param username the user name claimed by the other side + * @param[out] psk to be set to the pre-shared-key; should be allocated with malloc(), + * will be freed by MHD + * @param[out] psk_size to be set to the number of bytes in @a psk + * @return 0 on success, -1 on errors + */ +typedef int +(*MHD_PskServerCredentialsCallback)(void *cls, + const struct MHD_Connection *connection, + const char *username, + void **psk, + size_t *psk_size); + +/** + * Values for #MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE. + * + * These values can limit the scope of validity of MHD-generated nonces. + * Values can be combined with bitwise OR. + * Any value, except #MHD_DAUTH_BIND_NONCE_NONE, enforce function + * #MHD_digest_auth_check3() (and similar functions) to check nonce by + * re-generating it again with the same parameters, which is CPU-intensive + * operation. + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DAuthBindNonce +{ + /** + * Generated nonces are valid for any request from any client until expired. + * This is default and recommended value. + * #MHD_digest_auth_check3() (and similar functions) would check only whether + * the nonce value that is used by client has been generated by MHD and not + * expired yet. + * It is recommended because RFC 7616 allows clients to use the same nonce + * for any request in the same "protection space". + * When checking client's authorisation requests CPU is loaded less if this + * value is used. + * This mode gives MHD maximum flexibility for nonces generation and can + * prevent possible nonce collisions (and corresponding log warning messages) + * when clients' requests are intensive. + * This value cannot be biwise-OR combined with other values. + */ + MHD_DAUTH_BIND_NONCE_NONE = 0, + + /** + * Generated nonces are valid only for the same realm. + */ + MHD_DAUTH_BIND_NONCE_REALM = 1 << 0, + + /** + * Generated nonces are valid only for the same URI (excluding parameters + * after '?' in URI) and request method (GET, POST etc). + * Not recommended unless "protection space" is limited to a single URI as + * RFC 7616 allows clients to re-use server-generated nonces for any URI + * in the same "protection space" which by default consists of all server + * URIs. + * Before #MHD_VERSION 0x00097701 this was default (and only supported) + * nonce bind type. + */ + MHD_DAUTH_BIND_NONCE_URI = 1 << 1, + + /** + * Generated nonces are valid only for the same URI including URI parameters + * and request method (GET, POST etc). + * This value implies #MHD_DAUTH_BIND_NONCE_URI. + * Not recommended for that same reasons as #MHD_DAUTH_BIND_NONCE_URI. + */ + MHD_DAUTH_BIND_NONCE_URI_PARAMS = 1 << 2, + + /** + * Generated nonces are valid only for the single client's IP. + * While it looks like security improvement, in practice the same client may + * jump from one IP to another (mobile or Wi-Fi handover, DHCP re-assignment, + * Multi-NAT, different proxy chain and other reasons), while IP address + * spoofing could be used relatively easily. + */ + MHD_DAUTH_BIND_NONCE_CLIENT_IP = 1 << 3 +} _MHD_FLAGS_ENUM; + +/** + * @brief MHD options. + * + * Passed in the varargs portion of #MHD_start_daemon. + */ +enum MHD_OPTION +{ + + /** + * No more options / last option. This is used + * to terminate the VARARGs list. + */ + MHD_OPTION_END = 0, + + /** + * Maximum memory size per connection (followed by a `size_t`). + * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT). + * Values above 128k are unlikely to result in much benefit, as half + * of the memory will be typically used for IO, and TCP buffers are + * unlikely to support window sizes above 64k on most systems. + * Values below 64 bytes are completely unusable. + * Since #MHD_VERSION 0x00097710 silently ignored if followed by zero value. + */ + MHD_OPTION_CONNECTION_MEMORY_LIMIT = 1, + + /** + * Maximum number of concurrent connections to + * accept (followed by an `unsigned int`). + */ + MHD_OPTION_CONNECTION_LIMIT = 2, + + /** + * After how many seconds of inactivity should a + * connection automatically be timed out? (followed + * by an `unsigned int`; use zero for no timeout). + * Values larger than (UINT64_MAX / 2000 - 1) will + * be clipped to this number. + */ + MHD_OPTION_CONNECTION_TIMEOUT = 3, + + /** + * Register a function that should be called whenever a request has + * been completed (this can be used for application-specific clean + * up). Requests that have never been presented to the application + * (via #MHD_AccessHandlerCallback) will not result in + * notifications. + * + * This option should be followed by TWO pointers. First a pointer + * to a function of type #MHD_RequestCompletedCallback and second a + * pointer to a closure to pass to the request completed callback. + * The second pointer may be NULL. + */ + MHD_OPTION_NOTIFY_COMPLETED = 4, + + /** + * Limit on the number of (concurrent) connections made to the + * server from the same IP address. Can be used to prevent one + * IP from taking over all of the allowed connections. If the + * same IP tries to establish more than the specified number of + * connections, they will be immediately rejected. The option + * should be followed by an `unsigned int`. The default is + * zero, which means no limit on the number of connections + * from the same IP address. + */ + MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5, + + /** + * Bind daemon to the supplied `struct sockaddr`. This option should + * be followed by a `struct sockaddr *`. If #MHD_USE_IPv6 is + * specified, the `struct sockaddr*` should point to a `struct + * sockaddr_in6`, otherwise to a `struct sockaddr_in`. + * Silently ignored if followed by NULL pointer. + * @deprecated Use #MHD_OPTION_SOCK_ADDR_LEN + */ + MHD_OPTION_SOCK_ADDR = 6, + + /** + * Specify a function that should be called before parsing the URI from + * the client. The specified callback function can be used for processing + * the URI (including the options) before it is parsed. The URI after + * parsing will no longer contain the options, which maybe inconvenient for + * logging. This option should be followed by two arguments, the first + * one must be of the form + * + * void * my_logger(void *cls, const char *uri, struct MHD_Connection *con) + * + * where the return value will be passed as + * (`* req_cls`) in calls to the #MHD_AccessHandlerCallback + * when this request is processed later; returning a + * value of NULL has no special significance (however, + * note that if you return non-NULL, you can no longer + * rely on the first call to the access handler having + * `NULL == *req_cls` on entry;) + * "cls" will be set to the second argument following + * #MHD_OPTION_URI_LOG_CALLBACK. Finally, uri will + * be the 0-terminated URI of the request. + * + * Note that during the time of this call, most of the connection's + * state is not initialized (as we have not yet parsed the headers). + * However, information about the connecting client (IP, socket) + * is available. + * + * The specified function is called only once per request, therefore some + * programmers may use it to instantiate their own request objects, freeing + * them in the notifier #MHD_OPTION_NOTIFY_COMPLETED. + */ + MHD_OPTION_URI_LOG_CALLBACK = 7, + + /** + * Memory pointer for the private key (key.pem) to be used by the + * HTTPS daemon. This option should be followed by a + * `const char *` argument. + * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_CERT. + */ + MHD_OPTION_HTTPS_MEM_KEY = 8, + + /** + * Memory pointer for the certificate (cert.pem) to be used by the + * HTTPS daemon. This option should be followed by a + * `const char *` argument. + * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY. + */ + MHD_OPTION_HTTPS_MEM_CERT = 9, + + /** + * Daemon credentials type. + * Followed by an argument of type + * `gnutls_credentials_type_t`. + */ + MHD_OPTION_HTTPS_CRED_TYPE = 10, + + /** + * Memory pointer to a `const char *` specifying the GnuTLS priorities string. + * If this options is not specified, then MHD will try the following strings: + * * "@LIBMICROHTTPD" (application-specific system-wide configuration) + * * "@SYSTEM" (system-wide configuration) + * * default GnuTLS priorities string + * * "NORMAL" + * The first configuration accepted by GnuTLS will be used. + * For more details see GnuTLS documentation for "Application-specific + * priority strings". + */ + MHD_OPTION_HTTPS_PRIORITIES = 11, + + /** + * Pass a listen socket for MHD to use (systemd-style). If this + * option is used, MHD will not open its own listen socket(s). The + * argument passed must be of type `MHD_socket` and refer to an + * existing socket that has been bound to a port and is listening. + * If followed by MHD_INVALID_SOCKET value, MHD ignores this option + * and creates socket by itself. + */ + MHD_OPTION_LISTEN_SOCKET = 12, + + /** + * Use the given function for logging error messages. This option + * must be followed by two arguments; the first must be a pointer to + * a function of type #MHD_LogCallback and the second a pointer + * `void *` which will be passed as the first argument to the log + * callback. + * Should be specified as the first option, otherwise some messages + * may be printed by standard MHD logger during daemon startup. + * + * Note that MHD will not generate any log messages + * if it was compiled without the "--enable-messages" + * flag being set. + */ + MHD_OPTION_EXTERNAL_LOGGER = 13, + + /** + * Number (`unsigned int`) of threads in thread pool. Enable + * thread pooling by setting this value to to something + * greater than 1. + * Can be used only for daemons started with #MHD_USE_INTERNAL_POLLING_THREAD. + * Ignored if followed by zero value. + */ + MHD_OPTION_THREAD_POOL_SIZE = 14, + + /** + * Additional options given in an array of `struct MHD_OptionItem`. + * The array must be terminated with an entry `{MHD_OPTION_END, 0, NULL}`. + * An example for code using #MHD_OPTION_ARRAY is: + * + * struct MHD_OptionItem ops[] = { + * { MHD_OPTION_CONNECTION_LIMIT, 100, NULL }, + * { MHD_OPTION_CONNECTION_TIMEOUT, 10, NULL }, + * { MHD_OPTION_END, 0, NULL } + * }; + * d = MHD_start_daemon (0, 8080, NULL, NULL, dh, NULL, + * MHD_OPTION_ARRAY, ops, + * MHD_OPTION_END); + * + * For options that expect a single pointer argument, the + * 'value' member of the `struct MHD_OptionItem` is ignored. + * For options that expect two pointer arguments, the first + * argument must be cast to `intptr_t`. + */ + MHD_OPTION_ARRAY = 15, + + /** + * Specify a function that should be called for unescaping escape + * sequences in URIs and URI arguments. Note that this function + * will NOT be used by the `struct MHD_PostProcessor`. If this + * option is not specified, the default method will be used which + * decodes escape sequences of the form "%HH". This option should + * be followed by two arguments, the first one must be of the form + * + * size_t my_unescaper(void *cls, + * struct MHD_Connection *c, + * char *s) + * + * where the return value must be the length of the value left in + * "s" (without the 0-terminator) and "s" should be updated. Note + * that the unescape function must not lengthen "s" (the result must + * be shorter than the input and must still be 0-terminated). + * However, it may also include binary zeros before the + * 0-termination. "cls" will be set to the second argument + * following #MHD_OPTION_UNESCAPE_CALLBACK. + */ + MHD_OPTION_UNESCAPE_CALLBACK = 16, + + /** + * Memory pointer for the random values to be used by the Digest + * Auth module. This option should be followed by two arguments. + * First an integer of type `size_t` which specifies the size + * of the buffer pointed to by the second argument in bytes. + * The recommended size is between 8 and 32. If size is four or less + * then security could be lowered. Sizes more then 32 (or, probably + * more than 16 - debatable) will not increase security. + * Note that the application must ensure that the buffer of the + * second argument remains allocated and unmodified while the + * daemon is running. + * @sa #MHD_OPTION_DIGEST_AUTH_RANDOM_COPY + */ + MHD_OPTION_DIGEST_AUTH_RANDOM = 17, + + /** + * Size of the internal array holding the map of the nonce and + * the nonce counter. This option should be followed by an `unsigend int` + * argument. + * The map size is 4 by default, which is enough to communicate with + * a single client at any given moment of time, but not enough to + * handle several clients simultaneously. + * If Digest Auth is not used, this option can be set to zero to minimise + * memory allocation. + */ + MHD_OPTION_NONCE_NC_SIZE = 18, + + /** + * Desired size of the stack for threads created by MHD. Followed + * by an argument of type `size_t`. Use 0 for system default. + */ + MHD_OPTION_THREAD_STACK_SIZE = 19, + + /** + * Memory pointer for the certificate (ca.pem) to be used by the + * HTTPS daemon for client authentication. + * This option should be followed by a `const char *` argument. + */ + MHD_OPTION_HTTPS_MEM_TRUST = 20, + + /** + * Increment to use for growing the read buffer (followed by a + * `size_t`). + * Must not be higher than 1/4 of #MHD_OPTION_CONNECTION_MEMORY_LIMIT. + * Since #MHD_VERSION 0x00097710 silently ignored if followed by zero value. + */ + MHD_OPTION_CONNECTION_MEMORY_INCREMENT = 21, + + /** + * Use a callback to determine which X.509 certificate should be + * used for a given HTTPS connection. This option should be + * followed by a argument of type `gnutls_certificate_retrieve_function2 *`. + * This option provides an + * alternative to #MHD_OPTION_HTTPS_MEM_KEY, + * #MHD_OPTION_HTTPS_MEM_CERT. You must use this version if + * multiple domains are to be hosted at the same IP address using + * TLS's Server Name Indication (SNI) extension. In this case, + * the callback is expected to select the correct certificate + * based on the SNI information provided. The callback is expected + * to access the SNI data using `gnutls_server_name_get()`. + * Using this option requires GnuTLS 3.0 or higher. + */ + MHD_OPTION_HTTPS_CERT_CALLBACK = 22, + + /** + * When using #MHD_USE_TCP_FASTOPEN, this option changes the default TCP + * fastopen queue length of 50. Note that having a larger queue size can + * cause resource exhaustion attack as the TCP stack has to now allocate + * resources for the SYN packet along with its DATA. This option should be + * followed by an `unsigned int` argument. + */ + MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE = 23, + + /** + * Memory pointer for the Diffie-Hellman parameters (dh.pem) to be used by the + * HTTPS daemon for key exchange. + * This option must be followed by a `const char *` argument. + */ + MHD_OPTION_HTTPS_MEM_DHPARAMS = 24, + + /** + * If present and set to true, allow reusing address:port socket + * (by using SO_REUSEPORT on most platform, or platform-specific ways). + * If present and set to false, disallow reusing address:port socket + * (does nothing on most platform, but uses SO_EXCLUSIVEADDRUSE on Windows). + * This option must be followed by a `unsigned int` argument. + */ + MHD_OPTION_LISTENING_ADDRESS_REUSE = 25, + + /** + * Memory pointer for a password that decrypts the private key (key.pem) + * to be used by the HTTPS daemon. This option should be followed by a + * `const char *` argument. + * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY. + * @sa ::MHD_FEATURE_HTTPS_KEY_PASSWORD + */ + MHD_OPTION_HTTPS_KEY_PASSWORD = 26, + + /** + * Register a function that should be called whenever a connection is + * started or closed. + * + * This option should be followed by TWO pointers. First a pointer + * to a function of type #MHD_NotifyConnectionCallback and second a + * pointer to a closure to pass to the request completed callback. + * The second pointer may be NULL. + */ + MHD_OPTION_NOTIFY_CONNECTION = 27, + + /** + * Allow to change maximum length of the queue of pending connections on + * listen socket. If not present than default platform-specific SOMAXCONN + * value is used. This option should be followed by an `unsigned int` + * argument. + */ + MHD_OPTION_LISTEN_BACKLOG_SIZE = 28, + + /** + * If set to 1 - be strict about the protocol. Use -1 to be + * as tolerant as possible. + * + * The more flexible option #MHD_OPTION_CLIENT_DISCIPLINE_LVL is recommended + * instead of this option. + * + * The values mapping table: + * #MHD_OPTION_STRICT_FOR_CLIENT | #MHD_OPTION_CLIENT_DISCIPLINE_LVL + * -----------------------------:|:--------------------------------- + * 1 | 1 + * 0 | 0 + * -1 | -3 + * + * This option should be followed by an `int` argument. + * @sa #MHD_OPTION_CLIENT_DISCIPLINE_LVL + */ + MHD_OPTION_STRICT_FOR_CLIENT = 29, + + /** + * This should be a pointer to callback of type + * gnutls_psk_server_credentials_function that will be given to + * gnutls_psk_set_server_credentials_function. It is used to + * retrieve the shared key for a given username. + */ + MHD_OPTION_GNUTLS_PSK_CRED_HANDLER = 30, + + /** + * Use a callback to determine which X.509 certificate should be + * used for a given HTTPS connection. This option should be + * followed by a argument of type `gnutls_certificate_retrieve_function3 *`. + * This option provides an + * alternative/extension to #MHD_OPTION_HTTPS_CERT_CALLBACK. + * You must use this version if you want to use OCSP stapling. + * Using this option requires GnuTLS 3.6.3 or higher. + */ + MHD_OPTION_HTTPS_CERT_CALLBACK2 = 31, + + /** + * Allows the application to disable certain sanity precautions + * in MHD. With these, the client can break the HTTP protocol, + * so this should never be used in production. The options are, + * however, useful for testing HTTP clients against "broken" + * server implementations. + * This argument must be followed by an "unsigned int", corresponding + * to an `enum MHD_DisableSanityCheck`. + */ + MHD_OPTION_SERVER_INSANITY = 32, + + /** + * If followed by value '1' informs MHD that SIGPIPE is suppressed or + * handled by application. Allows MHD to use network functions that could + * generate SIGPIPE, like `sendfile()`. + * Valid only for daemons without #MHD_USE_INTERNAL_POLLING_THREAD as + * MHD automatically suppresses SIGPIPE for threads started by MHD. + * This option should be followed by an `int` argument. + * @note Available since #MHD_VERSION 0x00097205 + */ + MHD_OPTION_SIGPIPE_HANDLED_BY_APP = 33, + + /** + * If followed by 'int' with value '1' disables usage of ALPN for TLS + * connections even if supported by TLS library. + * Valid only for daemons with #MHD_USE_TLS. + * This option should be followed by an `int` argument. + * @note Available since #MHD_VERSION 0x00097207 + */ + MHD_OPTION_TLS_NO_ALPN = 34, + + /** + * Memory pointer for the random values to be used by the Digest + * Auth module. This option should be followed by two arguments. + * First an integer of type `size_t` which specifies the size + * of the buffer pointed to by the second argument in bytes. + * The recommended size is between 8 and 32. If size is four or less + * then security could be lowered. Sizes more then 32 (or, probably + * more than 16 - debatable) will not increase security. + * An internal copy of the buffer will be made, the data do not + * need to be static. + * @sa #MHD_OPTION_DIGEST_AUTH_RANDOM + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_OPTION_DIGEST_AUTH_RANDOM_COPY = 35, + + /** + * Allow to controls the scope of validity of MHD-generated nonces. + * This regulates how "nonces" are generated and how "nonces" are checked by + * #MHD_digest_auth_check3() and similar functions. + * This option should be followed by an 'unsigned int` argument with value + * formed as bitwise OR combination of #MHD_DAuthBindNonce values. + * When not specified, default value #MHD_DAUTH_BIND_NONCE_NONE is used. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE = 36, + + /** + * Memory pointer to a `const char *` specifying the GnuTLS priorities to be + * appended to default priorities. + * This allow some specific options to be enabled/disabled, while leaving + * the rest of the settings to their defaults. + * The string does not have to start with a colon ':' character. + * See #MHD_OPTION_HTTPS_PRIORITIES description for details of automatic + * default priorities. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_OPTION_HTTPS_PRIORITIES_APPEND = 37, + + /** + * Sets specified client discipline level (i.e. HTTP protocol parsing + * strictness level). + * + * The following basic values are supported: + * 0 - default MHD level, a balance between extra security and broader + * compatibility, as allowed by RFCs for HTTP servers; + * 1 - more strict protocol interpretation, within the limits set by + * RFCs for HTTP servers; + * -1 - more lenient protocol interpretation, within the limits set by + * RFCs for HTTP servers. + * The following extended values could be used as well: + * 2 - stricter protocol interpretation, even stricter then allowed + * by RFCs for HTTP servers, however it should be absolutely compatible + * with clients following at least RFCs' "MUST" type of requirements + * for HTTP clients; + * 3 - strictest protocol interpretation, even stricter then allowed + * by RFCs for HTTP servers, however it should be absolutely compatible + * with clients following RFCs' "SHOULD" and "MUST" types of requirements + * for HTTP clients; + * -2 - more relaxed protocol interpretation, violating RFCs' "SHOULD" type + * of requirements for HTTP servers; + * -3 - the most flexible protocol interpretation, beyond RFCs' "MUST" type of + * requirements for HTTP server. + * Values higher than "3" or lower than "-3" are interpreted as "3" or "-3" + * respectively. + * + * Higher values are more secure, lower values are more compatible with + * various HTTP clients. + * + * The default value ("0") could be used in most cases. + * Value "1" is suitable for highly loaded public servers. + * Values "2" and "3" are generally recommended only for testing of HTTP + * clients against MHD. + * Value "2" may be used for security-centric application, however it is + * slight violation of RFCs' requirements. + * Negative values are not recommended for public servers. + * Values "-1" and "-2" could be used for servers in isolated environment. + * Value "-3" is not recommended unless it is absolutely necessary to + * communicate with some client(s) with badly broken HTTP implementation. + * + * This option should be followed by an `int` argument. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_OPTION_CLIENT_DISCIPLINE_LVL = 38, + + /** + * Specifies value of FD_SETSIZE used by application. Only For external + * polling modes (without MHD internal threads). + * Some platforms (FreeBSD, Solaris, W32 etc.) allow overriding of FD_SETSIZE + * value. When polling by select() is used, MHD rejects sockets with numbers + * equal or higher than FD_SETSIZE. If this option is used, MHD treats this + * value as a limitation for socket number instead of FD_SETSIZE value which + * was used for building MHD. + * When external polling is used with #MHD_get_fdset2() (or #MHD_get_fdset() + * macro) and #MHD_run_from_select() interfaces, it is recommended to always + * use this option. + * It is safe to use this option on platforms with fixed FD_SETSIZE (like + * GNU/Linux) if system value of FD_SETSIZE is used as the argument. + * Can be used only for daemons without #MHD_USE_INTERNAL_POLLING_THREAD, i.e. + * only when external sockets polling is used. + * On W32 it is silently ignored, as W32 does not limit the socket number in + * fd_sets. + * This option should be followed by a positive 'int' argument. + * @note Available since #MHD_VERSION 0x00097705 + */ + MHD_OPTION_APP_FD_SETSIZE = 39, + + /** + * Bind daemon to the supplied 'struct sockaddr'. This option should + * be followed by two parameters: 'socklen_t' the size of memory at the next + * pointer and the pointer 'const struct sockaddr *'. + * Note: the order of the arguments is not the same as for system bind() and + * other network functions. + * If #MHD_USE_IPv6 is specified, the 'struct sockaddr*' should + * point to a 'struct sockaddr_in6'. + * The socket domain (protocol family) is detected from provided + * 'struct sockaddr'. IP, IPv6 and UNIX sockets are supported (if supported + * by the platform). Other types may work occasionally. + * Silently ignored if followed by zero size and NULL pointer. + * @note Available since #MHD_VERSION 0x00097706 + */ + MHD_OPTION_SOCK_ADDR_LEN = 40 + , + /** + * Default nonce timeout value used for Digest Auth. + * This option should be followed by an 'unsigned int' argument. + * Silently ignored if followed by zero value. + * @see #MHD_digest_auth_check3(), MHD_digest_auth_check_digest3() + * @note Available since #MHD_VERSION 0x00097709 + */ + MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT = 41 + , + /** + * Default maximum nc (nonce count) value used for Digest Auth. + * This option should be followed by an 'uint32_t' argument. + * Silently ignored if followed by zero value. + * @see #MHD_digest_auth_check3(), MHD_digest_auth_check_digest3() + * @note Available since #MHD_VERSION 0x00097709 + */ + MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC = 42 + +} _MHD_FIXED_ENUM; + + +/** + * Bitfield for the #MHD_OPTION_SERVER_INSANITY specifying + * which santiy checks should be disabled. + */ +enum MHD_DisableSanityCheck +{ + /** + * All sanity checks are enabled. + */ + MHD_DSC_SANE = 0 + +} _MHD_FIXED_FLAGS_ENUM; + + +/** + * Entry in an #MHD_OPTION_ARRAY. + */ +struct MHD_OptionItem +{ + /** + * Which option is being given. Use #MHD_OPTION_END + * to terminate the array. + */ + enum MHD_OPTION option; + + /** + * Option value (for integer arguments, and for options requiring + * two pointer arguments); should be 0 for options that take no + * arguments or only a single pointer argument. + */ + intptr_t value; + + /** + * Pointer option value (use NULL for options taking no arguments + * or only an integer option). + */ + void *ptr_value; + +}; + + +/** + * The `enum MHD_ValueKind` specifies the source of + * the key-value pairs in the HTTP protocol. + */ +enum MHD_ValueKind +{ + + /** + * Response header + * @deprecated + */ + MHD_RESPONSE_HEADER_KIND = 0, +#define MHD_RESPONSE_HEADER_KIND \ + _MHD_DEPR_IN_MACRO ( \ + "Value MHD_RESPONSE_HEADER_KIND is deprecated and not used") \ + MHD_RESPONSE_HEADER_KIND + + /** + * HTTP header (request/response). + */ + MHD_HEADER_KIND = 1, + + /** + * Cookies. Note that the original HTTP header containing + * the cookie(s) will still be available and intact. + */ + MHD_COOKIE_KIND = 2, + + /** + * POST data. This is available only if a content encoding + * supported by MHD is used (currently only URL encoding), + * and only if the posted content fits within the available + * memory pool. Note that in that case, the upload data + * given to the #MHD_AccessHandlerCallback will be + * empty (since it has already been processed). + */ + MHD_POSTDATA_KIND = 4, + + /** + * GET (URI) arguments. + */ + MHD_GET_ARGUMENT_KIND = 8, + + /** + * HTTP footer (only for HTTP 1.1 chunked encodings). + */ + MHD_FOOTER_KIND = 16 +} _MHD_FIXED_ENUM; + + +/** + * The `enum MHD_RequestTerminationCode` specifies reasons + * why a request has been terminated (or completed). + * @ingroup request + */ +enum MHD_RequestTerminationCode +{ + + /** + * We finished sending the response. + * @ingroup request + */ + MHD_REQUEST_TERMINATED_COMPLETED_OK = 0, + + /** + * Error handling the connection (resources + * exhausted, application error accepting request, + * decrypt error (for HTTPS), connection died when + * sending the response etc.) + * @ingroup request + */ + MHD_REQUEST_TERMINATED_WITH_ERROR = 1, + + /** + * No activity on the connection for the number + * of seconds specified using + * #MHD_OPTION_CONNECTION_TIMEOUT. + * @ingroup request + */ + MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 2, + + /** + * We had to close the session since MHD was being + * shut down. + * @ingroup request + */ + MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 3, + + /** + * We tried to read additional data, but the connection became broken or + * the other side hard closed the connection. + * This error is similar to #MHD_REQUEST_TERMINATED_WITH_ERROR, but + * specific to the case where the connection died before request completely + * received. + * @ingroup request + */ + MHD_REQUEST_TERMINATED_READ_ERROR = 4, + + /** + * The client terminated the connection by closing the socket + * for writing (TCP half-closed) while still sending request. + * @ingroup request + */ + MHD_REQUEST_TERMINATED_CLIENT_ABORT = 5 + +} _MHD_FIXED_ENUM; + + +/** + * The `enum MHD_ConnectionNotificationCode` specifies types + * of connection notifications. + * @ingroup request + */ +enum MHD_ConnectionNotificationCode +{ + + /** + * A new connection has been started. + * @ingroup request + */ + MHD_CONNECTION_NOTIFY_STARTED = 0, + + /** + * A connection is closed. + * @ingroup request + */ + MHD_CONNECTION_NOTIFY_CLOSED = 1 + +} _MHD_FIXED_ENUM; + + +/** + * Information about a connection. + */ +union MHD_ConnectionInfo +{ + + /** + * Cipher algorithm used, of type "enum gnutls_cipher_algorithm". + */ + int /* enum gnutls_cipher_algorithm */ cipher_algorithm; + + /** + * Protocol used, of type "enum gnutls_protocol". + */ + int /* enum gnutls_protocol */ protocol; + + /** + * The suspended status of a connection. + */ + int /* MHD_YES or MHD_NO */ suspended; + + /** + * Amount of second that connection could spend in idle state + * before automatically disconnected. + * Zero for no timeout (unlimited idle time). + */ + unsigned int connection_timeout; + + /** + * HTTP status queued with the response, for #MHD_CONNECTION_INFO_HTTP_STATUS. + */ + unsigned int http_status; + + /** + * Connect socket + */ + MHD_socket connect_fd; + + /** + * Size of the client's HTTP header. + * It includes the request line, all request headers, the header section + * terminating empty line, with all CRLF (or LF) characters. + */ + size_t header_size; + + /** + * GNUtls session handle, of type "gnutls_session_t". + */ + void * /* gnutls_session_t */ tls_session; + + /** + * GNUtls client certificate handle, of type "gnutls_x509_crt_t". + */ + void * /* gnutls_x509_crt_t */ client_cert; + + /** + * Address information for the client. + */ + struct sockaddr *client_addr; + + /** + * Which daemon manages this connection (useful in case there are many + * daemons running). + */ + struct MHD_Daemon *daemon; + + /** + * Socket-specific client context. Points to the same address as + * the "socket_context" of the #MHD_NotifyConnectionCallback. + */ + void *socket_context; +}; + + +/** + * I/O vector type. Provided for use with #MHD_create_response_from_iovec(). + * @note Available since #MHD_VERSION 0x00097204 + */ +struct MHD_IoVec +{ + /** + * The pointer to the memory region for I/O. + */ + const void *iov_base; + + /** + * The size in bytes of the memory region for I/O. + */ + size_t iov_len; +}; + + +/** + * Values of this enum are used to specify what + * information about a connection is desired. + * @ingroup request + */ +enum MHD_ConnectionInfoType +{ + /** + * What cipher algorithm is being used. + * Takes no extra arguments. + * @ingroup request + */ + MHD_CONNECTION_INFO_CIPHER_ALGO, + + /** + * + * Takes no extra arguments. + * @ingroup request + */ + MHD_CONNECTION_INFO_PROTOCOL, + + /** + * Obtain IP address of the client. Takes no extra arguments. + * Returns essentially a `struct sockaddr **` (since the API returns + * a `union MHD_ConnectionInfo *` and that union contains a `struct + * sockaddr *`). + * @ingroup request + */ + MHD_CONNECTION_INFO_CLIENT_ADDRESS, + + /** + * Get the gnuTLS session handle. + * @ingroup request + */ + MHD_CONNECTION_INFO_GNUTLS_SESSION, + + /** + * Get the gnuTLS client certificate handle. Dysfunctional (never + * implemented, deprecated). Use #MHD_CONNECTION_INFO_GNUTLS_SESSION + * to get the `gnutls_session_t` and then call + * gnutls_certificate_get_peers(). + */ + MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT, + + /** + * Get the `struct MHD_Daemon *` responsible for managing this connection. + * @ingroup request + */ + MHD_CONNECTION_INFO_DAEMON, + + /** + * Request the file descriptor for the connection socket. + * MHD sockets are always in non-blocking mode. + * No extra arguments should be passed. + * @ingroup request + */ + MHD_CONNECTION_INFO_CONNECTION_FD, + + /** + * Returns the client-specific pointer to a `void *` that was (possibly) + * set during a #MHD_NotifyConnectionCallback when the socket was + * first accepted. + * Note that this is NOT the same as the "req_cls" argument of + * the #MHD_AccessHandlerCallback. The "req_cls" is fresh for each + * HTTP request, while the "socket_context" is fresh for each socket. + */ + MHD_CONNECTION_INFO_SOCKET_CONTEXT, + + /** + * Check whether the connection is suspended. + * @ingroup request + */ + MHD_CONNECTION_INFO_CONNECTION_SUSPENDED, + + /** + * Get connection timeout + * @ingroup request + */ + MHD_CONNECTION_INFO_CONNECTION_TIMEOUT, + + /** + * Return length of the client's HTTP request header. + * @ingroup request + */ + MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE, + + /** + * Return HTTP status queued with the response. NULL + * if no HTTP response has been queued yet. + */ + MHD_CONNECTION_INFO_HTTP_STATUS + +} _MHD_FIXED_ENUM; + + +/** + * Values of this enum are used to specify what + * information about a daemon is desired. + */ +enum MHD_DaemonInfoType +{ + /** + * No longer supported (will return NULL). + */ + MHD_DAEMON_INFO_KEY_SIZE, + + /** + * No longer supported (will return NULL). + */ + MHD_DAEMON_INFO_MAC_KEY_SIZE, + + /** + * Request the file descriptor for the listening socket. + * No extra arguments should be passed. + */ + MHD_DAEMON_INFO_LISTEN_FD, + + /** + * Request the file descriptor for the "external" sockets polling + * when 'epoll' mode is used. + * No extra arguments should be passed. + * + * Waiting on epoll FD must not block longer than value + * returned by #MHD_get_timeout() otherwise connections + * will "hung" with unprocessed data in network buffers + * and timed-out connections will not be closed. + * + * @sa #MHD_get_timeout(), #MHD_run() + */ + MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY, + MHD_DAEMON_INFO_EPOLL_FD = MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY, + + /** + * Request the number of current connections handled by the daemon. + * No extra arguments should be passed. + * Note: when using MHD in "external" polling mode, this type of request + * could be used only when #MHD_run()/#MHD_run_from_select is not + * working in other thread at the same time. + */ + MHD_DAEMON_INFO_CURRENT_CONNECTIONS, + + /** + * Request the daemon flags. + * No extra arguments should be passed. + * Note: flags may differ from original 'flags' specified for + * daemon, especially if #MHD_USE_AUTO was set. + */ + MHD_DAEMON_INFO_FLAGS, + + /** + * Request the port number of daemon's listen socket. + * No extra arguments should be passed. + * Note: if port '0' was specified for #MHD_start_daemon(), returned + * value will be real port number. + */ + MHD_DAEMON_INFO_BIND_PORT +} _MHD_FIXED_ENUM; + + +/** + * Callback for serious error condition. The default action is to print + * an error message and `abort()`. + * + * @param cls user specified value + * @param file where the error occurred, may be NULL if MHD was built without + * messages support + * @param line where the error occurred + * @param reason error detail, may be NULL + * @ingroup logging + */ +typedef void +(*MHD_PanicCallback) (void *cls, + const char *file, + unsigned int line, + const char *reason); + +/** + * Allow or deny a client to connect. + * + * @param cls closure + * @param addr address information from the client + * @param addrlen length of @a addr + * @return #MHD_YES if connection is allowed, #MHD_NO if not + */ +typedef enum MHD_Result +(*MHD_AcceptPolicyCallback)(void *cls, + const struct sockaddr *addr, + socklen_t addrlen); + + +/** + * A client has requested the given @a url using the given @a method + * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT, #MHD_HTTP_METHOD_DELETE, + * #MHD_HTTP_METHOD_POST, etc). + * + * The callback must call MHD function MHD_queue_response() to provide content + * to give back to the client and return an HTTP status code (i.e. + * #MHD_HTTP_OK, #MHD_HTTP_NOT_FOUND, etc.). The response can be created + * in this callback or prepared in advance. + * Alternatively, callback may call MHD_suspend_connection() to temporarily + * suspend data processing for this connection. + * + * As soon as response is provided this callback will not be called anymore + * for the current request. + * + * For each HTTP request this callback is called several times: + * * after request headers are fully received and decoded, + * * for each received part of request body (optional, if request has body), + * * when request is fully received. + * + * If response is provided before request is fully received, the rest + * of the request is discarded and connection is automatically closed + * after sending response. + * + * If the request is fully received, but response hasn't been provided and + * connection is not suspended, the callback can be called again immediately. + * + * The response cannot be queued when this callback is called to process + * the client upload data (when @a upload_data is not NULL). + * + * @param cls argument given together with the function + * pointer when the handler was registered with MHD + * @param connection the connection handle + * @param url the requested url + * @param method the HTTP method used (#MHD_HTTP_METHOD_GET, + * #MHD_HTTP_METHOD_PUT, etc.) + * @param version the HTTP version string (i.e. + * #MHD_HTTP_VERSION_1_1) + * @param upload_data the data being uploaded (excluding HEADERS, + * for a POST that fits into memory and that is encoded + * with a supported encoding, the POST data will NOT be + * given in upload_data and is instead available as + * part of #MHD_get_connection_values; very large POST + * data *will* be made available incrementally in + * @a upload_data) + * @param[in,out] upload_data_size set initially to the size of the + * @a upload_data provided; the method must update this + * value to the number of bytes NOT processed; + * @param[in,out] req_cls pointer that the callback can set to some + * address and that will be preserved by MHD for future + * calls for this request; since the access handler may + * be called many times (i.e., for a PUT/POST operation + * with plenty of upload data) this allows the application + * to easily associate some request-specific state. + * If necessary, this state can be cleaned up in the + * global #MHD_RequestCompletedCallback (which + * can be set with the #MHD_OPTION_NOTIFY_COMPLETED). + * Initially, `*req_cls` will be NULL. + * @return #MHD_YES if the connection was handled successfully, + * #MHD_NO if the socket must be closed due to a serious + * error while handling the request + * + * @sa #MHD_queue_response() + */ +typedef enum MHD_Result +(*MHD_AccessHandlerCallback)(void *cls, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t *upload_data_size, + void **req_cls); + + +/** + * Signature of the callback used by MHD to notify the + * application about completed requests. + * + * @param cls client-defined closure + * @param connection connection handle + * @param req_cls value as set by the last call to + * the #MHD_AccessHandlerCallback + * @param toe reason for request termination + * @see #MHD_OPTION_NOTIFY_COMPLETED + * @ingroup request + */ +typedef void +(*MHD_RequestCompletedCallback) (void *cls, + struct MHD_Connection *connection, + void **req_cls, + enum MHD_RequestTerminationCode toe); + + +/** + * Signature of the callback used by MHD to notify the + * application about started/stopped connections + * + * @param cls client-defined closure + * @param connection connection handle + * @param socket_context socket-specific pointer where the + * client can associate some state specific + * to the TCP connection; note that this is + * different from the "req_cls" which is per + * HTTP request. The client can initialize + * during #MHD_CONNECTION_NOTIFY_STARTED and + * cleanup during #MHD_CONNECTION_NOTIFY_CLOSED + * and access in the meantime using + * #MHD_CONNECTION_INFO_SOCKET_CONTEXT. + * @param toe reason for connection notification + * @see #MHD_OPTION_NOTIFY_CONNECTION + * @ingroup request + */ +typedef void +(*MHD_NotifyConnectionCallback) (void *cls, + struct MHD_Connection *connection, + void **socket_context, + enum MHD_ConnectionNotificationCode toe); + + +/** + * Iterator over key-value pairs. This iterator + * can be used to iterate over all of the cookies, + * headers, or POST-data fields of a request, and + * also to iterate over the headers that have been + * added to a response. + * + * @param cls closure + * @param kind kind of the header we are looking at + * @param key key for the value, can be an empty string + * @param value corresponding value, can be NULL + * @return #MHD_YES to continue iterating, + * #MHD_NO to abort the iteration + * @ingroup request + */ +typedef enum MHD_Result +(*MHD_KeyValueIterator)(void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *value); + + +/** + * Iterator over key-value pairs with size parameters. + * This iterator can be used to iterate over all of + * the cookies, headers, or POST-data fields of a + * request, and also to iterate over the headers that + * have been added to a response. + * @note Available since #MHD_VERSION 0x00096303 + * + * @param cls closure + * @param kind kind of the header we are looking at + * @param key key for the value, can be an empty string + * @param value corresponding value, can be NULL + * @param value_size number of bytes in @a value; + * for C-strings, the length excludes the 0-terminator + * @return #MHD_YES to continue iterating, + * #MHD_NO to abort the iteration + * @ingroup request + */ +typedef enum MHD_Result +(*MHD_KeyValueIteratorN)(void *cls, + enum MHD_ValueKind kind, + const char *key, + size_t key_size, + const char *value, + size_t value_size); + + +/** + * Callback used by libmicrohttpd in order to obtain content. + * + * The callback is to copy at most @a max bytes of content into @a buf. + * The total number of bytes that has been placed into @a buf should be + * returned. + * + * Note that returning zero will cause libmicrohttpd to try again. + * Thus, returning zero should only be used in conjunction + * with MHD_suspend_connection() to avoid busy waiting. + * + * @param cls extra argument to the callback + * @param pos position in the datastream to access; + * note that if a `struct MHD_Response` object is re-used, + * it is possible for the same content reader to + * be queried multiple times for the same data; + * however, if a `struct MHD_Response` is not re-used, + * libmicrohttpd guarantees that "pos" will be + * the sum of all non-negative return values + * obtained from the content reader so far. + * @param buf where to copy the data + * @param max maximum number of bytes to copy to @a buf (size of @a buf) + * @return number of bytes written to @a buf; + * 0 is legal unless MHD is started in "internal" sockets polling mode + * (since this would cause busy-waiting); 0 in "external" sockets + * polling mode will cause this function to be called again once + * any MHD_run*() function is called; + * #MHD_CONTENT_READER_END_OF_STREAM (-1) for the regular + * end of transmission (with chunked encoding, MHD will then + * terminate the chunk and send any HTTP footers that might be + * present; without chunked encoding and given an unknown + * response size, MHD will simply close the connection; note + * that while returning #MHD_CONTENT_READER_END_OF_STREAM is not technically + * legal if a response size was specified, MHD accepts this + * and treats it just as #MHD_CONTENT_READER_END_WITH_ERROR; + * #MHD_CONTENT_READER_END_WITH_ERROR (-2) to indicate a server + * error generating the response; this will cause MHD to simply + * close the connection immediately. If a response size was + * given or if chunked encoding is in use, this will indicate + * an error to the client. Note, however, that if the client + * does not know a response size and chunked encoding is not in + * use, then clients will not be able to tell the difference between + * #MHD_CONTENT_READER_END_WITH_ERROR and #MHD_CONTENT_READER_END_OF_STREAM. + * This is not a limitation of MHD but rather of the HTTP protocol. + */ +typedef ssize_t +(*MHD_ContentReaderCallback) (void *cls, + uint64_t pos, + char *buf, + size_t max); + + +/** + * This method is called by libmicrohttpd if we + * are done with a content reader. It should + * be used to free resources associated with the + * content reader. + * + * @param cls closure + * @ingroup response + */ +typedef void +(*MHD_ContentReaderFreeCallback) (void *cls); + + +/** + * Iterator over key-value pairs where the value + * may be made available in increments and/or may + * not be zero-terminated. Used for processing + * POST data. + * + * @param cls user-specified closure + * @param kind type of the value, always #MHD_POSTDATA_KIND when called from MHD + * @param key 0-terminated key for the value, NULL if not known. This value + * is never NULL for url-encoded POST data. + * @param filename name of the uploaded file, NULL if not known + * @param content_type mime-type of the data, NULL if not known + * @param transfer_encoding encoding of the data, NULL if not known + * @param data pointer to @a size bytes of data at the + * specified offset + * @param off offset of data in the overall value + * @param size number of bytes in @a data available + * @return #MHD_YES to continue iterating, + * #MHD_NO to abort the iteration + */ +typedef enum MHD_Result +(*MHD_PostDataIterator)(void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size); + +/* **************** Daemon handling functions ***************** */ + +/** + * Start a webserver on the given port. + * + * @param flags combination of `enum MHD_FLAG` values + * @param port port to bind to (in host byte order), + * use '0' to bind to random free port, + * ignored if MHD_OPTION_SOCK_ADDR or + * MHD_OPTION_LISTEN_SOCKET is provided + * or MHD_USE_NO_LISTEN_SOCKET is specified + * @param apc callback to call to check which clients + * will be allowed to connect; you can pass NULL + * in which case connections from any IP will be + * accepted + * @param apc_cls extra argument to apc + * @param dh handler called for all requests (repeatedly) + * @param dh_cls extra argument to @a dh + * @param ap list of options (type-value pairs, + * terminated with #MHD_OPTION_END). + * @return NULL on error, handle to daemon on success + * @ingroup event + */ +_MHD_EXTERN struct MHD_Daemon * +MHD_start_daemon_va (unsigned int flags, + uint16_t port, + MHD_AcceptPolicyCallback apc, void *apc_cls, + MHD_AccessHandlerCallback dh, void *dh_cls, + va_list ap); + + +/** + * Start a webserver on the given port. Variadic version of + * #MHD_start_daemon_va. + * + * @param flags combination of `enum MHD_FLAG` values + * @param port port to bind to (in host byte order), + * use '0' to bind to random free port, + * ignored if MHD_OPTION_SOCK_ADDR or + * MHD_OPTION_LISTEN_SOCKET is provided + * or MHD_USE_NO_LISTEN_SOCKET is specified + * @param apc callback to call to check which clients + * will be allowed to connect; you can pass NULL + * in which case connections from any IP will be + * accepted + * @param apc_cls extra argument to apc + * @param dh handler called for all requests (repeatedly) + * @param dh_cls extra argument to @a dh + * @return NULL on error, handle to daemon on success + * @ingroup event + */ +_MHD_EXTERN struct MHD_Daemon * +MHD_start_daemon (unsigned int flags, + uint16_t port, + MHD_AcceptPolicyCallback apc, void *apc_cls, + MHD_AccessHandlerCallback dh, void *dh_cls, + ...); + + +/** + * Stop accepting connections from the listening socket. Allows + * clients to continue processing, but stops accepting new + * connections. Note that the caller is responsible for closing the + * returned socket; however, if MHD is run using threads (anything but + * "external" sockets polling mode), it must not be closed until AFTER + * #MHD_stop_daemon has been called (as it is theoretically possible + * that an existing thread is still using it). + * + * Note that some thread modes require the caller to have passed + * #MHD_USE_ITC when using this API. If this daemon is + * in one of those modes and this option was not given to + * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET. + * + * @param daemon daemon to stop accepting new connections for + * @return old listen socket on success, #MHD_INVALID_SOCKET if + * the daemon was already not listening anymore + * @ingroup specialized + */ +_MHD_EXTERN MHD_socket +MHD_quiesce_daemon (struct MHD_Daemon *daemon); + + +/** + * Shutdown an HTTP daemon. + * + * @param daemon daemon to stop + * @ingroup event + */ +_MHD_EXTERN void +MHD_stop_daemon (struct MHD_Daemon *daemon); + + +/** + * Add another client connection to the set of connections managed by + * MHD. This API is usually not needed (since MHD will accept inbound + * connections on the server socket). Use this API in special cases, + * for example if your HTTP server is behind NAT and needs to connect + * out to the HTTP client, or if you are building a proxy. + * + * If you use this API in conjunction with an "internal" socket polling, + * you must set the option #MHD_USE_ITC to ensure that the freshly added + * connection is immediately processed by MHD. + * + * The given client socket will be managed (and closed!) by MHD after + * this call and must no longer be used directly by the application + * afterwards. + * + * @param daemon daemon that manages the connection + * @param client_socket socket to manage (MHD will expect + * to receive an HTTP request from this socket next). + * @param addr IP address of the client + * @param addrlen number of bytes in @a addr + * @return #MHD_YES on success, #MHD_NO if this daemon could + * not handle the connection (i.e. `malloc()` failed, etc). + * The socket will be closed in any case; `errno` is + * set to indicate further details about the error. + * @ingroup specialized + */ +_MHD_EXTERN enum MHD_Result +MHD_add_connection (struct MHD_Daemon *daemon, + MHD_socket client_socket, + const struct sockaddr *addr, + socklen_t addrlen); + + +/** + * Obtain the `select()` sets for this daemon. + * Daemon's FDs will be added to fd_sets. To get only + * daemon FDs in fd_sets, call FD_ZERO for each fd_set + * before calling this function. FD_SETSIZE is assumed + * to be platform's default. + * + * This function should be called only when MHD is configured to + * use "external" sockets polling with 'select()' or with 'epoll'. + * In the latter case, it will only add the single 'epoll' file + * descriptor used by MHD to the sets. + * It's necessary to use #MHD_get_timeout() to get maximum timeout + * value for `select()`. Usage of `select()` with indefinite timeout + * (or timeout larger than returned by #MHD_get_timeout()) will + * violate MHD API and may results in pending unprocessed data. + * + * This function must be called only for daemon started + * without #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @return #MHD_YES on success, #MHD_NO if this + * daemon was not started with the right + * options for this call or any FD didn't + * fit fd_set. + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_get_fdset (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd); + + +/** + * Obtain the `select()` sets for this daemon. + * Daemon's FDs will be added to fd_sets. To get only + * daemon FDs in fd_sets, call FD_ZERO for each fd_set + * before calling this function. + * + * Passing custom FD_SETSIZE as @a fd_setsize allow usage of + * larger/smaller than platform's default fd_sets. + * + * This function should be called only when MHD is configured to + * use "external" sockets polling with 'select()' or with 'epoll'. + * In the latter case, it will only add the single 'epoll' file + * descriptor used by MHD to the sets. + * It's necessary to use #MHD_get_timeout() to get maximum timeout + * value for `select()`. Usage of `select()` with indefinite timeout + * (or timeout larger than returned by #MHD_get_timeout()) will + * violate MHD API and may results in pending unprocessed data. + * + * This function must be called only for daemon started + * without #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @param fd_setsize value of FD_SETSIZE + * @return #MHD_YES on success, #MHD_NO if this + * daemon was not started with the right + * options for this call or any FD didn't + * fit fd_set. + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_get_fdset2 (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd, + unsigned int fd_setsize); + + +/** + * Obtain the `select()` sets for this daemon. + * Daemon's FDs will be added to fd_sets. To get only + * daemon FDs in fd_sets, call FD_ZERO for each fd_set + * before calling this function. Size of fd_set is + * determined by current value of FD_SETSIZE. + * + * This function should be called only when MHD is configured to + * use "external" sockets polling with 'select()' or with 'epoll'. + * In the latter case, it will only add the single 'epoll' file + * descriptor used by MHD to the sets. + * It's necessary to use #MHD_get_timeout() to get maximum timeout + * value for `select()`. Usage of `select()` with indefinite timeout + * (or timeout larger than returned by #MHD_get_timeout()) will + * violate MHD API and may results in pending unprocessed data. + * + * This function must be called only for daemon started + * without #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @return #MHD_YES on success, #MHD_NO if this + * daemon was not started with the right + * options for this call or any FD didn't + * fit fd_set. + * @ingroup event + */ +#define MHD_get_fdset(daemon,read_fd_set,write_fd_set,except_fd_set,max_fd) \ + MHD_get_fdset2 ((daemon),(read_fd_set),(write_fd_set),(except_fd_set), \ + (max_fd),FD_SETSIZE) + + +/** + * Obtain timeout value for polling function for this daemon. + * + * This function set value to the amount of milliseconds for which polling + * function (`select()`, `poll()` or epoll) should at most block, not the + * timeout value set for connections. + * + * Any "external" sockets polling function must be called with the timeout + * value provided by this function. Smaller timeout values can be used for + * polling function if it is required for any reason, but using larger + * timeout value or no timeout (indefinite timeout) when this function + * return #MHD_YES will break MHD processing logic and result in "hung" + * connections with data pending in network buffers and other problems. + * + * It is important to always use this function (or #MHD_get_timeout64(), + * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external" + * polling is used. + * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select()) + * must be called right after return from polling function, regardless of + * the states of MHD FDs. + * + * In practice, if #MHD_YES is returned then #MHD_run() (or + * #MHD_run_from_select()) must be called not later than @a timeout + * millisecond even if no activity is detected on sockets by sockets + * polling function. + * + * @param daemon daemon to query for timeout + * @param[out] timeout set to the timeout (in milliseconds) + * @return #MHD_YES on success, #MHD_NO if timeouts are + * not used and no data processing is pending. + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_get_timeout (struct MHD_Daemon *daemon, + MHD_UNSIGNED_LONG_LONG *timeout); + + +/** + * Free the memory allocated by MHD. + * + * If any MHD function explicitly mentions that returned pointer must be + * freed by this function, then no other method must be used to free + * the memory. + * + * @param ptr the pointer to free. + * @sa #MHD_digest_auth_get_username(), #MHD_basic_auth_get_username_password3() + * @sa #MHD_basic_auth_get_username_password() + * @note Available since #MHD_VERSION 0x00095600 + * @ingroup specialized + */ +_MHD_EXTERN void +MHD_free (void *ptr); + +/** + * Obtain timeout value for external polling function for this daemon. + * + * This function set value to the amount of milliseconds for which polling + * function (`select()`, `poll()` or epoll) should at most block, not the + * timeout value set for connections. + * + * Any "external" sockets polling function must be called with the timeout + * value provided by this function. Smaller timeout values can be used for + * polling function if it is required for any reason, but using larger + * timeout value or no timeout (indefinite timeout) when this function + * return #MHD_YES will break MHD processing logic and result in "hung" + * connections with data pending in network buffers and other problems. + * + * It is important to always use this function (or #MHD_get_timeout(), + * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external" + * polling is used. + * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select()) + * must be called right after return from polling function, regardless of + * the states of MHD FDs. + * + * In practice, if #MHD_YES is returned then #MHD_run() (or + * #MHD_run_from_select()) must be called not later than @a timeout + * millisecond even if no activity is detected on sockets by sockets + * polling function. + * + * @param daemon daemon to query for timeout + * @param[out] timeout64 the pointer to the variable to be set to the + * timeout (in milliseconds) + * @return #MHD_YES if timeout value has been set, + * #MHD_NO if timeouts are not used and no data processing is pending. + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_get_timeout64 (struct MHD_Daemon *daemon, + uint64_t *timeout); + + +/** + * Obtain timeout value for external polling function for this daemon. + * + * This function set value to the amount of milliseconds for which polling + * function (`select()`, `poll()` or epoll) should at most block, not the + * timeout value set for connections. + * + * Any "external" sockets polling function must be called with the timeout + * value provided by this function (if returned value is non-negative). + * Smaller timeout values can be used for polling function if it is required + * for any reason, but using larger timeout value or no timeout (indefinite + * timeout) when this function returns non-negative value will break MHD + * processing logic and result in "hung" connections with data pending in + * network buffers and other problems. + * + * It is important to always use this function (or #MHD_get_timeout(), + * #MHD_get_timeout64(), #MHD_get_timeout_i() functions) when "external" + * polling is used. + * If this function returns non-negative value then #MHD_run() (or + * #MHD_run_from_select()) must be called right after return from polling + * function, regardless of the states of MHD FDs. + * + * In practice, if zero or positive value is returned then #MHD_run() (or + * #MHD_run_from_select()) must be called not later than returned amount of + * millisecond even if no activity is detected on sockets by sockets + * polling function. + * + * @param daemon the daemon to query for timeout + * @return -1 if connections' timeouts are not set and no data processing + * is pending, so external polling function may wait for sockets + * activity for indefinite amount of time, + * otherwise returned value is the the maximum amount of millisecond + * that external polling function must wait for the activity of FDs. + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup event + */ +_MHD_EXTERN int64_t +MHD_get_timeout64s (struct MHD_Daemon *daemon); + + +/** + * Obtain timeout value for external polling function for this daemon. + * + * This function set value to the amount of milliseconds for which polling + * function (`select()`, `poll()` or epoll) should at most block, not the + * timeout value set for connections. + * + * Any "external" sockets polling function must be called with the timeout + * value provided by this function (if returned value is non-negative). + * Smaller timeout values can be used for polling function if it is required + * for any reason, but using larger timeout value or no timeout (indefinite + * timeout) when this function returns non-negative value will break MHD + * processing logic and result in "hung" connections with data pending in + * network buffers and other problems. + * + * It is important to always use this function (or #MHD_get_timeout(), + * #MHD_get_timeout64(), #MHD_get_timeout64s() functions) when "external" + * polling is used. + * If this function returns non-negative value then #MHD_run() (or + * #MHD_run_from_select()) must be called right after return from polling + * function, regardless of the states of MHD FDs. + * + * In practice, if zero or positive value is returned then #MHD_run() (or + * #MHD_run_from_select()) must be called not later than returned amount of + * millisecond even if no activity is detected on sockets by sockets + * polling function. + * + * @param daemon the daemon to query for timeout + * @return -1 if connections' timeouts are not set and no data processing + * is pending, so external polling function may wait for sockets + * activity for indefinite amount of time, + * otherwise returned value is the the maximum amount of millisecond + * (capped at INT_MAX) that external polling function must wait + * for the activity of FDs. + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup event + */ +_MHD_EXTERN int +MHD_get_timeout_i (struct MHD_Daemon *daemon); + + +/** + * Run webserver operations (without blocking unless in client callbacks). + * + * This method should be called by clients in combination with + * #MHD_get_fdset() (or #MHD_get_daemon_info() with MHD_DAEMON_INFO_EPOLL_FD + * if epoll is used) and #MHD_get_timeout() if the client-controlled + * connection polling method is used (i.e. daemon was started without + * #MHD_USE_INTERNAL_POLLING_THREAD flag). + * + * This function is a convenience method, which is useful if the + * fd_sets from #MHD_get_fdset were not directly passed to `select()`; + * with this function, MHD will internally do the appropriate `select()` + * call itself again. While it is acceptable to call #MHD_run (if + * #MHD_USE_INTERNAL_POLLING_THREAD is not set) at any moment, you should + * call #MHD_run_from_select() if performance is important (as it saves an + * expensive call to `select()`). + * + * If #MHD_get_timeout() returned #MHD_YES, than this function must be called + * right after polling function returns regardless of detected activity on + * the daemon's FDs. + * + * @param daemon daemon to run + * @return #MHD_YES on success, #MHD_NO if this + * daemon was not started with the right + * options for this call. + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_run (struct MHD_Daemon *daemon); + + +/** + * Run websever operation with possible blocking. + * + * This function does the following: waits for any network event not more than + * specified number of milliseconds, processes all incoming and outgoing data, + * processes new connections, processes any timed-out connection, and does + * other things required to run webserver. + * Once all connections are processed, function returns. + * + * This function is useful for quick and simple (lazy) webserver implementation + * if application needs to run a single thread only and does not have any other + * network activity. + * + * This function calls MHD_get_timeout() internally and use returned value as + * maximum wait time if it less than value of @a millisec parameter. + * + * It is expected that the "external" socket polling function is not used in + * conjunction with this function unless the @a millisec is set to zero. + * + * @param daemon the daemon to run + * @param millisec the maximum time in milliseconds to wait for network and + * other events. Note: there is no guarantee that function + * blocks for the specified amount of time. The real processing + * time can be shorter (if some data or connection timeout + * comes earlier) or longer (if data processing requires more + * time, especially in user callbacks). + * If set to '0' then function does not block and processes + * only already available data (if any). + * If set to '-1' then function waits for events + * indefinitely (blocks until next network activity or + * connection timeout). + * @return #MHD_YES on success, #MHD_NO if this + * daemon was not started with the right + * options for this call or some serious + * unrecoverable error occurs. + * @note Available since #MHD_VERSION 0x00097206 + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_run_wait (struct MHD_Daemon *daemon, + int32_t millisec); + + +/** + * Run webserver operations. This method should be called by clients + * in combination with #MHD_get_fdset and #MHD_get_timeout() if the + * client-controlled select method is used. + * + * You can use this function instead of #MHD_run if you called + * `select()` on the result from #MHD_get_fdset. File descriptors in + * the sets that are not controlled by MHD will be ignored. Calling + * this function instead of #MHD_run is more efficient as MHD will + * not have to call `select()` again to determine which operations are + * ready. + * + * If #MHD_get_timeout() returned #MHD_YES, than this function must be + * called right after `select()` returns regardless of detected activity + * on the daemon's FDs. + * + * This function cannot be used with daemon started with + * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to run select loop for + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @return #MHD_NO on serious errors, #MHD_YES on success + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_run_from_select (struct MHD_Daemon *daemon, + const fd_set *read_fd_set, + const fd_set *write_fd_set, + const fd_set *except_fd_set); + + +/** + * Run webserver operations. This method should be called by clients + * in combination with #MHD_get_fdset and #MHD_get_timeout() if the + * client-controlled select method is used. + * This function specifies FD_SETSIZE used when provided fd_sets were + * created. It is important on platforms where FD_SETSIZE can be + * overridden. + * + * You can use this function instead of #MHD_run if you called + * 'select()' on the result from #MHD_get_fdset2(). File descriptors in + * the sets that are not controlled by MHD will be ignored. Calling + * this function instead of #MHD_run() is more efficient as MHD will + * not have to call 'select()' again to determine which operations are + * ready. + * + * If #MHD_get_timeout() returned #MHD_YES, than this function must be + * called right after 'select()' returns regardless of detected activity + * on the daemon's FDs. + * + * This function cannot be used with daemon started with + * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon the daemon to run select loop for + * @param read_fd_set the read set + * @param write_fd_set the write set + * @param except_fd_set the except set + * @param fd_setsize the value of FD_SETSIZE + * @return #MHD_NO on serious errors, #MHD_YES on success + * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE + * @ingroup event + */ +_MHD_EXTERN enum MHD_Result +MHD_run_from_select2 (struct MHD_Daemon *daemon, + const fd_set *read_fd_set, + const fd_set *write_fd_set, + const fd_set *except_fd_set, + unsigned int fd_setsize); + + +/** + * Run webserver operations. This method should be called by clients + * in combination with #MHD_get_fdset and #MHD_get_timeout() if the + * client-controlled select method is used. + * This macro automatically substitutes current FD_SETSIZE value. + * It is important on platforms where FD_SETSIZE can be overridden. + * + * You can use this function instead of #MHD_run if you called + * 'select()' on the result from #MHD_get_fdset2(). File descriptors in + * the sets that are not controlled by MHD will be ignored. Calling + * this function instead of #MHD_run() is more efficient as MHD will + * not have to call 'select()' again to determine which operations are + * ready. + * + * If #MHD_get_timeout() returned #MHD_YES, than this function must be + * called right after 'select()' returns regardless of detected activity + * on the daemon's FDs. + * + * This function cannot be used with daemon started with + * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon the daemon to run select loop for + * @param read_fd_set the read set + * @param write_fd_set the write set + * @param except_fd_set the except set + * @param fd_setsize the value of FD_SETSIZE + * @return #MHD_NO on serious errors, #MHD_YES on success + * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE + * @ingroup event + */ +#define MHD_run_from_select(d,r,w,e) \ + MHD_run_from_select2((d),(r),(w),(e),(unsigned int)(FD_SETSIZE)) + +/* **************** Connection handling functions ***************** */ + +/** + * Get all of the headers from the request. + * + * @param connection connection to get values from + * @param kind types of values to iterate over, can be a bitmask + * @param iterator callback to call on each header; + * may be NULL (then just count headers) + * @param iterator_cls extra argument to @a iterator + * @return number of entries iterated over, + * -1 if connection is NULL. + * @ingroup request + */ +_MHD_EXTERN int +MHD_get_connection_values (struct MHD_Connection *connection, + enum MHD_ValueKind kind, + MHD_KeyValueIterator iterator, + void *iterator_cls); + + +/** + * Get all of the headers from the request. + * + * @param connection connection to get values from + * @param kind types of values to iterate over, can be a bitmask + * @param iterator callback to call on each header; + * may be NULL (then just count headers) + * @param iterator_cls extra argument to @a iterator + * @return number of entries iterated over, + * -1 if connection is NULL. + * @note Available since #MHD_VERSION 0x00096400 + * @ingroup request + */ +_MHD_EXTERN int +MHD_get_connection_values_n (struct MHD_Connection *connection, + enum MHD_ValueKind kind, + MHD_KeyValueIteratorN iterator, + void *iterator_cls); + + +/** + * This function can be used to add an entry to the HTTP headers of a + * connection (so that the #MHD_get_connection_values function will + * return them -- and the `struct MHD_PostProcessor` will also see + * them). This maybe required in certain situations (see Mantis + * #1399) where (broken) HTTP implementations fail to supply values + * needed by the post processor (or other parts of the application). + * + * This function MUST only be called from within the + * #MHD_AccessHandlerCallback (otherwise, access maybe improperly + * synchronized). Furthermore, the client must guarantee that the key + * and value arguments are 0-terminated strings that are NOT freed + * until the connection is closed. (The easiest way to do this is by + * passing only arguments to permanently allocated strings.). + * + * @param connection the connection for which a + * value should be set + * @param kind kind of the value + * @param key key for the value + * @param value the value itself + * @return #MHD_NO if the operation could not be + * performed due to insufficient memory; + * #MHD_YES on success + * @ingroup request + */ +_MHD_EXTERN enum MHD_Result +MHD_set_connection_value (struct MHD_Connection *connection, + enum MHD_ValueKind kind, + const char *key, + const char *value); + + +/** + * This function can be used to add an arbitrary entry to connection. + * This function could add entry with binary zero, which is allowed + * for #MHD_GET_ARGUMENT_KIND. For other kind on entries it is + * recommended to use #MHD_set_connection_value. + * + * This function MUST only be called from within the + * #MHD_AccessHandlerCallback (otherwise, access maybe improperly + * synchronized). Furthermore, the client must guarantee that the key + * and value arguments are 0-terminated strings that are NOT freed + * until the connection is closed. (The easiest way to do this is by + * passing only arguments to permanently allocated strings.). + * + * @param connection the connection for which a + * value should be set + * @param kind kind of the value + * @param key key for the value, must be zero-terminated + * @param key_size number of bytes in @a key (excluding 0-terminator) + * @param value the value itself, must be zero-terminated + * @param value_size number of bytes in @a value (excluding 0-terminator) + * @return #MHD_NO if the operation could not be + * performed due to insufficient memory; + * #MHD_YES on success + * @note Available since #MHD_VERSION 0x00096400 + * @ingroup request + */ +_MHD_EXTERN enum MHD_Result +MHD_set_connection_value_n (struct MHD_Connection *connection, + enum MHD_ValueKind kind, + const char *key, + size_t key_size, + const char *value, + size_t value_size); + + +/** + * Sets the global error handler to a different implementation. + * + * @a cb will only be called in the case of typically fatal, serious internal + * consistency issues or serious system failures like failed lock of mutex. + * + * These issues should only arise in the case of serious memory corruption or + * similar problems with the architecture, there is no safe way to continue + * even for closing of the application. + * + * The default implementation that is used if no panic function is set simply + * prints an error message and calls `abort()`. + * Alternative implementations might call `exit()` or other similar functions. + * + * @param cb new error handler or NULL to use default handler + * @param cls passed to @a cb + * @ingroup logging + */ +_MHD_EXTERN void +MHD_set_panic_func (MHD_PanicCallback cb, void *cls); + + +/** + * Process escape sequences ('%HH') Updates val in place; the + * result cannot be larger than the input. + * The result is still be 0-terminated. + * + * @param val value to unescape (modified in the process) + * @return length of the resulting val (`strlen(val)` may be + * shorter afterwards due to elimination of escape sequences) + */ +_MHD_EXTERN size_t +MHD_http_unescape (char *val); + + +/** + * Get a particular header value. If multiple + * values match the kind, return any one of them. + * + * @param connection connection to get values from + * @param kind what kind of value are we looking for + * @param key the header to look for, NULL to lookup 'trailing' value without a key + * @return NULL if no such item was found + * @ingroup request + */ +_MHD_EXTERN const char * +MHD_lookup_connection_value (struct MHD_Connection *connection, + enum MHD_ValueKind kind, + const char *key); + + +/** + * Get a particular header value. If multiple + * values match the kind, return any one of them. + * @note Since MHD_VERSION 0x00096304 + * + * @param connection connection to get values from + * @param kind what kind of value are we looking for + * @param key the header to look for, NULL to lookup 'trailing' value without a key + * @param key_size the length of @a key in bytes + * @param[out] value_ptr the pointer to variable, which will be set to found value, + * will not be updated if key not found, + * could be NULL to just check for presence of @a key + * @param[out] value_size_ptr the pointer variable, which will set to found value, + * will not be updated if key not found, + * could be NULL + * @return #MHD_YES if key is found, + * #MHD_NO otherwise. + * @ingroup request + */ +_MHD_EXTERN enum MHD_Result +MHD_lookup_connection_value_n (struct MHD_Connection *connection, + enum MHD_ValueKind kind, + const char *key, + size_t key_size, + const char **value_ptr, + size_t *value_size_ptr); + + +/** + * Queue a response to be transmitted to the client (as soon as + * possible but after #MHD_AccessHandlerCallback returns). + * + * For any active connection this function must be called + * only by #MHD_AccessHandlerCallback callback. + * + * For suspended connection this function can be called at any moment (this + * behaviour is deprecated and will be removed!). Response will be sent + * as soon as connection is resumed. + * + * For single thread environment, when MHD is used in "external polling" mode + * (without MHD_USE_SELECT_INTERNALLY) this function can be called any + * time (this behaviour is deprecated and will be removed!). + * + * If HTTP specifications require use no body in reply, like @a status_code with + * value 1xx, the response body is automatically not sent even if it is present + * in the response. No "Content-Length" or "Transfer-Encoding" headers are + * generated and added. + * + * When the response is used to respond HEAD request or used with @a status_code + * #MHD_HTTP_NOT_MODIFIED, then response body is not sent, but "Content-Length" + * header is added automatically based the size of the body in the response. + * If body size it set to #MHD_SIZE_UNKNOWN or chunked encoding is enforced + * then "Transfer-Encoding: chunked" header (for HTTP/1.1 only) is added instead + * of "Content-Length" header. For example, if response with zero-size body is + * used for HEAD request, then "Content-Length: 0" is added automatically to + * reply headers. + * @sa #MHD_RF_HEAD_ONLY_RESPONSE + * + * In situations, where reply body is required, like answer for the GET request + * with @a status_code #MHD_HTTP_OK, headers "Content-Length" (for known body + * size) or "Transfer-Encoding: chunked" (for #MHD_SIZE_UNKNOWN with HTTP/1.1) + * are added automatically. + * In practice, the same response object can be used to respond to both HEAD and + * GET requests. + * + * @param connection the connection identifying the client + * @param status_code HTTP status code (i.e. #MHD_HTTP_OK) + * @param response response to transmit, the NULL is tolerated + * @return #MHD_NO on error (reply already sent, response is NULL), + * #MHD_YES on success or if message has been queued + * @ingroup response + * @sa #MHD_AccessHandlerCallback + */ +_MHD_EXTERN enum MHD_Result +MHD_queue_response (struct MHD_Connection *connection, + unsigned int status_code, + struct MHD_Response *response); + + +/** + * Suspend handling of network data for a given connection. + * This can be used to dequeue a connection from MHD's event loop + * (not applicable to thread-per-connection!) for a while. + * + * If you use this API in conjunction with an "internal" socket polling, + * you must set the option #MHD_USE_ITC to ensure that a resumed + * connection is immediately processed by MHD. + * + * Suspended connections continue to count against the total number of + * connections allowed (per daemon, as well as per IP, if such limits + * are set). Suspended connections will NOT time out; timeouts will + * restart when the connection handling is resumed. While a + * connection is suspended, MHD will not detect disconnects by the + * client. + * + * The only safe way to call this function is to call it from the + * #MHD_AccessHandlerCallback or #MHD_ContentReaderCallback. + * + * Finally, it is an API violation to call #MHD_stop_daemon while + * having suspended connections (this will at least create memory and + * socket leaks or lead to undefined behavior). You must explicitly + * resume all connections before stopping the daemon. + * + * @param connection the connection to suspend + * + * @sa #MHD_AccessHandlerCallback + */ +_MHD_EXTERN void +MHD_suspend_connection (struct MHD_Connection *connection); + + +/** + * Resume handling of network data for suspended connection. It is + * safe to resume a suspended connection at any time. Calling this + * function on a connection that was not previously suspended will + * result in undefined behavior. + * + * If you are using this function in "external" sockets polling mode, you must + * make sure to run #MHD_run() and #MHD_get_timeout() afterwards (before + * again calling #MHD_get_fdset()), as otherwise the change may not be + * reflected in the set returned by #MHD_get_fdset() and you may end up + * with a connection that is stuck until the next network activity. + * + * @param connection the connection to resume + */ +_MHD_EXTERN void +MHD_resume_connection (struct MHD_Connection *connection); + + +/* **************** Response manipulation functions ***************** */ + + +/** + * Flags for special handling of responses. + */ +enum MHD_ResponseFlags +{ + /** + * Default: no special flags. + * @note Available since #MHD_VERSION 0x00093701 + */ + MHD_RF_NONE = 0, + + /** + * Only respond in conservative (dumb) HTTP/1.0-compatible mode. + * Response still use HTTP/1.1 version in header, but always close + * the connection after sending the response and do not use chunked + * encoding for the response. + * You can also set the #MHD_RF_HTTP_1_0_SERVER flag to force + * HTTP/1.0 version in the response. + * Responses are still compatible with HTTP/1.1. + * This option can be used to communicate with some broken client, which + * does not implement HTTP/1.1 features, but advertises HTTP/1.1 support. + * @note Available since #MHD_VERSION 0x00097308 + */ + MHD_RF_HTTP_1_0_COMPATIBLE_STRICT = 1 << 0, + /** + * The same as #MHD_RF_HTTP_1_0_COMPATIBLE_STRICT + * @note Available since #MHD_VERSION 0x00093701 + */ + MHD_RF_HTTP_VERSION_1_0_ONLY = 1 << 0, + + /** + * Only respond in HTTP 1.0-mode. + * Contrary to the #MHD_RF_HTTP_1_0_COMPATIBLE_STRICT flag, the response's + * HTTP version will always be set to 1.0 and keep-alive connections + * will be used if explicitly requested by the client. + * The "Connection:" header will be added for both "close" and "keep-alive" + * connections. + * Chunked encoding will not be used for the response. + * Due to backward compatibility, responses still can be used with + * HTTP/1.1 clients. + * This option can be used to emulate HTTP/1.0 server (for response part + * only as chunked encoding in requests (if any) is processed by MHD). + * @note Available since #MHD_VERSION 0x00097308 + */ + MHD_RF_HTTP_1_0_SERVER = 1 << 1, + /** + * The same as #MHD_RF_HTTP_1_0_SERVER + * @note Available since #MHD_VERSION 0x00096000 + */ + MHD_RF_HTTP_VERSION_1_0_RESPONSE = 1 << 1, + + /** + * Disable sanity check preventing clients from manually + * setting the HTTP content length option. + * Allow to set several "Content-Length" headers. These headers will + * be used even with replies without body. + * @note Available since #MHD_VERSION 0x00096702 + */ + MHD_RF_INSANITY_HEADER_CONTENT_LENGTH = 1 << 2, + + /** + * Enable sending of "Connection: keep-alive" header even for + * HTTP/1.1 clients when "Keep-Alive" connection is used. + * Disabled by default for HTTP/1.1 clients as per RFC. + * @note Available since #MHD_VERSION 0x00097310 + */ + MHD_RF_SEND_KEEP_ALIVE_HEADER = 1 << 3, + + /** + * Enable special processing of the response as body-less (with undefined + * body size). No automatic "Content-Length" or "Transfer-Encoding: chunked" + * headers are added when the response is used with #MHD_HTTP_NOT_MODIFIED + * code or to respond to HEAD request. + * The flag also allow to set arbitrary "Content-Length" by + * MHD_add_response_header() function. + * This flag value can be used only with responses created without body + * (zero-size body). + * Responses with this flag enabled cannot be used in situations where + * reply body must be sent to the client. + * This flag is primarily intended to be used when automatic "Content-Length" + * header is undesirable in response to HEAD requests. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_RF_HEAD_ONLY_RESPONSE = 1 << 4 +} _MHD_FIXED_FLAGS_ENUM; + + +/** + * MHD options (for future extensions). + */ +enum MHD_ResponseOptions +{ + /** + * End of the list of options. + */ + MHD_RO_END = 0 +} _MHD_FIXED_ENUM; + + +/** + * Set special flags and options for a response. + * + * @param response the response to modify + * @param flags to set for the response + * @param ... #MHD_RO_END terminated list of options + * @return #MHD_YES on success, #MHD_NO on error + */ +_MHD_EXTERN enum MHD_Result +MHD_set_response_options (struct MHD_Response *response, + enum MHD_ResponseFlags flags, + ...); + + +/** + * Create a response object. + * The response object can be extended with header information and then be used + * any number of times. + * + * If response object is used to answer HEAD request then the body of the + * response is not used, while all headers (including automatic headers) are + * used. + * + * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown + * @param block_size preferred block size for querying crc (advisory only, + * MHD may still call @a crc using smaller chunks); this + * is essentially the buffer size used for IO, clients + * should pick a value that is appropriate for IO and + * memory performance requirements + * @param crc callback to use to obtain response data + * @param crc_cls extra argument to @a crc + * @param crfc callback to call to free @a crc_cls resources + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_callback (uint64_t size, + size_t block_size, + MHD_ContentReaderCallback crc, void *crc_cls, + MHD_ContentReaderFreeCallback crfc); + + +/** + * Create a response object. + * The response object can be extended with header information and then be used + * any number of times. + * + * If response object is used to answer HEAD request then the body of the + * response is not used, while all headers (including automatic headers) are + * used. + * + * @param size size of the @a data portion of the response + * @param data the data itself + * @param must_free libmicrohttpd should free data when done + * @param must_copy libmicrohttpd must make a copy of @a data + * right away, the data may be released anytime after + * this call returns + * @return NULL on error (i.e. invalid arguments, out of memory) + * @deprecated use #MHD_create_response_from_buffer instead + * @ingroup response + */ +_MHD_DEPR_FUNC ("MHD_create_response_from_data() is deprecated, " \ + "use MHD_create_response_from_buffer()") \ + _MHD_EXTERN struct MHD_Response * +MHD_create_response_from_data (size_t size, + void *data, + int must_free, + int must_copy); + + +/** + * Specification for how MHD should treat the memory buffer + * given for the response. + * @ingroup response + */ +enum MHD_ResponseMemoryMode +{ + + /** + * Buffer is a persistent (static/global) buffer that won't change + * for at least the lifetime of the response, MHD should just use + * it, not free it, not copy it, just keep an alias to it. + * @ingroup response + */ + MHD_RESPMEM_PERSISTENT, + + /** + * Buffer is heap-allocated with `malloc()` (or equivalent) and + * should be freed by MHD after processing the response has + * concluded (response reference counter reaches zero). + * The more portable way to automatically free the buffer is function + * MHD_create_response_from_buffer_with_free_callback() with '&free' as + * crfc parameter as it does not require to use the same runtime library. + * @warning It is critical to make sure that the same C-runtime library + * is used by both application and MHD (especially + * important for W32). + * @ingroup response + */ + MHD_RESPMEM_MUST_FREE, + + /** + * Buffer is in transient memory, but not on the heap (for example, + * on the stack or non-`malloc()` allocated) and only valid during the + * call to #MHD_create_response_from_buffer. MHD must make its + * own private copy of the data for processing. + * @ingroup response + */ + MHD_RESPMEM_MUST_COPY + +} _MHD_FIXED_ENUM; + + +/** + * Create a response object with the content of provided buffer used as + * the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size size of the data portion of the response + * @param buffer size bytes containing the response's data portion + * @param mode flags for buffer management + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_buffer (size_t size, + void *buffer, + enum MHD_ResponseMemoryMode mode); + + +/** + * Create a response object with the content of provided statically allocated + * buffer used as the response body. + * + * The buffer must be valid for the lifetime of the response. The easiest way + * to achieve this is to use a statically allocated buffer. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size the size of the data in @a buffer, can be zero + * @param buffer the buffer with the data for the response body, can be NULL + * if @a size is zero + * @return NULL on error (i.e. invalid arguments, out of memory) + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_buffer_static (size_t size, + const void *buffer); + + +/** + * Create a response object with the content of provided temporal buffer + * used as the response body. + * + * An internal copy of the buffer will be made automatically, so buffer have + * to be valid only during the call of this function (as a typical example: + * buffer is a local (non-static) array). + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size the size of the data in @a buffer, can be zero + * @param buffer the buffer with the data for the response body, can be NULL + * if @a size is zero + * @return NULL on error (i.e. invalid arguments, out of memory) + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_buffer_copy (size_t size, + const void *buffer); + + +/** + * Create a response object with the content of provided buffer used as + * the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size size of the data portion of the response + * @param buffer size bytes containing the response's data portion + * @param crfc function to call to free the @a buffer + * @return NULL on error (i.e. invalid arguments, out of memory) + * @note Available since #MHD_VERSION 0x00096000 + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_buffer_with_free_callback (size_t size, + void *buffer, + MHD_ContentReaderFreeCallback + crfc); + + +/** + * Create a response object with the content of provided buffer used as + * the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size size of the data portion of the response + * @param buffer size bytes containing the response's data portion + * @param crfc function to call to cleanup, if set to NULL then callback + * is not called + * @param crfc_cls an argument for @a crfc + * @return NULL on error (i.e. invalid arguments, out of memory) + * @note Available since #MHD_VERSION 0x00097302 + * @note 'const' qualifier is used for @a buffer since #MHD_VERSION 0x00097701 + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_buffer_with_free_callback_cls (size_t size, + const void *buffer, + MHD_ContentReaderFreeCallback + crfc, + void *crfc_cls); + + +/** + * Create a response object with the content of provided file used as + * the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size size of the data portion of the response + * @param fd file descriptor referring to a file on disk with the + * data; will be closed when response is destroyed; + * fd should be in 'blocking' mode + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_fd (size_t size, + int fd); + + +/** + * Create a response object with the response body created by reading + * the provided pipe. + * + * The response object can be extended with header information and + * then be used ONLY ONCE. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param fd file descriptor referring to a read-end of a pipe with the + * data; will be closed when response is destroyed; + * fd should be in 'blocking' mode + * @return NULL on error (i.e. invalid arguments, out of memory) + * @note Available since #MHD_VERSION 0x00097102 + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_pipe (int fd); + + +/** + * Create a response object with the content of provided file used as + * the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size size of the data portion of the response; + * sizes larger than 2 GiB may be not supported by OS or + * MHD build; see ::MHD_FEATURE_LARGE_FILE + * @param fd file descriptor referring to a file on disk with the + * data; will be closed when response is destroyed; + * fd should be in 'blocking' mode + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_fd64 (uint64_t size, + int fd); + + +/** + * Create a response object with the content of provided file with + * specified offset used as the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size size of the data portion of the response + * @param fd file descriptor referring to a file on disk with the + * data; will be closed when response is destroyed; + * fd should be in 'blocking' mode + * @param offset offset to start reading from in the file; + * Be careful! `off_t` may have been compiled to be a + * 64-bit variable for MHD, in which case your application + * also has to be compiled using the same options! Read + * the MHD manual for more details. + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_DEPR_FUNC ("Function MHD_create_response_from_fd_at_offset() is " \ + "deprecated, use MHD_create_response_from_fd_at_offset64()") \ + _MHD_EXTERN struct MHD_Response * +MHD_create_response_from_fd_at_offset (size_t size, + int fd, + off_t offset); + +#if ! defined(_MHD_NO_DEPR_IN_MACRO) || defined(_MHD_NO_DEPR_FUNC) +/* Substitute MHD_create_response_from_fd_at_offset64() instead of MHD_create_response_from_fd_at_offset() + to minimize potential problems with different off_t sizes */ +#define MHD_create_response_from_fd_at_offset(size,fd,offset) \ + _MHD_DEPR_IN_MACRO ( \ + "Usage of MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()") \ + MHD_create_response_from_fd_at_offset64 ((size),(fd),(offset)) +#endif /* !_MHD_NO_DEPR_IN_MACRO || _MHD_NO_DEPR_FUNC */ + + +/** + * Create a response object with the content of provided file with + * specified offset used as the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param size size of the data portion of the response; + * sizes larger than 2 GiB may be not supported by OS or + * MHD build; see ::MHD_FEATURE_LARGE_FILE + * @param fd file descriptor referring to a file on disk with the + * data; will be closed when response is destroyed; + * fd should be in 'blocking' mode + * @param offset offset to start reading from in the file; + * reading file beyond 2 GiB may be not supported by OS or + * MHD build; see ::MHD_FEATURE_LARGE_FILE + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_fd_at_offset64 (uint64_t size, + int fd, + uint64_t offset); + + +/** + * Create a response object with an array of memory buffers + * used as the response body. + * + * The response object can be extended with header information and then + * be used any number of times. + * + * If response object is used to answer HEAD request then the body + * of the response is not used, while all headers (including automatic + * headers) are used. + * + * @param iov the array for response data buffers, an internal copy of this + * will be made + * @param iovcnt the number of elements in @a iov + * @param free_cb the callback to clean up any data associated with @a iov when + * the response is destroyed. + * @param cls the argument passed to @a free_cb + * @return NULL on error (i.e. invalid arguments, out of memory) + * @note Available since #MHD_VERSION 0x00097204 + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_from_iovec (const struct MHD_IoVec *iov, + unsigned int iovcnt, + MHD_ContentReaderFreeCallback free_cb, + void *cls); + + +/** + * Create a response object with empty (zero size) body. + * + * The response object can be extended with header information and then be used + * any number of times. + * + * This function is a faster equivalent of #MHD_create_response_from_buffer call + * with zero size combined with call of #MHD_set_response_options. + * + * @param flags the flags for the new response object + * @return NULL on error (i.e. invalid arguments, out of memory), + * the pointer to the created response object otherwise + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_empty (enum MHD_ResponseFlags flags); + + +/** + * Enumeration for actions MHD should perform on the underlying socket + * of the upgrade. This API is not finalized, and in particular + * the final set of actions is yet to be decided. This is just an + * idea for what we might want. + */ +enum MHD_UpgradeAction +{ + + /** + * Close the socket, the application is done with it. + * + * Takes no extra arguments. + */ + MHD_UPGRADE_ACTION_CLOSE = 0, + + /** + * Enable CORKing on the underlying socket. + */ + MHD_UPGRADE_ACTION_CORK_ON = 1, + + /** + * Disable CORKing on the underlying socket. + */ + MHD_UPGRADE_ACTION_CORK_OFF = 2 + +} _MHD_FIXED_ENUM; + + +/** + * Handle given to the application to manage special + * actions relating to MHD responses that "upgrade" + * the HTTP protocol (i.e. to WebSockets). + */ +struct MHD_UpgradeResponseHandle; + + +/** + * This connection-specific callback is provided by MHD to + * applications (unusual) during the #MHD_UpgradeHandler. + * It allows applications to perform 'special' actions on + * the underlying socket from the upgrade. + * + * @param urh the handle identifying the connection to perform + * the upgrade @a action on. + * @param action which action should be performed + * @param ... arguments to the action (depends on the action) + * @return #MHD_NO on error, #MHD_YES on success + */ +_MHD_EXTERN enum MHD_Result +MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, + enum MHD_UpgradeAction action, + ...); + + +/** + * Function called after a protocol "upgrade" response was sent + * successfully and the socket should now be controlled by some + * protocol other than HTTP. + * + * Any data already received on the socket will be made available in + * @e extra_in. This can happen if the application sent extra data + * before MHD send the upgrade response. The application should + * treat data from @a extra_in as if it had read it from the socket. + * + * Note that the application must not close() @a sock directly, + * but instead use #MHD_upgrade_action() for special operations + * on @a sock. + * + * Data forwarding to "upgraded" @a sock will be started as soon + * as this function return. + * + * Except when in 'thread-per-connection' mode, implementations + * of this function should never block (as it will still be called + * from within the main event loop). + * + * @param cls closure, whatever was given to #MHD_create_response_for_upgrade(). + * @param connection original HTTP connection handle, + * giving the function a last chance + * to inspect the original HTTP request + * @param req_cls last value left in `req_cls` of the `MHD_AccessHandlerCallback` + * @param extra_in if we happened to have read bytes after the + * HTTP header already (because the client sent + * more than the HTTP header of the request before + * we sent the upgrade response), + * these are the extra bytes already read from @a sock + * by MHD. The application should treat these as if + * it had read them from @a sock. + * @param extra_in_size number of bytes in @a extra_in + * @param sock socket to use for bi-directional communication + * with the client. For HTTPS, this may not be a socket + * that is directly connected to the client and thus certain + * operations (TCP-specific setsockopt(), getsockopt(), etc.) + * may not work as expected (as the socket could be from a + * socketpair() or a TCP-loopback). The application is expected + * to perform read()/recv() and write()/send() calls on the socket. + * The application may also call shutdown(), but must not call + * close() directly. + * @param urh argument for #MHD_upgrade_action()s on this @a connection. + * Applications must eventually use this callback to (indirectly) + * perform the close() action on the @a sock. + */ +typedef void +(*MHD_UpgradeHandler)(void *cls, + struct MHD_Connection *connection, + void *req_cls, + const char *extra_in, + size_t extra_in_size, + MHD_socket sock, + struct MHD_UpgradeResponseHandle *urh); + + +/** + * Create a response object that can be used for 101 UPGRADE + * responses, for example to implement WebSockets. After sending the + * response, control over the data stream is given to the callback (which + * can then, for example, start some bi-directional communication). + * If the response is queued for multiple connections, the callback + * will be called for each connection. The callback + * will ONLY be called after the response header was successfully passed + * to the OS; if there are communication errors before, the usual MHD + * connection error handling code will be performed. + * + * Setting the correct HTTP code (i.e. MHD_HTTP_SWITCHING_PROTOCOLS) + * and setting correct HTTP headers for the upgrade must be done + * manually (this way, it is possible to implement most existing + * WebSocket versions using this API; in fact, this API might be useful + * for any protocol switch, not just WebSockets). Note that + * draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this + * way as the header "HTTP/1.1 101 WebSocket Protocol Handshake" + * cannot be generated; instead, MHD will always produce "HTTP/1.1 101 + * Switching Protocols" (if the response code 101 is used). + * + * As usual, the response object can be extended with header + * information and then be used any number of times (as long as the + * header information is not connection-specific). + * + * @param upgrade_handler function to call with the "upgraded" socket + * @param upgrade_handler_cls closure for @a upgrade_handler + * @return NULL on error (i.e. invalid arguments, out of memory) + */ +_MHD_EXTERN struct MHD_Response * +MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, + void *upgrade_handler_cls); + + +/** + * Destroy a response object and associated resources. Note that + * libmicrohttpd may keep some of the resources around if the response + * is still in the queue for some clients, so the memory may not + * necessarily be freed immediately. + * + * @param response response to destroy + * @ingroup response + */ +_MHD_EXTERN void +MHD_destroy_response (struct MHD_Response *response); + + +/** + * Add a header line to the response. + * + * When reply is generated with queued response, some headers are generated + * automatically. Automatically generated headers are only sent to the client, + * but not added back to the response object. + * + * The list of automatic headers: + * + "Date" header is added automatically unless already set by + * this function + * @see #MHD_USE_SUPPRESS_DATE_NO_CLOCK + * + "Content-Length" is added automatically when required, attempt to set + * it manually by this function is ignored. + * @see #MHD_RF_INSANITY_HEADER_CONTENT_LENGTH + * + "Transfer-Encoding" with value "chunked" is added automatically, + * when chunked transfer encoding is used automatically. Same header with + * the same value can be set manually by this function to enforce chunked + * encoding, however for HTTP/1.0 clients chunked encoding will not be used + * and manually set "Transfer-Encoding" header is automatically removed + * for HTTP/1.0 clients + * + "Connection" may be added automatically with value "Keep-Alive" (only + * for HTTP/1.0 clients) or "Close". The header "Connection" with value + * "Close" could be set by this function to enforce closure of + * the connection after sending this response. "Keep-Alive" cannot be + * enforced and will be removed automatically. + * @see #MHD_RF_SEND_KEEP_ALIVE_HEADER + * + * Some headers are pre-processed by this function: + * * "Connection" headers are combined into single header entry, value is + * normilised, "Keep-Alive" tokens are removed. + * * "Transfer-Encoding" header: the only one header is allowed, the only + * allowed value is "chunked". + * * "Date" header: the only one header is allowed, the second added header + * replaces the first one. + * * "Content-Length" application-defined header is not allowed. + * @see #MHD_RF_INSANITY_HEADER_CONTENT_LENGTH + * + * Headers are used in order as they were added. + * + * @param response the response to add a header to + * @param header the header name to add, no need to be static, an internal copy + * will be created automatically + * @param content the header value to add, no need to be static, an internal + * copy will be created automatically + * @return #MHD_YES on success, + * #MHD_NO on error (i.e. invalid header or content format), + * or out of memory + * @ingroup response + */ +_MHD_EXTERN enum MHD_Result +MHD_add_response_header (struct MHD_Response *response, + const char *header, + const char *content); + + +/** + * Add a footer line to the response. + * + * @param response response to remove a header from + * @param footer the footer to delete + * @param content value to delete + * @return #MHD_NO on error (i.e. invalid footer or content format). + * @ingroup response + */ +_MHD_EXTERN enum MHD_Result +MHD_add_response_footer (struct MHD_Response *response, + const char *footer, + const char *content); + + +/** + * Delete a header (or footer) line from the response. + * + * For "Connection" headers this function remove all tokens from existing + * value. Successful result means that at least one token has been removed. + * If all tokens are removed from "Connection" header, the empty "Connection" + * header removed. + * + * @param response response to remove a header from + * @param header the header to delete + * @param content value to delete + * @return #MHD_NO on error (no such header known) + * @ingroup response + */ +_MHD_EXTERN enum MHD_Result +MHD_del_response_header (struct MHD_Response *response, + const char *header, + const char *content); + + +/** + * Get all of the headers (and footers) added to a response. + * + * @param response response to query + * @param iterator callback to call on each header; + * may be NULL (then just count headers) + * @param iterator_cls extra argument to @a iterator + * @return number of entries iterated over + * @ingroup response + */ +_MHD_EXTERN int +MHD_get_response_headers (struct MHD_Response *response, + MHD_KeyValueIterator iterator, + void *iterator_cls); + + +/** + * Get a particular header (or footer) from the response. + * + * @param response response to query + * @param key which header to get + * @return NULL if header does not exist + * @ingroup response + */ +_MHD_EXTERN const char * +MHD_get_response_header (struct MHD_Response *response, + const char *key); + + +/* ********************** PostProcessor functions ********************** */ + +/** + * Create a `struct MHD_PostProcessor`. + * + * A `struct MHD_PostProcessor` can be used to (incrementally) parse + * the data portion of a POST request. Note that some buggy browsers + * fail to set the encoding type. If you want to support those, you + * may have to call #MHD_set_connection_value with the proper encoding + * type before creating a post processor (if no supported encoding + * type is set, this function will fail). + * + * @param connection the connection on which the POST is + * happening (used to determine the POST format) + * @param buffer_size maximum number of bytes to use for + * internal buffering (used only for the parsing, + * specifically the parsing of the keys). A + * tiny value (256-1024) should be sufficient. + * Do NOT use a value smaller than 256. For good + * performance, use 32 or 64k (i.e. 65536). + * @param iter iterator to be called with the parsed data, + * Must NOT be NULL. + * @param iter_cls first argument to @a iter + * @return NULL on error (out of memory, unsupported encoding), + * otherwise a PP handle + * @ingroup request + */ +_MHD_EXTERN struct MHD_PostProcessor * +MHD_create_post_processor (struct MHD_Connection *connection, + size_t buffer_size, + MHD_PostDataIterator iter, void *iter_cls); + + +/** + * Parse and process POST data. Call this function when POST data is + * available (usually during an #MHD_AccessHandlerCallback) with the + * "upload_data" and "upload_data_size". Whenever possible, this will + * then cause calls to the #MHD_PostDataIterator. + * + * @param pp the post processor + * @param post_data @a post_data_len bytes of POST data + * @param post_data_len length of @a post_data + * @return #MHD_YES on success, #MHD_NO on error + * (out-of-memory, iterator aborted, parse error) + * @ingroup request + */ +_MHD_EXTERN enum MHD_Result +MHD_post_process (struct MHD_PostProcessor *pp, + const char *post_data, + size_t post_data_len); + + +/** + * Release PostProcessor resources. + * + * @param pp the PostProcessor to destroy + * @return #MHD_YES if processing completed nicely, + * #MHD_NO if there were spurious characters / formatting + * problems; it is common to ignore the return + * value of this function + * @ingroup request + */ +_MHD_EXTERN enum MHD_Result +MHD_destroy_post_processor (struct MHD_PostProcessor *pp); + + +/* ********************* Digest Authentication functions *************** */ + + +/** + * Length of the binary output of the MD5 hash function. + * @sa #MHD_digest_get_hash_size() + * @ingroup authentication + */ +#define MHD_MD5_DIGEST_SIZE 16 + +/** + * Length of the binary output of the SHA-256 hash function. + * @sa #MHD_digest_get_hash_size() + * @ingroup authentication + */ +#define MHD_SHA256_DIGEST_SIZE 32 + +/** + * Length of the binary output of the SHA-512/256 hash function. + * @warning While this value is the same as the #MHD_SHA256_DIGEST_SIZE, + * the calculated digests for SHA-256 and SHA-512/256 are different. + * @sa #MHD_digest_get_hash_size() + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +#define MHD_SHA512_256_DIGEST_SIZE 32 + +/** + * Base type of hash calculation. + * Used as part of #MHD_DigestAuthAlgo3 values. + * + * @warning Not used directly by MHD API. + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DigestBaseAlgo +{ + /** + * Invalid hash algorithm value + */ + MHD_DIGEST_BASE_ALGO_INVALID = 0, + + /** + * MD5 hash algorithm. + * As specified by RFC1321 + */ + MHD_DIGEST_BASE_ALGO_MD5 = (1 << 0), + + /** + * SHA-256 hash algorithm. + * As specified by FIPS PUB 180-4 + */ + MHD_DIGEST_BASE_ALGO_SHA256 = (1 << 1), + + /** + * SHA-512/256 hash algorithm. + * As specified by FIPS PUB 180-4 + */ + MHD_DIGEST_BASE_ALGO_SHA512_256 = (1 << 2) +} _MHD_FIXED_FLAGS_ENUM; + +/** + * The flag indicating non-session algorithm types, + * like 'MD5', 'SHA-256' or 'SHA-512-256'. + * @note Available since #MHD_VERSION 0x00097701 + */ +#define MHD_DIGEST_AUTH_ALGO3_NON_SESSION (1 << 6) + +/** + * The flag indicating session algorithm types, + * like 'MD5-sess', 'SHA-256-sess' or 'SHA-512-256-sess'. + * @note Available since #MHD_VERSION 0x00097701 + */ +#define MHD_DIGEST_AUTH_ALGO3_SESSION (1 << 7) + +/** + * Digest algorithm identification + * @warning Do not be confused with #MHD_DigestAuthAlgorithm, + * which uses other values! + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DigestAuthAlgo3 +{ + /** + * Unknown or wrong algorithm type. + * Used in struct MHD_DigestAuthInfo to indicate client value that + * cannot by identified. + */ + MHD_DIGEST_AUTH_ALGO3_INVALID = 0, + + /** + * The 'MD5' algorithm, non-session version. + */ + MHD_DIGEST_AUTH_ALGO3_MD5 = + MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO3_NON_SESSION, + + /** + * The 'MD5-sess' algorithm. + * Not supported by MHD for authentication. + */ + MHD_DIGEST_AUTH_ALGO3_MD5_SESSION = + MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO3_SESSION, + + /** + * The 'SHA-256' algorithm, non-session version. + */ + MHD_DIGEST_AUTH_ALGO3_SHA256 = + MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO3_NON_SESSION, + + /** + * The 'SHA-256-sess' algorithm. + * Not supported by MHD for authentication. + */ + MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION = + MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO3_SESSION, + + /** + * The 'SHA-512-256' (SHA-512/256) algorithm. + */ + MHD_DIGEST_AUTH_ALGO3_SHA512_256 = + MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO3_NON_SESSION, + + /** + * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm. + * Not supported by MHD for authentication. + */ + MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION = + MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO3_SESSION +}; + + +/** + * Get digest size for specified algorithm. + * + * The size of the digest specifies the size of the userhash, userdigest + * and other parameters which size depends on used hash algorithm. + * @param algo3 the algorithm to check + * @return the size of the digest (either #MHD_MD5_DIGEST_SIZE or + * #MHD_SHA256_DIGEST_SIZE/MHD_SHA512_256_DIGEST_SIZE) + * or zero if the input value is not supported or not valid + * @sa #MHD_digest_auth_calc_userdigest() + * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex() + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN size_t +MHD_digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3); + +/** + * Digest algorithm identification, allow multiple selection. + * + * #MHD_DigestAuthAlgo3 always can be casted to #MHD_DigestAuthMultiAlgo3, but + * not vice versa. + * + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DigestAuthMultiAlgo3 +{ + /** + * Unknown or wrong algorithm type. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_INVALID = MHD_DIGEST_AUTH_ALGO3_INVALID, + + /** + * The 'MD5' algorithm, non-session version. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_MD5 = MHD_DIGEST_AUTH_ALGO3_MD5, + + /** + * The 'MD5-sess' algorithm. + * Not supported by MHD for authentication. + * Reserved value. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_MD5_SESSION = MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, + + /** + * The 'SHA-256' algorithm, non-session version. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA256 = MHD_DIGEST_AUTH_ALGO3_SHA256, + + /** + * The 'SHA-256-sess' algorithm. + * Not supported by MHD for authentication. + * Reserved value. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA256_SESSION = + MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION, + + /** + * The 'SHA-512-256' (SHA-512/256) algorithm, non-session version. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA512_256 = MHD_DIGEST_AUTH_ALGO3_SHA512_256, + + /** + * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm. + * Not supported by MHD for authentication. + * Reserved value. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA512_256_SESSION = + MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION, + + /** + * SHA-256 or SHA-512/256 non-session algorithm, MHD will choose + * the preferred or the matching one. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA_ANY_NON_SESSION = + MHD_DIGEST_AUTH_ALGO3_SHA256 | MHD_DIGEST_AUTH_ALGO3_SHA512_256, + + /** + * Any non-session algorithm, MHD will choose the preferred or + * the matching one. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION = + (0x3F) | MHD_DIGEST_AUTH_ALGO3_NON_SESSION, + + /** + * The SHA-256 or SHA-512/256 session algorithm. + * Not supported by MHD. + * Reserved value. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA_ANY_SESSION = + MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION + | MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION, + + /** + * Any session algorithm. + * Not supported by MHD. + * Reserved value. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_ANY_SESSION = + (0x3F) | MHD_DIGEST_AUTH_ALGO3_SESSION, + + /** + * The MD5 algorithm, session or non-session. + * Currently supported as non-session only. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_MD5_ANY = + MHD_DIGEST_AUTH_MULT_ALGO3_MD5 | MHD_DIGEST_AUTH_MULT_ALGO3_MD5_SESSION, + + /** + * The SHA-256 algorithm, session or non-session. + * Currently supported as non-session only. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA256_ANY = + MHD_DIGEST_AUTH_MULT_ALGO3_SHA256 + | MHD_DIGEST_AUTH_MULT_ALGO3_SHA256_SESSION, + + /** + * The SHA-512/256 algorithm, session or non-session. + * Currently supported as non-session only. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA512_256_ANY = + MHD_DIGEST_AUTH_MULT_ALGO3_SHA512_256 + | MHD_DIGEST_AUTH_MULT_ALGO3_SHA512_256_SESSION, + + /** + * The SHA-256 or SHA-512/256 algorithm, session or non-session. + * Currently supported as non-session only. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_SHA_ANY_ANY = + MHD_DIGEST_AUTH_MULT_ALGO3_SHA_ANY_NON_SESSION + | MHD_DIGEST_AUTH_MULT_ALGO3_SHA_ANY_SESSION, + + /** + * Any algorithm, MHD will choose the preferred or the matching one. + */ + MHD_DIGEST_AUTH_MULT_ALGO3_ANY = + (0x3F) | MHD_DIGEST_AUTH_ALGO3_NON_SESSION | MHD_DIGEST_AUTH_ALGO3_SESSION +}; + + +/** + * Calculate "userhash", return it as binary data. + * + * The "userhash" is the hash of the string "username:realm". + * + * The "userhash" could be used to avoid sending username in cleartext in Digest + * Authorization client's header. + * + * Userhash is not designed to hide the username in local database or files, + * as username in cleartext is required for #MHD_digest_auth_check3() function + * to check the response, but it can be used to hide username in HTTP headers. + * + * This function could be used when the new username is added to the username + * database to save the "userhash" alongside with the username (preferably) or + * when loading list of the usernames to generate the userhash for every loaded + * username (this will cause delays at the start with the long lists). + * + * Once "userhash" is generated it could be used to identify users by clients + * with "userhash" support. + * Avoid repetitive usage of this function for the same username/realm + * combination as it will cause excessive CPU load; save and re-use the result + * instead. + * + * @param algo3 the algorithm for userhash calculations + * @param username the username + * @param realm the realm + * @param[out] userhash_bin the output buffer for userhash as binary data; + * if this function succeeds, then this buffer has + * #MHD_digest_get_hash_size(algo3) bytes of userhash + * upon return + * @param bin_buf_size the size of the @a userhash_bin buffer, must be + * at least #MHD_digest_get_hash_size(algo3) bytes long + * @return MHD_YES on success, + * MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is + * not supported (or external error has occurred, + * see #MHD_FEATURE_EXTERN_HASH) + * @sa #MHD_digest_auth_calc_userhash_hex() + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo3 algo3, + const char *username, + const char *realm, + void *userhash_bin, + size_t bin_buf_size); + + +/** + * Calculate "userhash", return it as hexadecimal string. + * + * The "userhash" is the hash of the string "username:realm". + * + * The "userhash" could be used to avoid sending username in cleartext in Digest + * Authorization client's header. + * + * Userhash is not designed to hide the username in local database or files, + * as username in cleartext is required for #MHD_digest_auth_check3() function + * to check the response, but it can be used to hide username in HTTP headers. + * + * This function could be used when the new username is added to the username + * database to save the "userhash" alongside with the username (preferably) or + * when loading list of the usernames to generate the userhash for every loaded + * username (this will cause delays at the start with the long lists). + * + * Once "userhash" is generated it could be used to identify users by clients + * with "userhash" support. + * Avoid repetitive usage of this function for the same username/realm + * combination as it will cause excessive CPU load; save and re-use the result + * instead. + * + * @param algo3 the algorithm for userhash calculations + * @param username the username + * @param realm the realm + * @param[out] userhash_hex the output buffer for userhash as hex string; + * if this function succeeds, then this buffer has + * #MHD_digest_get_hash_size(algo3)*2 chars long + * userhash zero-terminated string + * @param bin_buf_size the size of the @a userhash_bin buffer, must be + * at least #MHD_digest_get_hash_size(algo3)*2+1 chars long + * @return MHD_YES on success, + * MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is + * not supported (or external error has occurred, + * see #MHD_FEATURE_EXTERN_HASH). + * @sa #MHD_digest_auth_calc_userhash() + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_digest_auth_calc_userhash_hex (enum MHD_DigestAuthAlgo3 algo3, + const char *username, + const char *realm, + char *userhash_hex, + size_t hex_buf_size); + + +/** + * The type of username used by client in Digest Authorization header + * + * Values are sorted so simplified checks could be used. + * For example: + * * (value <= MHD_DIGEST_AUTH_UNAME_TYPE_INVALID) is true if no valid username + * is provided by the client + * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH) is true if username is + * provided in any form + * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD) is true if username is + * provided in clear text (no userhash matching is needed) + * + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DigestAuthUsernameType +{ + /** + * No username parameter in in Digest Authorization header. + * This should be treated as an error. + */ + MHD_DIGEST_AUTH_UNAME_TYPE_MISSING = 0, + + /** + * The 'username' parameter is used to specify the username. + */ + MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD = (1 << 2), + + /** + * The username is specified by 'username*' parameter with + * the extended notation (see RFC 5987 #section-3.2.1). + * The only difference between standard and extended types is + * the way how username value is encoded in the header. + */ + MHD_DIGEST_AUTH_UNAME_TYPE_EXTENDED = (1 << 3), + + /** + * The username provided in form of 'userhash' as + * specified by RFC 7616 #section-3.4.4. + * @sa #MHD_digest_auth_calc_userhash_hex(), #MHD_digest_auth_calc_userhash() + */ + MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH = (1 << 1), + + /** + * The invalid combination of username parameters are used by client. + * Either: + * * both 'username' and 'username*' are used + * * 'username*' is used with 'userhash=true' + * * 'username*' used with invalid extended notation + * * 'username' is not hexadecimal string, while 'userhash' set to 'true' + */ + MHD_DIGEST_AUTH_UNAME_TYPE_INVALID = (1 << 0) +} _MHD_FIXED_ENUM; + +/** + * The QOP ('quality of protection') types. + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DigestAuthQOP +{ + /** + * Invalid/unknown QOP. + * Used in struct MHD_DigestAuthInfo to indicate client value that + * cannot by identified. + */ + MHD_DIGEST_AUTH_QOP_INVALID = 0, + + /** + * No QOP parameter. + * As described in old RFC 2069 original specification. + * This mode is not allowed by latest RFCs and should be used only to + * communicate with clients that do not support more modern modes (with QOP + * parameter). + * This mode is less secure than other modes and inefficient. + */ + MHD_DIGEST_AUTH_QOP_NONE = 1 << 0, + + /** + * The 'auth' QOP type. + */ + MHD_DIGEST_AUTH_QOP_AUTH = 1 << 1, + + /** + * The 'auth-int' QOP type. + * Not supported by MHD for authentication. + */ + MHD_DIGEST_AUTH_QOP_AUTH_INT = 1 << 2 +} _MHD_FIXED_FLAGS_ENUM; + +/** + * The QOP ('quality of protection') types, multiple selection. + * + * #MHD_DigestAuthQOP always can be casted to #MHD_DigestAuthMultiQOP, but + * not vice versa. + * + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DigestAuthMultiQOP +{ + /** + * Invalid/unknown QOP. + */ + MHD_DIGEST_AUTH_MULT_QOP_INVALID = MHD_DIGEST_AUTH_QOP_INVALID, + + /** + * No QOP parameter. + * As described in old RFC 2069 original specification. + * This mode is not allowed by latest RFCs and should be used only to + * communicate with clients that do not support more modern modes (with QOP + * parameter). + * This mode is less secure than other modes and inefficient. + */ + MHD_DIGEST_AUTH_MULT_QOP_NONE = MHD_DIGEST_AUTH_QOP_NONE, + + /** + * The 'auth' QOP type. + */ + MHD_DIGEST_AUTH_MULT_QOP_AUTH = MHD_DIGEST_AUTH_QOP_AUTH, + + /** + * The 'auth-int' QOP type. + * Not supported by MHD. + * Reserved value. + */ + MHD_DIGEST_AUTH_MULT_QOP_AUTH_INT = MHD_DIGEST_AUTH_QOP_AUTH_INT, + + /** + * The 'auth' QOP type OR the old RFC2069 (no QOP) type. + * In other words: any types except 'auth-int'. + * RFC2069-compatible mode is allowed, thus this value should be used only + * when it is really necessary. + */ + MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT = + MHD_DIGEST_AUTH_QOP_NONE | MHD_DIGEST_AUTH_QOP_AUTH, + + /** + * Any 'auth' QOP type ('auth' or 'auth-int'). + * Currently supported as 'auth' QOP type only. + */ + MHD_DIGEST_AUTH_MULT_QOP_AUTH_ANY = + MHD_DIGEST_AUTH_QOP_AUTH | MHD_DIGEST_AUTH_QOP_AUTH_INT +} _MHD_FIXED_ENUM; + +/** + * The invalid value of 'nc' parameter in client Digest Authorization header. + * @note Available since #MHD_VERSION 0x00097701 + */ +#define MHD_DIGEST_AUTH_INVALID_NC_VALUE (0) + +/** + * Information from Digest Authorization client's header. + * + * All buffers pointed by any struct members are freed when #MHD_free() is + * called for pointer to this structure. + * + * Application may modify buffers as needed until #MHD_free() is called for + * pointer to this structure + * @note Available since #MHD_VERSION 0x00097701 + */ +struct MHD_DigestAuthInfo +{ + /** + * The algorithm as defined by client. + * Set automatically to MD5 if not specified by client. + * @warning Do not be confused with #MHD_DigestAuthAlgorithm, + * which uses other values! + */ + enum MHD_DigestAuthAlgo3 algo3; + + /** + * The type of username used by client. + */ + enum MHD_DigestAuthUsernameType uname_type; + + /** + * The username string. + * Used only if username type is standard or extended, always NULL otherwise. + * If extended notation is used, this string is pct-decoded string + * with charset and language tag removed (i.e. it is original username + * extracted from the extended notation). + * When userhash is used by the client, this member is NULL and + * @a userhash_hex and @a userhash_bin are set. + * The buffer pointed by the @a username becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + */ + char *username; + + /** + * The length of the @a username. + * When the @a username is NULL, this member is always zero. + */ + size_t username_len; + + /** + * The userhash string. + * Valid only if username type is userhash. + * This is unqoted string without decoding of the hexadecimal + * digits (as provided by the client). + * The buffer pointed by the @a userhash_hex becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + * @sa #MHD_digest_auth_calc_userhash_hex() + */ + char *userhash_hex; + + /** + * The length of the @a userhash_hex in characters. + * The valid size should be #MHD_digest_get_hash_size(algo3) * 2 characters. + * When the @a userhash_hex is NULL, this member is always zero. + */ + size_t userhash_hex_len; + + /** + * The userhash decoded to binary form. + * Used only if username type is userhash, always NULL otherwise. + * When not NULL, this points to binary sequence @a userhash_hex_len /2 bytes + * long. + * The valid size should be #MHD_digest_get_hash_size(algo3) bytes. + * The buffer pointed by the @a userhash_bin becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + * @warning This is a binary data, no zero termination. + * @warning To avoid buffer overruns, always check the size of the data before + * use, because @a userhash_bin can point even to zero-sized + * data. + * @sa #MHD_digest_auth_calc_userhash() + */ + uint8_t *userhash_bin; + + /** + * The 'opaque' parameter value, as specified by client. + * NULL if not specified by client. + * The buffer pointed by the @a opaque becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + */ + char *opaque; + + /** + * The length of the @a opaque. + * When the @a opaque is NULL, this member is always zero. + */ + size_t opaque_len; + + /** + * The 'realm' parameter value, as specified by client. + * NULL if not specified by client. + * The buffer pointed by the @a realm becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + */ + char *realm; + + /** + * The length of the @a realm. + * When the @a realm is NULL, this member is always zero. + */ + size_t realm_len; + + /** + * The 'qop' parameter value. + */ + enum MHD_DigestAuthQOP qop; + + /** + * The length of the 'cnonce' parameter value, including possible + * backslash-escape characters. + * 'cnonce' is used in hash calculation, which is CPU-intensive procedure. + * An application may want to reject too large cnonces to limit the CPU load. + * A few kilobytes is a reasonable limit, typically cnonce is just 32-160 + * characters long. + */ + size_t cnonce_len; + + /** + * The nc parameter value. + * Can be used by application to limit the number of nonce re-uses. If @a nc + * is higher than application wants to allow, then "auth required" response + * with 'stale=true' could be used to force client to retry with the fresh + * 'nonce'. + * If not specified by client or does not have hexadecimal digits only, the + * value is #MHD_DIGEST_AUTH_INVALID_NC_VALUE. + */ + uint32_t nc; +}; + + +/** + * Get information about Digest Authorization client's header. + * + * @param connection The MHD connection structure + * @return NULL if no valid Digest Authorization header is used in the request; + * a pointer to the structure with information if the valid request + * header found, free using #MHD_free(). + * @sa #MHD_digest_auth_get_username3() + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN struct MHD_DigestAuthInfo * +MHD_digest_auth_get_request_info3 (struct MHD_Connection *connection); + + +/** + * Information from Digest Authorization client's header. + * + * All buffers pointed by any struct members are freed when #MHD_free() is + * called for pointer to this structure. + * + * Application may modify buffers as needed until #MHD_free() is called for + * pointer to this structure + * @note Available since #MHD_VERSION 0x00097701 + */ +struct MHD_DigestAuthUsernameInfo +{ + /** + * The algorithm as defined by client. + * Set automatically to MD5 if not specified by client. + * @warning Do not be confused with #MHD_DigestAuthAlgorithm, + * which uses other values! + */ + enum MHD_DigestAuthAlgo3 algo3; + + /** + * The type of username used by client. + * The 'invalid' and 'missing' types are not used in this structure, + * instead NULL is returned by #MHD_digest_auth_get_username3(). + */ + enum MHD_DigestAuthUsernameType uname_type; + + /** + * The username string. + * Used only if username type is standard or extended, always NULL otherwise. + * If extended notation is used, this string is pct-decoded string + * with charset and language tag removed (i.e. it is original username + * extracted from the extended notation). + * When userhash is used by the client, this member is NULL and + * @a userhash_hex and @a userhash_bin are set. + * The buffer pointed by the @a username becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + */ + char *username; + + /** + * The length of the @a username. + * When the @a username is NULL, this member is always zero. + */ + size_t username_len; + + /** + * The userhash string. + * Valid only if username type is userhash. + * This is unqoted string without decoding of the hexadecimal + * digits (as provided by the client). + * The buffer pointed by the @a userhash_hex becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + * @sa #MHD_digest_auth_calc_userhash_hex() + */ + char *userhash_hex; + + /** + * The length of the @a userhash_hex in characters. + * The valid size should be #MHD_digest_get_hash_size(algo3) * 2 characters. + * When the @a userhash_hex is NULL, this member is always zero. + */ + size_t userhash_hex_len; + + /** + * The userhash decoded to binary form. + * Used only if username type is userhash, always NULL otherwise. + * When not NULL, this points to binary sequence @a userhash_hex_len /2 bytes + * long. + * The valid size should be #MHD_digest_get_hash_size(algo3) bytes. + * The buffer pointed by the @a userhash_bin becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + * @warning This is a binary data, no zero termination. + * @warning To avoid buffer overruns, always check the size of the data before + * use, because @a userhash_bin can point even to zero-sized + * data. + * @sa #MHD_digest_auth_calc_userhash() + */ + uint8_t *userhash_bin; +}; + + +/** + * Get the username from Digest Authorization client's header. + * + * @param connection The MHD connection structure + * @return NULL if no valid Digest Authorization header is used in the request, + * or no username parameter is present in the header, or username is + * provided incorrectly by client (see description for + * #MHD_DIGEST_AUTH_UNAME_TYPE_INVALID); + * a pointer structure with information if the valid request header + * found, free using #MHD_free(). + * @sa #MHD_digest_auth_get_request_info3() provides more complete information + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN struct MHD_DigestAuthUsernameInfo * +MHD_digest_auth_get_username3 (struct MHD_Connection *connection); + + +/** + * The result of digest authentication of the client. + * + * All error values are zero or negative. + * + * @note Available since #MHD_VERSION 0x00097701 + */ +enum MHD_DigestAuthResult +{ + /** + * Authentication OK. + */ + MHD_DAUTH_OK = 1, + + /** + * General error, like "out of memory". + */ + MHD_DAUTH_ERROR = 0, + + /** + * No "Authorization" header or wrong format of the header. + * Also may be returned if required parameters in client Authorisation header + * are missing or broken (in invalid format). + */ + MHD_DAUTH_WRONG_HEADER = -1, + + /** + * Wrong 'username'. + */ + MHD_DAUTH_WRONG_USERNAME = -2, + + /** + * Wrong 'realm'. + */ + MHD_DAUTH_WRONG_REALM = -3, + + /** + * Wrong 'URI' (or URI parameters). + */ + MHD_DAUTH_WRONG_URI = -4, + + /** + * Wrong 'qop'. + */ + MHD_DAUTH_WRONG_QOP = -5, + + /** + * Wrong 'algorithm'. + */ + MHD_DAUTH_WRONG_ALGO = -6, + + /** + * Too large (>64 KiB) Authorization parameter value. + */ + MHD_DAUTH_TOO_LARGE = -15, + + /* The different form of naming is intentionally used for the results below, + * as they are more important */ + + /** + * The 'nonce' is too old. Suggest the client to retry with the same + * username and password to get the fresh 'nonce'. + * The validity of the 'nonce' may be not checked. + */ + MHD_DAUTH_NONCE_STALE = -17, + + /** + * The 'nonce' was generated by MHD for other conditions. + * This value is only returned if #MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE + * is set to anything other than #MHD_DAUTH_BIND_NONCE_NONE. + * The interpretation of this code could be different. For example, if + * #MHD_DAUTH_BIND_NONCE_URI is set and client just used the same 'nonce' for + * another URI, the code could be handled as #MHD_DAUTH_NONCE_STALE as + * RFCs allow nonces re-using for other URIs in the same "protection + * space". However, if only #MHD_DAUTH_BIND_NONCE_CLIENT_IP bit is set and + * it is know that clients have fixed IP addresses, this return code could + * be handled like #MHD_DAUTH_NONCE_WRONG. + */ + MHD_DAUTH_NONCE_OTHER_COND = -18, + + /** + * The 'nonce' is wrong. May indicate an attack attempt. + */ + MHD_DAUTH_NONCE_WRONG = -33, + + /** + * The 'response' is wrong. Typically it means that wrong password used. + * May indicate an attack attempt. + */ + MHD_DAUTH_RESPONSE_WRONG = -34 +}; + + +/** + * Authenticates the authorization header sent by the client. + * + * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in + * @a mqop and the client uses this mode, then server generated nonces are + * used as one-time nonces because nonce-count is not supported in this old RFC. + * Communication in this mode is very inefficient, especially if the client + * requests several resources one-by-one as for every request a new nonce must + * be generated and client repeats all requests twice (first time to get a new + * nonce and second time to perform an authorised request). + * + * @param connection the MHD connection structure + * @param realm the realm for authorization of the client + * @param username the username to be authenticated, must be in clear text + * even if userhash is used by the client + * @param password the password matching the @a username (and the @a realm) + * @param nonce_timeout the period of seconds since nonce generation, when + * the nonce is recognised as valid and not stale; + * if zero is specified then daemon default value is used. + * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc + * exceeds the specified value then MHD_DAUTH_NONCE_STALE is + * returned; + * if zero is specified then daemon default value is used. + * @param mqop the QOP to use + * @param malgo3 digest algorithms allowed to use, fail if algorithm used + * by the client is not allowed by this parameter + * @return #MHD_DAUTH_OK if authenticated, + * the error code otherwise + * @note Available since #MHD_VERSION 0x00097708 + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_DigestAuthResult +MHD_digest_auth_check3 (struct MHD_Connection *connection, + const char *realm, + const char *username, + const char *password, + unsigned int nonce_timeout, + uint32_t max_nc, + enum MHD_DigestAuthMultiQOP mqop, + enum MHD_DigestAuthMultiAlgo3 malgo3); + + +/** + * Calculate userdigest, return it as a binary data. + * + * The "userdigest" is the hash of the "username:realm:password" string. + * + * The "userdigest" can be used to avoid storing the password in clear text + * in database/files + * + * This function is designed to improve security of stored credentials, + * the "userdigest" does not improve security of the authentication process. + * + * The results can be used to store username & userdigest pairs instead of + * username & password pairs. To further improve security, application may + * store username & userhash & userdigest triplets. + * + * @param algo3 the digest algorithm + * @param username the username + * @param realm the realm + * @param password the password + * @param[out] userdigest_bin the output buffer for userdigest; + * if this function succeeds, then this buffer has + * #MHD_digest_get_hash_size(algo3) bytes of + * userdigest upon return + * @param bin_buf_size the size of the @a userdigest_bin buffer, must be + * at least #MHD_digest_get_hash_size(algo3) bytes long + * @return MHD_YES on success, + * MHD_NO if @a userdigest_bin is too small or if @a algo3 algorithm is + * not supported (or external error has occurred, + * see #MHD_FEATURE_EXTERN_HASH). + * @sa #MHD_digest_auth_check_digest3() + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_digest_auth_calc_userdigest (enum MHD_DigestAuthAlgo3 algo3, + const char *username, + const char *realm, + const char *password, + void *userdigest_bin, + size_t bin_buf_size); + + +/** + * Authenticates the authorization header sent by the client by using + * hash of "username:realm:password". + * + * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in + * @a mqop and the client uses this mode, then server generated nonces are + * used as one-time nonces because nonce-count is not supported in this old RFC. + * Communication in this mode is very inefficient, especially if the client + * requests several resources one-by-one as for every request a new nonce must + * be generated and client repeats all requests twice (first time to get a new + * nonce and second time to perform an authorised request). + * + * @param connection the MHD connection structure + * @param realm the realm for authorization of the client + * @param username the username to be authenticated, must be in clear text + * even if userhash is used by the client + * @param userdigest the precalculated binary hash of the string + * "username:realm:password", + * see #MHD_digest_auth_calc_userdigest() + * @param userdigest_size the size of the @a userdigest in bytes, must match the + * hashing algorithm (see #MHD_MD5_DIGEST_SIZE, + * #MHD_SHA256_DIGEST_SIZE, #MHD_SHA512_256_DIGEST_SIZE, + * #MHD_digest_get_hash_size()) + * @param nonce_timeout the period of seconds since nonce generation, when + * the nonce is recognised as valid and not stale; + * if zero is specified then daemon default value is used. + * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc + * exceeds the specified value then MHD_DAUTH_NONCE_STALE is + * returned; + * if zero is specified then daemon default value is used. + * @param mqop the QOP to use + * @param malgo3 digest algorithms allowed to use, fail if algorithm used + * by the client is not allowed by this parameter; + * more than one base algorithms (MD5, SHA-256, SHA-512/256) + * cannot be used at the same time for this function + * as @a userdigest must match specified algorithm + * @return #MHD_DAUTH_OK if authenticated, + * the error code otherwise + * @sa #MHD_digest_auth_calc_userdigest() + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_DigestAuthResult +MHD_digest_auth_check_digest3 (struct MHD_Connection *connection, + const char *realm, + const char *username, + const void *userdigest, + size_t userdigest_size, + unsigned int nonce_timeout, + uint32_t max_nc, + enum MHD_DigestAuthMultiQOP mqop, + enum MHD_DigestAuthMultiAlgo3 malgo3); + + +/** + * Queues a response to request authentication from the client + * + * This function modifies provided @a response. The @a response must not be + * reused and should be destroyed (by #MHD_destroy_response()) after call of + * this function. + * + * If @a mqop allows both RFC 2069 (MHD_DIGEST_AUTH_QOP_NONE) and QOP with + * value, then response is formed like if MHD_DIGEST_AUTH_QOP_NONE bit was + * not set, because such response should be backward-compatible with RFC 2069. + * + * If @a mqop allows only MHD_DIGEST_AUTH_MULT_QOP_NONE, then the response is + * formed in strict accordance with RFC 2069 (no 'qop', no 'userhash', no + * 'charset'). For better compatibility with clients, it is recommended (but + * not required) to set @a domain to NULL in this mode. + * + * @param connection the MHD connection structure + * @param realm the realm presented to the client + * @param opaque the string for opaque value, can be NULL, but NULL is + * not recommended for better compatibility with clients; + * the recommended format is hex or Base64 encoded string + * @param domain the optional space-separated list of URIs for which the + * same authorisation could be used, URIs can be in form + * "path-absolute" (the path for the same host with initial slash) + * or in form "absolute-URI" (the full path with protocol), in + * any case client may assume that URI is in the same "protection + * space" if it starts with any of values specified here; + * could be NULL (clients typically assume that the same + * credentials could be used for any URI on the same host); + * this list provides information for the client only and does + * not actually restrict anything on the server side + * @param response the reply to send; should contain the "access denied" + * body; + * note: this function sets the "WWW Authenticate" header and + * the caller should not set this header; + * the NULL is tolerated + * @param signal_stale if set to #MHD_YES then indication of stale nonce used in + * the client's request is signalled by adding 'stale=true' + * to the authentication header, this instructs the client + * to retry immediately with the new nonce and the same + * credentials, without asking user for the new password + * @param mqop the QOP to use + * @param malgo3 digest algorithm to use; if several algorithms are allowed + * then MD5 is preferred (currently, may be changed in next + * versions) + * @param userhash_support if set to non-zero value (#MHD_YES) then support of + * userhash is indicated, allowing client to provide + * hash("username:realm") instead of the username in + * clear text; + * note that clients are allowed to provide the username + * in cleartext even if this parameter set to non-zero; + * when userhash is used, application must be ready to + * identify users by provided userhash value instead of + * username; see #MHD_digest_auth_calc_userhash() and + * #MHD_digest_auth_calc_userhash_hex() + * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is + * added, indicating for the client that UTF-8 encoding for + * the username is preferred + * @return #MHD_YES on success, #MHD_NO otherwise + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_queue_auth_required_response3 (struct MHD_Connection *connection, + const char *realm, + const char *opaque, + const char *domain, + struct MHD_Response *response, + int signal_stale, + enum MHD_DigestAuthMultiQOP mqop, + enum MHD_DigestAuthMultiAlgo3 algo, + int userhash_support, + int prefer_utf8); + + +/** + * Constant to indicate that the nonce of the provided + * authentication code was wrong. + * Used as return code by #MHD_digest_auth_check(), #MHD_digest_auth_check2(), + * #MHD_digest_auth_check_digest(), #MHD_digest_auth_check_digest2(). + * @ingroup authentication + */ +#define MHD_INVALID_NONCE -1 + + +/** + * Get the username from the authorization header sent by the client + * + * This function supports username in standard and extended notations. + * "userhash" is not supported by this function. + * + * @param connection The MHD connection structure + * @return NULL if no username could be found, username provided as + * "userhash", extended notation broken or memory allocation error + * occurs; + * a pointer to the username if found, free using #MHD_free(). + * @warning Returned value must be freed by #MHD_free(). + * @sa #MHD_digest_auth_get_username3() + * @ingroup authentication + */ +_MHD_EXTERN char * +MHD_digest_auth_get_username (struct MHD_Connection *connection); + + +/** + * Which digest algorithm should MHD use for HTTP digest authentication? + * Used as parameter for #MHD_digest_auth_check2(), + * #MHD_digest_auth_check_digest2(), #MHD_queue_auth_fail_response2(). + */ +enum MHD_DigestAuthAlgorithm +{ + + /** + * MHD should pick (currently defaults to MD5). + */ + MHD_DIGEST_ALG_AUTO = 0, + + /** + * Force use of MD5. + */ + MHD_DIGEST_ALG_MD5, + + /** + * Force use of SHA-256. + */ + MHD_DIGEST_ALG_SHA256 + +} _MHD_FIXED_ENUM; + + +/** + * Authenticates the authorization header sent by the client. + * + * @param connection The MHD connection structure + * @param realm The realm presented to the client + * @param username The username needs to be authenticated + * @param password The password used in the authentication + * @param nonce_timeout The amount of time for a nonce to be + * invalid in seconds + * @param algo digest algorithms allowed for verification + * @return #MHD_YES if authenticated, #MHD_NO if not, + * #MHD_INVALID_NONCE if nonce is invalid or stale + * @note Available since #MHD_VERSION 0x00096200 + * @deprecated use MHD_digest_auth_check3() + * @ingroup authentication + */ +_MHD_EXTERN int +MHD_digest_auth_check2 (struct MHD_Connection *connection, + const char *realm, + const char *username, + const char *password, + unsigned int nonce_timeout, + enum MHD_DigestAuthAlgorithm algo); + + +/** + * Authenticates the authorization header sent by the client. + * Uses #MHD_DIGEST_ALG_MD5 (for now, for backwards-compatibility). + * Note that this MAY change to #MHD_DIGEST_ALG_AUTO in the future. + * If you want to be sure you get MD5, use #MHD_digest_auth_check2() + * and specify MD5 explicitly. + * + * @param connection The MHD connection structure + * @param realm The realm presented to the client + * @param username The username needs to be authenticated + * @param password The password used in the authentication + * @param nonce_timeout The amount of time for a nonce to be + * invalid in seconds + * @return #MHD_YES if authenticated, #MHD_NO if not, + * #MHD_INVALID_NONCE if nonce is invalid or stale + * @deprecated use MHD_digest_auth_check3() + * @ingroup authentication + */ +_MHD_EXTERN int +MHD_digest_auth_check (struct MHD_Connection *connection, + const char *realm, + const char *username, + const char *password, + unsigned int nonce_timeout); + + +/** + * Authenticates the authorization header sent by the client. + * + * @param connection The MHD connection structure + * @param realm The realm presented to the client + * @param username The username needs to be authenticated + * @param digest An `unsigned char *' pointer to the binary MD5 sum + * for the precalculated hash value "username:realm:password" + * of @a digest_size bytes + * @param digest_size number of bytes in @a digest (size must match @a algo!) + * @param nonce_timeout The amount of time for a nonce to be + * invalid in seconds + * @param algo digest algorithms allowed for verification + * @return #MHD_YES if authenticated, #MHD_NO if not, + * #MHD_INVALID_NONCE if nonce is invalid or stale + * @note Available since #MHD_VERSION 0x00096200 + * @deprecated use MHD_digest_auth_check_digest3() + * @ingroup authentication + */ +_MHD_EXTERN int +MHD_digest_auth_check_digest2 (struct MHD_Connection *connection, + const char *realm, + const char *username, + const uint8_t *digest, + size_t digest_size, + unsigned int nonce_timeout, + enum MHD_DigestAuthAlgorithm algo); + + +/** + * Authenticates the authorization header sent by the client + * Uses #MHD_DIGEST_ALG_MD5 (required, as @a digest is of fixed + * size). + * + * @param connection The MHD connection structure + * @param realm The realm presented to the client + * @param username The username needs to be authenticated + * @param digest An `unsigned char *' pointer to the binary hash + * for the precalculated hash value "username:realm:password"; + * length must be #MHD_MD5_DIGEST_SIZE bytes + * @param nonce_timeout The amount of time for a nonce to be + * invalid in seconds + * @return #MHD_YES if authenticated, #MHD_NO if not, + * #MHD_INVALID_NONCE if nonce is invalid or stale + * @note Available since #MHD_VERSION 0x00096000 + * @deprecated use #MHD_digest_auth_check_digest3() + * @ingroup authentication + */ +_MHD_EXTERN int +MHD_digest_auth_check_digest (struct MHD_Connection *connection, + const char *realm, + const char *username, + const uint8_t digest[MHD_MD5_DIGEST_SIZE], + unsigned int nonce_timeout); + + +/** + * Queues a response to request authentication from the client + * + * This function modifies provided @a response. The @a response must not be + * reused and should be destroyed after call of this function. + * + * @param connection The MHD connection structure + * @param realm the realm presented to the client + * @param opaque string to user for opaque value + * @param response reply to send; should contain the "access denied" + * body; note that this function will set the "WWW Authenticate" + * header and that the caller should not do this; the NULL is tolerated + * @param signal_stale #MHD_YES if the nonce is stale to add + * 'stale=true' to the authentication header + * @param algo digest algorithm to use + * @return #MHD_YES on success, #MHD_NO otherwise + * @note Available since #MHD_VERSION 0x00096200 + * @deprecated use MHD_queue_auth_required_response3() + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, + const char *realm, + const char *opaque, + struct MHD_Response *response, + int signal_stale, + enum MHD_DigestAuthAlgorithm algo); + + +/** + * Queues a response to request authentication from the client. + * For now uses MD5 (for backwards-compatibility). Still, if you + * need to be sure, use #MHD_queue_auth_fail_response2(). + * + * This function modifies provided @a response. The @a response must not be + * reused and should be destroyed after call of this function. + * + * @param connection The MHD connection structure + * @param realm the realm presented to the client + * @param opaque string to user for opaque value + * @param response reply to send; should contain the "access denied" + * body; note that this function will set the "WWW Authenticate" + * header and that the caller should not do this; the NULL is tolerated + * @param signal_stale #MHD_YES if the nonce is stale to add + * 'stale=true' to the authentication header + * @return #MHD_YES on success, #MHD_NO otherwise + * @deprecated use MHD_queue_auth_required_response3() + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_queue_auth_fail_response (struct MHD_Connection *connection, + const char *realm, + const char *opaque, + struct MHD_Response *response, + int signal_stale); + + +/* ********************* Basic Authentication functions *************** */ + + +/** + * Information decoded from Basic Authentication client's header. + * + * The username and the password are technically allowed to have binary zeros, + * username_len and password_len could be used to detect such situations. + * + * The buffers pointed by username and password members are freed + * when #MHD_free() is called for pointer to this structure. + * + * Application may modify buffers as needed until #MHD_free() is called for + * pointer to this structure + */ +struct MHD_BasicAuthInfo +{ + /** + * The username, cannot be NULL. + * The buffer pointed by the @a username becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + */ + char *username; + + /** + * The length of the @a username, not including zero-termination + */ + size_t username_len; + + /** + * The password, may be NULL if password is not encoded by the client. + * The buffer pointed by the @a password becomes invalid when the pointer + * to the structure is freed by #MHD_free(). + */ + char *password; + + /** + * The length of the @a password, not including zero-termination; + * when the @a password is NULL, the length is always zero. + */ + size_t password_len; +}; + +/** + * Get the username and password from the Basic Authorisation header + * sent by the client + * + * @param connection the MHD connection structure + * @return NULL if no valid Basic Authentication header is present in + * current request, or + * pointer to structure with username and password, which must be + * freed by #MHD_free(). + * @note Available since #MHD_VERSION 0x00097701 + * @ingroup authentication + */ +_MHD_EXTERN struct MHD_BasicAuthInfo * +MHD_basic_auth_get_username_password3 (struct MHD_Connection *connection); + +/** + * Queues a response to request basic authentication from the client. + * + * The given response object is expected to include the payload for + * the response; the "WWW-Authenticate" header will be added and the + * response queued with the 'UNAUTHORIZED' status code. + * + * See RFC 7617#section-2 for details. + * + * The @a response is modified by this function. The modified response object + * can be used to respond subsequent requests by #MHD_queue_response() + * function with status code #MHD_HTTP_UNAUTHORIZED and must not be used again + * with MHD_queue_basic_auth_required_response3() function. The response could + * be destroyed right after call of this function. + * + * @param connection the MHD connection structure + * @param realm the realm presented to the client + * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will + * be added, indicating for client that UTF-8 encoding + * is preferred + * @param response the response object to modify and queue; the NULL + * is tolerated + * @return #MHD_YES on success, #MHD_NO otherwise + * @note Available since #MHD_VERSION 0x00097704 + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_queue_basic_auth_required_response3 (struct MHD_Connection *connection, + const char *realm, + int prefer_utf8, + struct MHD_Response *response); + +/** + * Get the username and password from the basic authorization header sent by the client + * + * @param connection The MHD connection structure + * @param[out] password a pointer for the password, free using #MHD_free(). + * @return NULL if no username could be found, a pointer + * to the username if found, free using #MHD_free(). + * @deprecated use #MHD_basic_auth_get_username_password3() + * @ingroup authentication + */ +_MHD_EXTERN char * +MHD_basic_auth_get_username_password (struct MHD_Connection *connection, + char **password); + + +/** + * Queues a response to request basic authentication from the client + * The given response object is expected to include the payload for + * the response; the "WWW-Authenticate" header will be added and the + * response queued with the 'UNAUTHORIZED' status code. + * + * @param connection The MHD connection structure + * @param realm the realm presented to the client + * @param response response object to modify and queue; the NULL is tolerated + * @return #MHD_YES on success, #MHD_NO otherwise + * @deprecated use MHD_queue_basic_auth_required_response3() + * @ingroup authentication + */ +_MHD_EXTERN enum MHD_Result +MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, + const char *realm, + struct MHD_Response *response); + +/* ********************** generic query functions ********************** */ + + +/** + * Obtain information about the given connection. + * The returned pointer is invalidated with the next call of this function or + * when the connection is closed. + * + * @param connection what connection to get information about + * @param info_type what information is desired? + * @param ... depends on @a info_type + * @return NULL if this information is not available + * (or if the @a info_type is unknown) + * @ingroup specialized + */ +_MHD_EXTERN const union MHD_ConnectionInfo * +MHD_get_connection_info (struct MHD_Connection *connection, + enum MHD_ConnectionInfoType info_type, + ...); + + +/** + * MHD connection options. Given to #MHD_set_connection_option to + * set custom options for a particular connection. + */ +enum MHD_CONNECTION_OPTION +{ + + /** + * Set a custom timeout for the given connection. Specified + * as the number of seconds, given as an `unsigned int`. Use + * zero for no timeout. + * If timeout was set to zero (or unset) before, setup of new value by + * MHD_set_connection_option() will reset timeout timer. + * Values larger than (UINT64_MAX / 2000 - 1) will + * be clipped to this number. + */ + MHD_CONNECTION_OPTION_TIMEOUT + +} _MHD_FIXED_ENUM; + + +/** + * Set a custom option for the given connection, overriding defaults. + * + * @param connection connection to modify + * @param option option to set + * @param ... arguments to the option, depending on the option type + * @return #MHD_YES on success, #MHD_NO if setting the option failed + * @ingroup specialized + */ +_MHD_EXTERN enum MHD_Result +MHD_set_connection_option (struct MHD_Connection *connection, + enum MHD_CONNECTION_OPTION option, + ...); + + +/** + * Information about an MHD daemon. + */ +union MHD_DaemonInfo +{ + /** + * Size of the key, no longer supported. + * @deprecated + */ + size_t key_size; + + /** + * Size of the mac key, no longer supported. + * @deprecated + */ + size_t mac_key_size; + + /** + * Socket, returned for #MHD_DAEMON_INFO_LISTEN_FD. + */ + MHD_socket listen_fd; + + /** + * Bind port number, returned for #MHD_DAEMON_INFO_BIND_PORT. + */ + uint16_t port; + + /** + * epoll FD, returned for #MHD_DAEMON_INFO_EPOLL_FD. + */ + int epoll_fd; + + /** + * Number of active connections, for #MHD_DAEMON_INFO_CURRENT_CONNECTIONS. + */ + unsigned int num_connections; + + /** + * Combination of #MHD_FLAG values, for #MHD_DAEMON_INFO_FLAGS. + * This value is actually a bitfield. + * Note: flags may differ from original 'flags' specified for + * daemon, especially if #MHD_USE_AUTO was set. + */ + enum MHD_FLAG flags; +}; + + +/** + * Obtain information about the given daemon. + * The returned pointer is invalidated with the next call of this function or + * when the daemon is stopped. + * + * @param daemon what daemon to get information about + * @param info_type what information is desired? + * @param ... depends on @a info_type + * @return NULL if this information is not available + * (or if the @a info_type is unknown) + * @ingroup specialized + */ +_MHD_EXTERN const union MHD_DaemonInfo * +MHD_get_daemon_info (struct MHD_Daemon *daemon, + enum MHD_DaemonInfoType info_type, + ...); + + +/** + * Obtain the version of this library + * + * @return static version string, e.g. "0.9.9" + * @ingroup specialized + */ +_MHD_EXTERN const char * +MHD_get_version (void); + + +/** + * Obtain the version of this library as a binary value. + * + * @return version binary value, e.g. "0x00090900" (#MHD_VERSION of + * compiled MHD binary) + * @note Available since #MHD_VERSION 0x00097601 + * @ingroup specialized + */ +_MHD_EXTERN uint32_t +MHD_get_version_bin (void); + + +/** + * Types of information about MHD features, + * used by #MHD_is_feature_supported(). + */ +enum MHD_FEATURE +{ + /** + * Get whether messages are supported. If supported then in debug + * mode messages can be printed to stderr or to external logger. + */ + MHD_FEATURE_MESSAGES = 1, + + /** + * Get whether HTTPS is supported. If supported then flag + * #MHD_USE_TLS and options #MHD_OPTION_HTTPS_MEM_KEY, + * #MHD_OPTION_HTTPS_MEM_CERT, #MHD_OPTION_HTTPS_MEM_TRUST, + * #MHD_OPTION_HTTPS_MEM_DHPARAMS, #MHD_OPTION_HTTPS_CRED_TYPE, + * #MHD_OPTION_HTTPS_PRIORITIES can be used. + */ + MHD_FEATURE_TLS = 2, + MHD_FEATURE_SSL = 2, + + /** + * Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK is + * supported. + */ + MHD_FEATURE_HTTPS_CERT_CALLBACK = 3, + + /** + * Get whether IPv6 is supported. If supported then flag + * #MHD_USE_IPv6 can be used. + */ + MHD_FEATURE_IPv6 = 4, + + /** + * Get whether IPv6 without IPv4 is supported. If not supported + * then IPv4 is always enabled in IPv6 sockets and + * flag #MHD_USE_DUAL_STACK is always used when #MHD_USE_IPv6 is + * specified. + */ + MHD_FEATURE_IPv6_ONLY = 5, + + /** + * Get whether `poll()` is supported. If supported then flag + * #MHD_USE_POLL can be used. + */ + MHD_FEATURE_POLL = 6, + + /** + * Get whether `epoll()` is supported. If supported then Flags + * #MHD_USE_EPOLL and + * #MHD_USE_EPOLL_INTERNAL_THREAD can be used. + */ + MHD_FEATURE_EPOLL = 7, + + /** + * Get whether shutdown on listen socket to signal other + * threads is supported. If not supported flag + * #MHD_USE_ITC is automatically forced. + */ + MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET = 8, + + /** + * Get whether socketpair is used internally instead of pipe to + * signal other threads. + */ + MHD_FEATURE_SOCKETPAIR = 9, + + /** + * Get whether TCP Fast Open is supported. If supported then + * flag #MHD_USE_TCP_FASTOPEN and option + * #MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE can be used. + */ + MHD_FEATURE_TCP_FASTOPEN = 10, + + /** + * Get whether HTTP Basic authorization is supported. If supported + * then functions #MHD_basic_auth_get_username_password and + * #MHD_queue_basic_auth_fail_response can be used. + */ + MHD_FEATURE_BASIC_AUTH = 11, + + /** + * Get whether HTTP Digest authorization is supported. If + * supported then options #MHD_OPTION_DIGEST_AUTH_RANDOM, + * #MHD_OPTION_NONCE_NC_SIZE and + * #MHD_digest_auth_check() can be used. + */ + MHD_FEATURE_DIGEST_AUTH = 12, + + /** + * Get whether postprocessor is supported. If supported then + * functions #MHD_create_post_processor(), #MHD_post_process() and + * #MHD_destroy_post_processor() can + * be used. + */ + MHD_FEATURE_POSTPROCESSOR = 13, + + /** + * Get whether password encrypted private key for HTTPS daemon is + * supported. If supported then option + * ::MHD_OPTION_HTTPS_KEY_PASSWORD can be used. + */ + MHD_FEATURE_HTTPS_KEY_PASSWORD = 14, + + /** + * Get whether reading files beyond 2 GiB boundary is supported. + * If supported then #MHD_create_response_from_fd(), + * #MHD_create_response_from_fd64 #MHD_create_response_from_fd_at_offset() + * and #MHD_create_response_from_fd_at_offset64() can be used with sizes and + * offsets larger than 2 GiB. If not supported value of size+offset is + * limited to 2 GiB. + */ + MHD_FEATURE_LARGE_FILE = 15, + + /** + * Get whether MHD set names on generated threads. + */ + MHD_FEATURE_THREAD_NAMES = 16, + MHD_THREAD_NAMES = 16, + + /** + * Get whether HTTP "Upgrade" is supported. + * If supported then #MHD_ALLOW_UPGRADE, #MHD_upgrade_action() and + * #MHD_create_response_for_upgrade() can be used. + */ + MHD_FEATURE_UPGRADE = 17, + + /** + * Get whether it's safe to use same FD for multiple calls of + * #MHD_create_response_from_fd() and whether it's safe to use single + * response generated by #MHD_create_response_from_fd() with multiple + * connections at same time. + * If #MHD_is_feature_supported() return #MHD_NO for this feature then + * usage of responses with same file FD in multiple parallel threads may + * results in incorrect data sent to remote client. + * It's always safe to use same file FD in multiple responses if MHD + * is run in any single thread mode. + */ + MHD_FEATURE_RESPONSES_SHARED_FD = 18, + + /** + * Get whether MHD support automatic detection of bind port number. + * @sa #MHD_DAEMON_INFO_BIND_PORT + */ + MHD_FEATURE_AUTODETECT_BIND_PORT = 19, + + /** + * Get whether MHD supports automatic SIGPIPE suppression. + * If SIGPIPE suppression is not supported, application must handle + * SIGPIPE signal by itself. + */ + MHD_FEATURE_AUTOSUPPRESS_SIGPIPE = 20, + + /** + * Get whether MHD use system's sendfile() function to send + * file-FD based responses over non-TLS connections. + * @note Since v0.9.56 + */ + MHD_FEATURE_SENDFILE = 21, + + /** + * Get whether MHD supports threads. + */ + MHD_FEATURE_THREADS = 22, + + /** + * Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK2 is + * supported. + */ + MHD_FEATURE_HTTPS_CERT_CALLBACK2 = 23, + + /** + * Get whether automatic parsing of HTTP Cookie header is supported. + * If disabled, no MHD_COOKIE_KIND will be generated by MHD. + * MHD versions before 0x00097701 always support cookie parsing. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_HTTPS_COOKIE_PARSING = 24, + + /** + * Get whether the early version the Digest Authorization (RFC 2069) is + * supported (digest authorisation without QOP parameter). + * Since #MHD_VERSION 0x00097701 it is always supported if Digest Auth + * module is built. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DIGEST_AUTH_RFC2069 = 25, + + /** + * Get whether the MD5-based hashing algorithms are supported for Digest + * Authorization. + * Currently it is always supported if Digest Auth module is built + * unless manually disabled in a custom build. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DIGEST_AUTH_MD5 = 26, + + /** + * Get whether the SHA-256-based hashing algorithms are supported for Digest + * Authorization. + * It is always supported since #MHD_VERSION 0x00096200 if Digest Auth + * module is built unless manually disabled in a custom build. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DIGEST_AUTH_SHA256 = 27, + + /** + * Get whether the SHA-512/256-based hashing algorithms are supported + * for Digest Authorization. + * It it always supported since #MHD_VERSION 0x00097701 if Digest Auth + * module is built unless manually disabled in a custom build. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DIGEST_AUTH_SHA512_256 = 28, + + /** + * Get whether QOP with value 'auth-int' (authentication with integrity + * protection) is supported for Digest Authorization. + * Currently it is always not supported. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DIGEST_AUTH_AUTH_INT = 29, + + /** + * Get whether 'session' algorithms (like 'MD5-sess') are supported for Digest + * Authorization. + * Currently it is always not supported. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DIGEST_AUTH_ALGO_SESSION = 30, + + /** + * Get whether 'userhash' is supported for Digest Authorization. + * It is always supported since #MHD_VERSION 0x00097701 if Digest Auth + * module is built. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DIGEST_AUTH_USERHASH = 31, + + /** + * Get whether any of hashing algorithms is implemented by external + * function (like TLS library) and may fail due to external conditions, + * like "out-of-memory". + * + * If result is #MHD_YES then functions which use hash calculations + * like #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_check3() and others + * potentially may fail even with valid input because of out-of-memory error + * or crypto accelerator device failure, however in practice such fails are + * unlikely. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_EXTERN_HASH = 32, + + /** + * Get whether MHD was built with asserts enabled. + * For debug builds the error log is always enabled even if #MHD_USE_ERROR_LOG + * is not specified for daemon. + * @note Available since #MHD_VERSION 0x00097701 + */ + MHD_FEATURE_DEBUG_BUILD = 33, + + /** + * Get whether MHD was build with support for overridable FD_SETSIZE. + * This feature should be always available when the relevant platform ability + * is detected. + * @sa #MHD_OPTION_APP_FD_SETSIZE + * @note Available since #MHD_VERSION 0x00097705 + */ + MHD_FEATURE_FLEXIBLE_FD_SETSIZE = 34 +}; + + +/** + * Get information about supported MHD features. + * Indicate that MHD was compiled with or without support for + * particular feature. Some features require additional support + * by kernel. Kernel support is not checked by this function. + * + * @param feature type of requested information + * @return #MHD_YES if feature is supported by MHD, #MHD_NO if + * feature is not supported or feature is unknown. + * @ingroup specialized + */ +_MHD_EXTERN enum MHD_Result +MHD_is_feature_supported (enum MHD_FEATURE feature); + + +#ifdef __cplusplus +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +} +#endif + +#endif diff --git a/vendor/etahen/lib/libmicrohttpd.a b/vendor/etahen/lib/libmicrohttpd.a new file mode 100644 index 0000000000000000000000000000000000000000..cc1c6fc22013df9b0349c09f0081012827088932 GIT binary patch literal 409986 zcmeFa3t&{$wLg3&6CfaP0;1xhI#Sd`0W-YJ2-*xu;Ec=w6;NzzhmcH2YLXde&LI&& zgEIr1o{n;>UhUg^z4zAEK2R(2P)QJzpw{A}YFk?$t;%$4MXeD~$^W`QR$_m3^^)sf_*c;Rp49K}=^LbinSXB{ zk%o!C;Ztvx9DgCDDqI_FX^GUTjnS5HO;b~}HryO(j>fMGOBA>|qB;@Q)HG?4#Lyw( z78aJs6YCg3EKXB2dW{wvl-RMt1W88*nrq_Mgln6kiAWvi-x0>Z9ID0YYSc)$sV1R@ zYmoIdjjG761HYlBrLHLwjz?l>rIv_ATI!rd$N3xtXJD|WHAfuS z464Oe$7||PY>u3<(yWO=Fpd(fsdM63OsS2{k*H=fDc)z#9EdS{rmepMDcr~z(~$jm zv^kuJG@(LF&j&PN<~`h6)5sG=S;y6IT@5Oas00o`cuft9kx-*CC(gB6Vyns>CTEKNpEE0}2X5n6c^?2_k@UHLk5$ zg?iiA5^JidQ}RQkMq?szU!!xKTCQ(pU>6sfDg;R0+8FNJ9C8 zNq~t4mTX>x0U^x}(kuv~2uH5fP}OQtftw-;A-O#87H&H7gg{Tij?jjhL|BbpgBm}W zW*j=aCURWCi9FHOXjp@Bm_5_x#Rl0dv>^e8IAgkn=!E6Lbda<#0TY;%C}@Eyvfsue zMSw{T2S782KzYqcmUKQU)Ex`P!cFOJs2z!o|CZ50%c zi_Jlmj6SQ;)Xt$wtU;CMMd>i&)Vj4mC`~oj4bdJFMr{-gx1+gC5N$NlH9|G$wV^H^ zMw=X76|EDkHN&Ex`bN}v&NgET>RZd-skuNw)z_iIssbfidktf%Wfdy_HH|H+2f`a$ z8X{=hnH}L&c@$?}oN#Wv!cC0{6%|VGp+cF+P}FNJwNi6K9e=f-(5i9UNi3Reb{Lug zJJk{uz8IsGAECA(QhSY^NsB@Q9F~Z)iRa!x7>0u^v8i|ch}K7;F+2`R%I0P$S{!aS zr1=u({0#^}SumT!TU;SG3x~D7rWa(1(F*3C4o@|2RFra!8jjZ2qo7#yPsI}cL0-IA zV~jT+c|+@kSI8PJTVgB=^>xRhOKLqdcdNAedQlX4)8*l)Ffrab9t)|pQEgzYrsY~% zN_VViygGjxi{Zi4hmO)nH8O8-q&cSYoCp_?dE~-}vWh;^7OBlz zBCNt;z{VD2omB*jc)TBHY6FVY>^|_)ZK-L7JWcVN`lG}`8q6CWy+%l01Wg?CM@Fo)~7RPj%r zHQUA(?~Vup(m&2D@AUA%cqXiWTodYuk7ge&*dUdGt|k(#(Rdxt|EFQG+;A~CP>(50 z2VOssN*4|ss&kCg<$IhxW4ZvZ9M#mgs=2W?9;MDo9eV#$Z8v3F^uocxsQh-nIWGq9 zsO1eZyT^G0`49_rOY#T9TcDl-b$n~D84?9<;m~35gN6=d?o49H@J6+E$gtXIbF4-k zGMM>1c|*-QlQ)q3BW_>wb4A9}va@+9tcK@Bikdf&SLY#vo9kxfjh1MrLDd;5NYt0S z!AyV6^e%J`Cqo;Zug-Dh*)#c|@

}`MB1u9Cc%LaDIWyg+XS1xui=a`^|(((!rB# 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

AW`oKUvDNg06M5?! z>c5R;{=MPvrtnC=zJIow7@X8s)|a>@f{CtF1(D^Ip43%`@{GnZw@KS#Ml~_>!w16Y3;~V7XqDq<) z&SSw0-lE<^%dG9APSfWeTFO|d%>9AEY5U2>Uh++er))6)zYc%Fgh`*Q4|Cx~+=)5- zKFon@eDk3Kvs*yxDO{OYThgrE7mb(pmBzP~#GfyTzgigIM+>7ph1fosPyhVoZ)iEP zctd71UYiw-H%H9kSaC0>C|;RMYkJYbJTo(JuPW@tQ?Vvayez|u|GYm99iw;}*3|k^ zk6AJf9<4xPKT$s1)t`t8q;dT^XTFSQ zOS`hO&Ec;SFX@_dHz0qaq8N8Y-En&9yG1TK^F&h6f79=c*Z)MwE3)hx*{3#l5>TW(e8eh1fKX>ps zqpL4JarNyXEl@-El5O~+_+AR$e4^L(+1wDVFB;j@`hH5&Xj)CJTLcaaRy>?J-MIf>joCaw{hCye=Le0Fqsj5Z|fE5HQSD?s$0}p_yqEz|EzW@h~;!5pgZ<; z8-y>lD+m|o{Ru&-5XDY{h!?+ZHK~q`oHun_`UPVnC2h~A_Ggg!{xeCGw$YS#OS)p& z5fsuKtFAPyE}QCkioG zjaC;Pd!a1<<-p5yX+Z7ErV?m1bTeh+1_;EOypGpn4P^gG^hxMKvhhG`QVtr?bSfxX zfI+fjL6HfA=<#IN$kMWszTViel!C#_)k4e^Uq{SDujy54e7c(K;(>cgv6%B~rjDlt zIr~xFksF)|Ue{?zQK8KY>QG2Eo+5 zW%D{#zZ@J-W6v|QDNkZZVJ_xD_No2MqKb?jt_io}L&9GCWh%Dec6^+eR{txBf9Of2 zMO}l!{lzU*+1=6`ySt?A;L%MnZYLhMImu;$T9KPeyOyAWGz||v_{@tiM!U@2?EVwx z%^T7_;TbM&pN<~fKE>ZG9C($qzOo13)~4Eu3whTqG{N+GxE+l()o)ap^-1m>pU`jf zFWf$Xq@tHpWi|addP!qW({8V;kus2q^4nDPQ}OvF0qUwP>7}KVEqMl)K^OJcI-ZSo zE$k}^7d>z0t{BpKt3|XFvqx75oeG;WiYQi?#U}n6`cK)E9-B)4N5pFB|FPkY2ayCj zq4hYr#S{gboX7q_br4li9o0wD;?QPOoq1WjS-vO9D9vqU-C7sZO}v{36NYk^MXx{|J8s9`RlW;?PqJtb7wRoc?_ z)`uL)WjNe+;E1Mr=zJWN_=L>xqXp@0duxvBYbx0@pQ7it@z3&^@qvG4OrvkB7OGdM z$sc$bIr8#jn20GnqqLqmbx(ED)BX#{ip|2<9=-$ee80|v;DRw#4`CQ&eqUMJIpI^e65z z?WbZ*dH-ff*X-;_(i#H~+ASGWNuZ`SwRr3^)X{FeEEJnti2t>u8qbwQ%&AK zB79mA`kM=>Vf#~TN@3d)>aXoBoxCKg>5nB{OXzB&Wy*P2LGgH%Si}|$zg#@sozj0q zUeD$sRW6l8c8CepR(RaUR8?Q1ox#!d;(w#g0X5L2@hv6sUwHRzT}d*g+4PHe?80pY zSPq-!r#o?!uH#G^(A3&tlGnDaAaB1Frc!#0Uz+oJ`cI;IHX2_*F|W#@rY>vSv<6&Q z(Ria5RQ=LwvG0_7@mbll&~h|;Lo{BL-4ms~Udn+Bo;h$%QFb5wk7n-9y9Amh4VihPCZ7lKd!kSy8;F?Sq^< zcTtgxzv`vD(Drl&rJ%L{jjpSk^Li)(=}kw*f7bSPded>_85QoRrJQVgi^c>M$kMhg z<(tWrbvR!yg*#s)ADW`0-Vb*^!}}?;{}}E2r*GCw>JHHN8K^YbUd~F2a^jp#4mfAq z3TiQ37I@yybj}-Uo9RXIhS=8DRx(NFtC>zqL010+el8NtXZ$MarJ}Py`mW0HwoS{z zzJG?RJoGaj&+AECt$4gslC_m&our^Gr3539Yv_nc*1=DhEV{&LJg$o4nSQN~yzPly z;UtU7uuT?yf5Rjs8b44Hzgm(-yE*9pAz9S#GbOh)ew#_xV}sKL5jcFQBkhXv=E+D} z$p$*VaQ8+hZ;FPeZtA)>=EbSk^R!>PQ;cqjjq9)sDen;tLc0zv&6Dhzb5 ziF1v*ZZi_OHiL3)I_KJSlWXMnkQ%>4$P>aykLPETH+hriXA>=$M~gXl{pw64E* zVvl!JFV>)^L27f06r-7CsLMY3&nPwLsZvwwC!Lm)E-1IBnzG;`s($@kICR;$)0CYb zQ+ArZr#$UzPObU(|5|$TdZ;@4QcuUTk5eBxL~HgBoS8^0?a{X~!tGzCoy0k8`+%mD z;)Kw0t)NBe2f|;XFA~tVWN7XNm0{#(;f^P0TM{3jww}*6`Tf!oZpUMbL6uz763;vi zZ_1*n!WyVm@~AnY_V%-t{yo>LsIh9y>c7dxc4$Om1(BaMO-UL78h@AxL{$|X@7A!1 z0`T!s+BPkR5<{iVRd5!I%r37)=Ys??_?j1Q_N8E zg@CL}67xZA`k4U{UO;(RMR~ZOlJe1HUSRX?M~3P!nqIosbWXmD!wtrHPqW{>bqtoP(dYrCG-kQ^A zmWw}d?6l1OO^MvItxZEoyuzdDg-qH?2}H|7C<|H9QAVYeYGNuaCFl#sUp6-_ zmh=Wi>}-tQsEC%dZ7rZ_Dmp_>CzzJLU(#n!m#ORrjR!lZt9VOK>@ze}EROHQ^8Uqn z&(fz(@}8y7ozRCzqBL5hLfb!L-g2z9UrZkXncN$jepT1(PtoxD_1GV;?wazc!Y5FP z(V#MRK7C81ApFIx&Dr!Znx@kV@B4rb+#5T-kS6@%uhAf)|1sz`nrZ5`?ZbiC#hx9* zlAsrFXrTVQ=f#_|Fh5BCoZ^l@h1;joK@v`BnojpzsJrh~?wLTy?-SrEHN!xDJcXZE zp(X$2V_l|m@Hjq6K9CvyR7ur`W?sdwrtxu{O~shoUP2|dDE_v$>FxBqfxP`T4~l#H zk6unSD1BexgIINGS2RC^zQ_>!Q)$h0kA^CdP;6A&N2#$$+eay}QB)jwC)pFDsO7<~qV{!_JUi#81k5(x{pBO9Xe z+|sTmyGgiY+x^(UnNm)ZTh^5E+1TR?se(DY7zN!ORxQpl372hkNQ z?s{-9ZKCn)Y#Pm$#t#h4%r)>+<{(M&4$sF8JGP$h2!Dk)OPx zJ2ALLMyD?R8>%#Nsq)B|I-N&0e)0Y^GGsUY(XiqOsvG+^`s(^|FM?bmYKZBDl;6>1 zcNX~hgX;YUBsOqW12yAx!;zc7;`V{2<8TlIKBr0rdV!EH2=F_|bWO{l#v(S1ay)CG z&+GarP9bdaEu3iA1kA1EMZ3%`BpJ_Q>L{K@IiFcL@JpNk+K_VmHvyXHs~*2eM1cE4 zhq$T^WY{bIP*>lFhbfmzv)8CW4y7-R3?j-&ixQ%K1u1bqzgQwCJwL!X{eHgg&D&ZBBjtq8NRKqo#^T zWK2`TZHwnr*NlnGq0e^EH#_*VA@dvYz#o9TsTEmBE0U9f>udnW1YYIx^(Vd$(o{d_ z045o0LJMkY8qS|nH~)^BkO5;ORN@cs;~jj0M)6j^x0pkGG#^7J)_+dW`KCtd9f|i0 zJ(e{!pFC6Oe9I#BH&zzUjKx^C`v^y`Bb#rB)fSl zGGQ7%1mfgD8IG9Tp`b|5LAHzjf9SdZT@NHepqz}w5R%+`_*XQdGWD+`G7x`RFYDLf z)vPCx&L0>pbW$KI4<)?<*{g@h{#0a9_GEp`Yax3j%icy3G@a`?*sKzNkB)f`^dt(rn?Ju}=R^7BRFw3OpC9cQ28lzJ;cdmZ7t@8j^_p?&{+ zx#jIn=&&UP=PWxNf^^Bjp5&3(+v2M>Wx0%HS0TVHe9lC+33_ebKyM4nu7K>#L&^e5 zz4@XI;=Gn+PeU1$I5^i{>fA&;A|$ed35La7{t^ zTtwk;3R7EY2l2D-ne=d&`(R7rWYRgG1K>a?H2H+AQ|w;y|3S}oLptagZp*3nt{kGC z5}N8$+~tSE^#m^dk%rp!JHaJ#kb^skeyRSGee^ss6q7rjevm)Y_!95LPGWv8b37Xe zcRBqa|4ZXbJkwgj+|*gLFY$s{&^Lc9KN_1M?vs4O2Z57+lLxn0hq^SgYIP7dJ>Ve+ z(gv+^mpGi}zulQ&c=kQjZ|OrJQ`Zu^hOUiN^VJb68?hVnKh2yS2k>s1qsKj(=I9yB zBd*u%qpeIeU;nU&-1lVD9PS28Ggqfe?0%YA2`z}D_8IEZ%#-y&9JR$zmlhf~6cR}r z^5m}-OB?b;v2fHHgWUr1qTEhqEafxCyofoj6LD!FTm?g2S}1=gB$5`ocnDuY1a@!b zBZZDcn!iG70^ZN^|A&!WzwoB{D_-zH+F(8q`tgt_oV05zX&?MaL+!e_yi0ltWY^z5 zLVNDJA{~5WGi{~M<_pu#&*bi%{H`SYD@pjnNjRQ!8EM`Ip~R3wxrEzd_;Bl?|B}Wx3?Jch(^n?nz9jnp zVdNz=_mxS06t(js&Faop70M+X`k*77`q1=)iC;}Tp~Z-re+!I!qMkH;T{^NXiTr9K zFQt1XNx~m6`qA6B?jhcO+werIX!?qDY-18VzevJ& z89fE8H59r}_UsqeO_2NWSzo&i}Goo*yo6e8_xJj@FT( zH{n7J^BZbNi`nOIyIm-1CdrQfwYPjBlVv9_*Svo>G%oaow+i~?=_2}aT9w&;j9gW1 zP1OSWdYzS9ShKLI;V$#7yP;ufZB)&QII+bQHMi4uRV%9IG}hGBG~$bMvBg!ji%l@v z)raTKudl$OIkClcHTAyG;+lo@g*RHuX92CKlTall+{2B|af&9wg%Djfc^fSRlsF@G zH4Eviz#vo&%At9S7R4y@!Ra%2i7=cxs9e}!4i8dk4>u+|V7SdoKNdEKByPSDLC)09 zX%y&Z9-_lb!T90v-CIg@UESO{RSQB5v09Xs3NzbgKKN%9y6LuG@3oN()J7{N&7ozK z=FOv(X>643nnr_dx>A!S;=_b&eOk8>L6bC;NKt+p4JUvzlhS3=sO zPH1;AB=cqIiV(d9T(h{IYLUjK#s(~e?TDL5CcZtX%ju%UV#o+`_V|~x$~{aMD`e-8 zP2l?jMyD;xLa;d zqkb$L4j)ZFk-vmF;)7n6@I}nE-OoDmZah~d;TxI5?x!66FFEp$L| za*%iHCHa<*mfz**Kg!WB-@MWCX;4fK8&`fbbI4DnpTra6eK>G8AMSCudwuLbd4&1%&>I}8~D%uzMyBzMGuW1f<^~4bcM1 zuAVi_ksT+}Pwf84;U_s9Z77_MzuUgMcBMQ+-nEO@X5qBm?^tZOYgc9-pa<8K#8YOR zz{?yiGe6*N{!Ax79Jm`#%!k8)yYal;P#e!vXkYBg^@#Yp@r{{OUloD=`+X2O!iLWjG0A`W-kQ}j9EP)^+T+AR;R-C83(wA?1EA0Be# zT|NKma5w%>I^2!_8C-Ac{4ZdR_`CAhhXZ%*N;?Sd+MNwya$3*D77x+m=8vl<+4VBv z6Y8mOk!7mP0(<_#~@W-TK)*FOw-eoIbxr78^c?_9eY;IhpHlnUU7{ zaFe5_+L5nuxU2uO4u_1`{V{W-7ikgx1asJ(=kU`V?v``6{JZ&pJ{X+N2k9rkuG>Fc zVx(=mgS1P0KF1ug$Xnqnm_tA63gIU^e7?io>*6yGcdtjcoOd{S-0MQ@>iXfuB=S3$ z>+<;lRoYsG&!(IKyGS~X$IWX`%M}Ll^$GyHTaJZ{~ zauWSge`@_@jviOP)Eh{btA9=s{k0BvuixWL?$~nZmWOPIf5u5K$~K(NPien&e59P~ z{ES*PreEitFDY+Ye-+DX{nE~A{V_+sd%hwL=PWVAjSqB*Yvvs=9-14{?eO8ekBwUn zk8${DC;z37io>}M4?FUe4$pLWr^AnR_63r7prT`6e+ApCZDv&E`x8Kh@#Y4nNJ|YaAYN_y&ic z?(hQ+ALH;GRH)=&_YAXV|IKo^Tq8Kr>hLoidE9@5gPya@p8fZR!%;{3?g+aFd6ac= zxeh;1AZ=wGb;zIZ@a2yD1rFch@bM1+q~E$6bYIEb1$6GbIV(3}K0R2L@4kJUEZ>)M zM24!OwH|Bg=8W?{Dmm!R72Tebn_)_9kRrY>rbL2nktMMscgU26L2((H7;}5Y+=KMz z-t~Pmr7-X&l7E{l5jos%@O8?avBS~j-u}`#8))1OK=-m78}9917rS?vT=}Foo6PMs zN5i0d$AeFPk|-XQnR(TN=C+&@pQM6(hwku2lii2=1RBikzE2>}x9~neh@tli z4=a1^jlDzIv3Kp1kh+1Vj{3!X$UQhEIHYVix6zd7kUMJXc<@cL{}zkRqD@6tV3=FC z(|&>Si%#j7fzt2d8 zLVw|{Y_$DSIuK-kCEH)i0bw6<+WtMn0__8mljr%YZ|E~Vn12bfUw}y+a?82D0sA;d z+Wy1Dg6y{*Ne9Tu^Uu~d)cz_u5M;lPCs2AgAne1ow*M5dAp6T%Z~=#xjn4na=|GVE z+^FN&e z2c^G&x6BXyMbw6hyQJo_~%|`12%Jb#2?q9j{k{N zDF?;Bk`2AW;bo)k<9Xen^0PL;KE{RGel&^w0v_z5eQ=$&e?=1ek;`o;xBeMTNZYSU zVt+N;kGRHZU)#SmiT(Tl`xwt^`z=ZA_ptr%9m4*dN$i)gefRuF0_=Y?iTwtiRN&L- z$3mxnbrSo%0qGwTU?1=D1(m;Uw!hi8Ye zFR<}-^B?m8`uq>4{y|Xs%XpIJ1gpmXuhWm`&4aGLz5*M>E&n-$wEYW{*l%F_@?5w? zK-b0a^zU4!?LVKye(zKp3U=YJ&845V zpH77*$bK0YoD~S{IBkC*iT%uJHjrz7JRxm=Y7+Z<*}l9VAW_ivFQxE7<-eTm%X~WG zF)_e?T@w457+8_J*>3#*+Wu`x?5{1dLEQ9XNTSpKPf6@Iu>Bi+%XUZGUz)`JUbdgh z;SrB~`f2+=Ok%%}?QiGsveEXxo5X&k*oIin0bw6Q5^W#v>jss-ZZy{9900;YMOSSzolGyJ< zXMx;(cH{ro=|7diQxrl4zJ%SWg+X$A?Z((IpnYwB8r#RU>AGu9vpxwg$By$6Y7s7q)4)`cFeRSq6&KlT_2Mwx-cn zV_*#!a-^D6(NE#_MxOZuKdIkTp*%Fwm67F{$> ztEx3;MB|n8O$^gZ@)xh(v>S@!o6N(R9nUtM$&v2L_1D|!A6EDzx;B1t%qnRaiBBnP zh6?MjiqRDkNwfGV$As1-M{JLxl}jy&c3l$fYNQ2vc~u`;$%xk2bCxgKNh>=Y_6jxJ z^$dO7+B82w6lL85cRdKR!iRlk1=lQ`nS&5ncfAX&b3(__FN{HuoO%94t=;fh5}S(k zKCH-)Ynt((%_mt?!PWu8{O~3Y>`NOmvq0|_(=qoQXphjTZVB;nU3;nhhv z<~oD)-$&ei$J*pKF|^%5@((BB-%7%NoP>w!=PaaGbNFR3y0fuZ-ge`;e?H>B4KpW3 zucXbdpC21c=u3FGI|Lz+9h*jZxO;C9;siMMs%+bDEWZ%{q6cu^J5N}xd8tC1@ z|BtzM0gS4;^T%hBfC0gYZxpQqA_N5_fJ%yJ1`@o3Gny(?wv~n$f{6l&$&BEG8l0ps z9j9em-P&#+^to)GbX#3i#2`q5x*DyvTHA`XtxU%%x;{Xy`F%d;G4q|9xk|U&|Nak5 z?!BM$J>T#5yw5%Nobz2F9kCcljD@XpE zrnB^)*6C*+o&07g;M@ssXVBfnCDxHoX_dYix`>4~!P2oD?H zLf_Qkhm6_BnDCn|p}AW9EzCKQV)1V;5`VTkHoVP$&Z!m~vu`u<-TD@LE*8~Z19q7J zY^zu#-10|IK7MXj!$`sP=}YdfTfWzreVd8@J-Lwj#vT6bSu@NST#nP_ec_nB>YSNo z^nUnb_N{zbF|I~kYkcE;!6IXJT886lMcBh|*1yj}7Pxf@{^F=?WjTWT*S z17u}}y>(S@MbdQx_ppmnr?TQOUp*Yf;hf#S0Sa3?y*OHTz|rR0?i~kAQy^^Uemwaw zsQv`3jNt{~XWzx6I+WFna>?b3z)cwauxUZ{vq&{%Dt9ojDwli2a(5Hg1(r0?`2Y8@o2cwenV~I*7ZpYtbf+Z}wOot&J zxZ9sNI5IXZad32?rw&|TTdAbu?5_L13D1%7iJB7kh;iLON%jn#9y#9h$yR78W&x$H z*u?Ba$>#az-L!|{q-Xh&Oh_Wwsd&5~O>ji-GMfoHy^i zFYKXh9QB3nVOyGMWReShw{quh;6MFyr%uJSXC|JE>8x$G76y7w1sd_Af!N0JHTgI? zq5D*#Gg&gUD9PiLQOX0|6QSh2lv+@4nOLLXgM>n{dAq<5Qvp06IM97DHAwX4Uz&41 zJkuw4urLliW(}lBW35k_`%5Oe0O}-R)ieoSj|AV7*a!fYK~$pL%ibmvg3^77J8??~ zul?!@o~*1#nSyPOkk?$90vR^ENW~xwimlD1GW*cbJxmP4CEAaSLY#V@faN^gChlWC zBb9gJIWryObIvL#%Zt59r3Id5`(h&!{Uy2Q8ei;)t`t=)gD-3Zb^jdq8Y$0g!9DT| z>cWZ=CsCc$7rTJj;&SUI=#$T0Zf{4EDzbJS5S_K75Nt@+5>RD5+MhWRS|i!p0okH; zFZ=FXY;|HY!ut@nOf7}wk~G?{(~qMqlPmXvN`vg`Eo<$`+{}C#1XlU@35Dg71f1%@ z5%48(98v!G4isRNkKe<-mB}}FPl!xD0Mo32?mDn?{B;AFc{!mV_hn|{G2(BA#ZR1& z|5|2}di>y$&KIkEtC8XByHet#>_bpMts;3XrfV%?Rn#DRHtTMDvW_{G$ex8#Y54`*x06SXQ9-lTaNs1?CLY-)*pBM=Pl4Ubke2hX;2DPVuj7Jl_94D(s6*#)tS=2Ju&YBZ)3bLLQV+)x;B()}xl z^gz{K)zp~!pppQ#^q3mP&Qogf);)a-33G!7m=O2k z@#6HXpe99u@tF>To?p|n%=}!MF#j{%@F2m>xOS;C?S1icU7M4g%uKoPtNg{~prBPot2N(Pl2gQ?BjgF?>3T5T8u3m@00+ zMUw@CaHjw1{tI!;Ok+sDYU`!x^HE}+j0Wo72~WoGO^@|1Nl&>jTKy)BXsQxu4E-_9 zt5EQ6vIQ?YGN1n-hh@#JfyC#)o<;-LX@SGyF`MgCKRnkd!sL9^zt1#zNci4JvKQmy zZO-HauoZ&gqZ5cchDg99^kce+z;2l;A3EQB`S>aW?6dO&Y7ClLpi%c!1LF)a2{MR0 z`-eAy)ZqWOPPNY;znr6>7PQNW2UwJb#g8*%wtID<*25*dWnpB};)@@n+uT76d)~s! zSO_*>ya!jt?gO$;_mlkMLas1Loi{&{OCRc^KCL*ZTc%U16W>w;CVxCXNK^APW(aEi zON752FV=|gWx~IP(h%Me{^i2oQU1b?-4&sa>-W9&FIS@C;X@kC1Sxx!??h5px1e!x zlIsRyW5VflrzDxtfdivp1T2kAsvR)TE`` z0zFS6!6ViG9Um9!x_2WriJu6iVapwOq22lLtMY95VQ^V(%Bnzi*tbkR}@*V6l`0`FuNxhh32`vf@cC z50(F}`?+YK_NBUR4B*d2KN+}tSGuewvlzFbzFS%C=+vjmObtLz$*AcU%yeWpbD;pX z`vla?#roYWj-tJD%}<~(eq%ENIH^mQA!4+VK3QdV-p=wo43bXgXr_WAr6bXsM5BuO&`jxA6L=|7*`4R6=`s07d zv>?|o*K`#8b=1Sjy4jhFfnow}Y_3HF>SWFb3RXkL%eBeqKy9+_DGq{>*1eJRPd0-N z4Nkw4f}OTxbeoe7m7%HF?4;+vhwD}jo3(Wv*zH0kDvKunglV$Q%Q1ewIDPXu2>k2F z%=2Te0icH?WzIyb?sZ(ReN7C(nyq^z4$d0|)6VaS(%^r=pzrywc z$-X(_KLDaN%cAKOW#nIm?t2Srh*LZZ8KH(R4A!R7itXdIIDw~BD7do zGO!qtsx3jR{PXv8pT`LMvYcTekNEKLoQ5T_PpAo}P}c*hcE+k`C>oZ?VXyhpnrP~x z+0oRcFzsvVD;n^@HSK7`2d^kM)$-)fo((E!)W4=3(ZFbDx+*o<(aOn4t6jVjH zg8Zs?5+C)&0 zH@-hoeJ}=FT!X>*Z|8O09Q2QmCnNrS$g>g@wjJZ4A%xgM*N2dS?q=ozjDo*C5cY$k z8HK~@lJdO>zVr6f&K|@&3=GauBrLWSMnzj)YH#a|wRf~N;pEr0j%iK4m91B;YHjLh zYl+3$mj^@j;o$YHZ7UmNt!=Am8OT@@T66;r3B>`DD_fhC*V${Qu358Y>Wa3GRa4_U z7#608V1Z~=d}XY)9bc}`Rz7O4;Z<$%)yo?@ZkUU&wf5M^p!(tr{`ml_TGxUBrnjuf z<*l$>)Y(c!J{nXX$JH6U{D7FFi9s!R+8{$rBf*c=0TuJ`%n8|Vv+lJTQ;;L4m~!)d zHj#Gyg;=Xm8usUGRm=iO#L)kOF9JpAOD+aE%>!ML3#Qg?benMBV^38iT6Lb$C%sILgZnsJIOxC z6^mamt?fQuUNSbAV-n_;m(nc)Bz2BW_)VxnVgX zZlBGvNab71KFK-ok@iDWnE)0weE14SXZd{`_a$mofr52@<94~iZRs}o0E}xCO0e3+ zI+dSz;5;VvTxUG^jn2AaYk25a%-+a1ftTd8GiA##Dpjd%9>k@X9g?5GpZeTn=vYLp zD;4pz7_Z*;N%HZv^xJSl{?wQ51by*6h%52`G|%dN6!(wfSCXUh`BYg2_G|n|za3Y) z5&Gi$1Fpm$GS8fIr+WoI;!mlkd>g~Z(t?vM41vO}c6sa|Zsi&()kYCRLAPZiPp!}G zD26Zep#PW$&U#&pPlE@}{c*+U*8rDmu2h=|g*ST8bDFFeAMSrEhJW1y|E>ql^ee`P z(}l(GT^{(;z>iU@j&$nZYBJ$~2mRX~xIH+2hP@ejSiL=f-cnTg*wZ(duD(HZ(&oha z+3K+PhWKh84vntYQeNMYqE=OKxVVf>n?418Wn0^|ahz$LKj&KOopOl8xTE6kP zxAc5Rq$7X+EIwE0$-cqj$C5D|X_*!luQxa^q#uPJ-7f|GS$MYeV_68`=*=;T#m5=k z9pCc=z0AkCf?nq16$0lN$MRn#aE!up_$>mL`M%fSOlQtISU%4PddVk1LO5PHma_Ce zH8|rX)8Vgz{zO543L^s+Y;6ZxAS^Pf3XM%=vxJ{Qz7rx8TvrN)iJ`b4kB-;VT zeWJnn{zhl%?fK=iHJrm=H1y}YaBJtW#)Wf#9bK)y z>b2B!v`Hto+!F*YMf#^m02fq$^ZaS2 zi*ACxkKKPJ>lf)yG4!&25f2(%)-U1{3|@nKIvd|g zgV$;}hfguMtY75A{oZu4ei5H#@OtH&=Re!vi(L5m24CXBYYcv+3$Hc!G8gU`e7Osc z7`(-W*BgAL3twdLb{D?H;4v3|rNP&_@MQ+S*@Z7Rc$W)rF?hENUup1-F5L3D&4qu* z&~I|#YYl$83%}Xmce?N{gMZb9cN=`O3*Tt)@3`>W48FyM+w+iq=)!L|^jlr{od*B8 z3qRG=qirsHoWZxd@G}hF>%u1+e76gqYVdv+US;q{UHCZ$A8_H-27k(h&o%fnE<9xL z-?;GICLQ*<@P32;!G%9+@cl0QHG_{8_;I+m?RKTX%W$m_IOoaeh|BR_vqE*BDaVM_;NLJfd5;(PT?QxpNdmv$;7tG11TM=b^VG`yg$MlvqbK7k<;ro+DT0q3&r+XL z1%8zWpRb5?m?G%6df*E|Lq~n&d%@!h)oCx^N2&xa--BudJ^}YO9U=xNe~HWVpCRaN zIx}Bp3j9^v)49t-P@%fNGf`AXy}--OJue#t&iZAYY{xivZk=ogSnqPq2xGp;+07{e z=lhyw{Fj(k|Ia_)b&$IUe>Bet>e)J*AX4w39=<0r3a9=__7R~f2cR!*G- zY8ZSlQSP)@d(xvM$Lx{NQ(48!P4Nkjg4sS9!g>^$?8~24YKex<6$%lqi9QoGOl?(7 zgJI48lP!O2Q&>dIYhkW<)a338Z`eLbHxUmX6yDCe+c2_D5F3XddDh@3-Ikz!syF4A zWtwH!)-|@ZbQj}SOg`t6>Fm6@e#*a}+vf$iDJK6Q6@%MPp>UK>I=6hj-&2$!!<}}! z4WVr(EbdOftKd;g{=Nx1#6A-b%4Z(A<@W$1i97#-BLKqL?_>IDX#Bh2QA~a>GZwB( z$fs<#{4KzW#lL?vL;HL$>r3vhJO1B>Pciv5l{$z$pMvopiJx2ke*r5N|6ab7!riJb zxxeo6*AJg!^7}a$fm^FDD*s2}-YuWsxr)iJ59olKOn7^7%YOwP#pKtpvxHlw{_66_ zD7od2g79MU_Zj)>+qL1ri(5YJCKQvu*~qv0GyNIXE&mJ;`J2oqMf?4fvgzFNgC6py zpRMWXPe=J=>6Xv=JCeA|zdc_~eP4&ab#D1}9`fs_>k#Im4sgp)82KFINcZ1n(D0@NaSw9k?DY#Kyp5;v_U$)=i%JWas|{zb z|7ya!$b1#Hfp&S=a2Dpc5&wtm6}I8GxdPbu+webtf3fmgVFr@V7(%8W`#Kxms>c2CWO%!c1b<={B>3gYLM&t}@Zvf(c8woqZX_gw;AkG`WpQ!M;` z6aRi!0N11M>{;hd4+Q9aNdludZx*q7|Q>@%c zZPAQPlojX{MatjU}EF`<(p@UcS zK6LPCthrlv01Kg=`^N=IfHwg>bC>k`+(MBo#>2E;^2r_27iOG z7rBq8`u)!Kuv*QFcB(vlFMD;0g9=vg%Ilz6;aSzIm#D!f z37_yF7MC9EJZVAT?o&#_iFfC$`AanL?Pog{;_t6JU&xk*lLw>8ouoM(*KB!saA&0Y z@z}8laNNjH;+D+dp)=l@v4`5~Mn9=b}bWXf-&5Pkwyy9LC z5+Yc}{0rpi6XDdlAQp~u4=SH`hEsKw*tUyh=&5KB>v~63B@P8+!xD!^#J>wXUI~IA z*J`Gs16Wu|a%@-2o`tX(vnV?0JL>V(nWd9$fGM4U?(Vs&~pH5tetfI7$Y`*3V<>9{l=DH&sTON*76QM7_I(Q ztd?8Ruv|MBdqvepRyAe>s~WR`4i)OUBcNK*s&)l@qRDr%rQoaj3v397PF$^QH&`Xt zZOv9Fzi{%`-01li3>YHGUqq9CjZS_#@EJ~LhPuulGdK2YC%JSRh^n636iv-~Hk|r+ zd8GQ!*B@Keo9%S1HFr|ozg4N8>{$j`QLchrycye)ux|HUEJ%Im;2PZ=pfsOOMq0V* zKSz^T*{TM}@oKC9-kLpLt=+~3B|PLkvF3g=buB~Tat3!fiFZc@daj0~3>&5pYQ%{S zcD|7;u;Cz5$=RV=tO{SH6ZrOHWEM!&G8Oz!MylWGI59hcF_;!Oty?9kGx#9j&XdTg zf_3W^)U8+sSp4YBW{_aPEFJ>gx8okEQ-PgxY}TCgLVu+CP$2OoJ|rG2agtADPel8g zx`S!%q!*3!JA*s1C8Q+Q2Ih;(2ib`2V|(^o;+^sF286D`CYwOwXW&rvWH|XS%E0** ziNPylBNKz;<0CWQf(OdSfB5G^F7^(;fg-KS%R3C%F_3wYK=R4VbGYh+%M9QaC%k1# zox#0e2_c>5=2iqZ+<5*j;-8(=aY1%4l2 zM_4A}*Fme!mGm$*>8xAMPaGT{JC;lTGyeuMYzL`D{E<~*lXqX}?YtRTb6k1iohxI1 z!dVZikufo>hkrQxo5aB>v2lrmbK*y3R{_}Kk9|ysXZpR<@fGaug)H2L6HlUM5<4aH zZ`OTQIW}cj&~sxSQ$hu63JG>*E`-Tz^Y! zMmYH!N1usz564xx3KrV7yHQ8E-i?7tYKhP+nG-?o zn}=JH@i==oS$UoenWV^gDyf^SB2Tv7kX=%QjHN=iI``db$Y_JW&F#n>S=HX|-ut@o z7^rFVA^~(&%p$;^!cpLE>+`9aLay5 zmC*?{!O7E=;D&R2RyeVPI+Vw8QieK1!@<#y=J1<>L{im5MQLv+`8oCt;cA@HqQ)NB z8?xnk3>?L%HJ23J*Q+{R+Xb)Ry&r+|Te3j8>yoxuuz7V`{OXn<7WcJv+z@PC9gMX! z2lML=Cv^tf+uBwJV{JjTys$CW9K;5Q;Jn7p)}~-69&2gqXuVNwoCxZrlR<2f=xkkm zHMT%30;^(#O)FbrnGCE=h?d4qNN#HD=xA<=k^QR17=r&D>eaSh-P{>F9Q}$?9;Sji ztWQPJSCAII)orVrntg5Ujn~DoyJY3nNTpcIDxWoqBFEI9 zso1cB0#V>p+bR(ET#T8D%u%qUO6Pud)4TbzNs`X}?3Q05iE;0i=kosFd;B~1*aV>o zztz!Qhc?{zsiP`BQ!;<_@VZ24=|b)g*|q0@`&|CJJjZ}^V@^KhBf;?#CRUy~#mo{CE$+Pbnw0q1 z&S|Ig#x19;{33UjX>avilDK`o(BQlj+aod&IO%Jc9&qfG=s2ZF{33(fax&ZC)}}M( zS*&fQ~zSrQK6Qa8lKkE5wgR3_VVBa$MO9p4JN%uqiNN;UMTRrbK_(7N4UV|f$ay9y* z{ubN&vKK!7+zyb!x!_WPTQ+}G^c*EomGQ-C)QFFs`#R~V0t2(E}u2lyMciLc8)%I>iZcoV! zd`;F&XXJK~%*gE`nUNDYBPVl4Ug&u??95`~)$pPrc5N{~J#6vt%nfEd{Ou6O!`qH` zKFqs$ZOns2jgvh5FnaRv!I;X!M~}2TJXbe)crYFumC>7vB9uwl>l&^SS=^w{ozCy! zQ6uOEJ=E5owUJ9NQdC$w(BRtAb5-l=25jpQ%w_q}9z}v(7jKKiDm^sfnesn0~y1d=~{Q_Fvr!QK2X z7W5obS^AHA(02%W_P&;Wod^Aw1wGqyOaC1Y`d&fL-rCYX;z9qCpy#(|OaHnDeT5ll zy3=QZ!QJ_LfuNV^6Y-$GR?tg*Zt$SLUC_(){FVp({er$AeLU#@B)`Oa6Tx^lu1yj>fD$gMwbRZy-^Q z)t>J*cCDpGIrhnf1aK0bXk^e+> zr~lNLd*YTSAxGfsW2~z;H>96pL0p#ze44<6=AQM1VXUh)H^fa-t&nbkk1+S@@;9#a zEIK9;%NUCfZ}V#*J%=7{i`puPS|5r#cup%a-pvg-wE`bPogac87J0#-^sqw6Vd`N8 zkOSAhEr1!y9#){-;P$Yn&2aayXw3lluxRr`;=>}>gXF^^mBZ%43Xp$I`afA#tEwH} zkXdida6w`GQF&g@ znEpXCm16UW`m?>a;Vu3MuwwEnIM{^yF!_5xQ%wHsBJ!CeZu##3D<(g9nDXEBkZ)}_ z+ITYld>?Vk=U$0o@~0oBe111A7XOwa@#py3Eq|$p{F=j*zr;g+R}uLfue;@Qe24!- z%3u9q%1?U8zq5#ZjpxX;%m22A{H=#6pYyxL(!a8Ze9l(8<#SJYvHb5f@|Piubnf=}aS!=5Mt+dY z;VSVPho4*iUyc0fBoZ#j#tM$%q%-W4&cuhK!?Wg?<{Eer(f=h2LW0Pn##wx%EGL*6iw_aMOp}Ys9YYo;7p! z%o&R2@Yi-9yfd#sjk?9UH@pE??X7vMZ+PI2ojYF`hCBZ@rWuYr-?>ZE7o0PSW!}~n z3RZH@fDu$DvDU$wrJ7~2Df-Z0Eb)#bPTjXz89*f=i1+$>GuD8{x$677FP&0ZW8y)uQJ}@`Y$}|9+78vcv0=pDx2%9NJvM zaral^6x@MmdI}D{T|K?)rb?)JQ!q9O=dY^u(#Fa{IN6sy4Q2wAa)F)(%++U_@F$Xd z6$?4F8uRzm&gEj+PtWH0!dMhN8;hbl*HTDL*uOiPTv20A>yM=F>w+q=b<#_>B4#+&*Ct*ck_nj`I}N)5U{}JNE*`G#i;qS``f<{)vojM!Vd-12 z3{0^~>i`yk3tLpXaGEv~JkT=&D=#z0;SV%jmbKp|3d&ZUw)0ag|UdUm7I;hf^~NOF4DElW^j*Emk*WU(92kB?;I>AB$mdAvmStu;LFj(ImfXufh0BQp-5lFGYJn~#tQn6buCI3Y{q(6HcwEcaojKNcz+MaC*_XILVqu zo^BeW^Of0#DuhbrRPT(Rg7duN*b6cr%V6hM_RTM2+e$beGb&Iie zd%vXP^4KU`%VUlBTNZCd%|`>(N3ZxNnK*2q`m*(`95dam-VPN#)9R@WGz{1IqpDsm z==)TtVJWJ`Tf{nE&VC83(YW=gb@YSb^qT1f&DU;hI>0UhG*)jp$p@p!gZmK|Xl;>yqW!e<2l|O^?gb*3T9xG5|l**gMN&x0da>`KZY!D{v`B9!f5)K7orpe4hDw1s zOMf08hUO-FWbRaSRfurLwn|_|9?r(!+FfASNb(VEpn)mDHxn;CfG#NJuuqzp81x5v z`r!||3~Uhk>UveGr0?fu1D$qR*d4N-tR_x@=h(a_OMii9EmrG>(hG3<{vTkAWX*{% zPNKIWIH|IoG(K37xd0pyhw5hn8)o7*lH%YB+P)eZ#Ifx#LV|P82Vs7FH;ZJfj^!tI zCjR>45hIFrZ*1e8Jr5Be14zugh?o?kft^GZI~fp1m?sXF#cE)YBNj{?^v5qX&7z^@ z);+V-IXlbS>m*MvBj8*L7)t>)hBFs&=L}wC&n$|}onBRODLVx6*$w}p-# z0@dPJcK6C*Gw@?cfGbuXqREF~ha{YQ!&HZPtPZEE>TnN&z%&5rg4)msf!yO{RKkE! z`Iw3ze6Sfx`IuUe_em}7PtQjkfL$ne9f(x#M;-Vy(gWK{s`m#rbmG?7AHcW=#sy%n z0(D*8^r4lB%}=~r5}TZOSC@YZVOL>|U$OkNHlzFxX4F!At$YCu^TZtx;~LNMPg;-i z@AeYq-{oZl%wl$*%d)of>?$Mp;~lq z-et&^AND7eRlWLUqj%>%^|BFC+e5Ki@xc6a*||vfNOf=L6bH?1I@%lB7DQ&Kwj1sI z2~K)lFKh$knkyX(3RmMt+lEtK9eR8iV1SjBYeLtQT%&n_ESPqVK|Sm^Dsk|6T2b@I zu%~3{u5BowgLc!U(l>FawDY3cWN%%v-|YXoD0SR=!!wlJ8M^H7**YI$3hG$Qhze6s zlwX_dM-*yPiz{kVOUGETmxnH^SE<36SapZg&yA>Db;571-#v842sF>)9LVPUEKMxj^@qaSf+xCj=v@Z4`phKCu zhQWJR{B&$a_G7=2+|^r`+@q^v9bRg{DwXEO&%wQDybhJF8I{~?c9*2i|E!a$$Loi) zjK+J<2yJKlF<=VxWbq1-J;@cn%vkLmtHc0onJ;#<36NOZazx-(Za@p%y^%vOZi)+Z z?~NU)2{Jsp6pv%lvo3_ddZ+sJjz6Yn-49A1?$|t4Iwep*E=cVr2+& zVrcto6uN#}7l>&fCa~dBaAT|kJ--4L+RjxKPGZ|8JYe5n6?~o4M$R%YCf(ymZJ59& zBpDo~pyySv*$DDJre%-_<%*tbnQCcqIe9<#CZ-o%ILb-h!ELDiC!Oji0viTMome{^ z0sn-L7))TyJK*&=t>{OwB;ysK->L2oBz7x`bz60QpxkXEeb+Wsn4Q$tF3`qSqI1Be z^R38GV=*Rs10uv1UkLex(r)8EJUEG+&tn7UzQC<@N{MZ~06}t|Cg~>$<2(t^g>nAO z)5zM)@uZs*hdr#%kQCcJ*^o&)HMjSMwqvW{V0W*Mmx>c?XQLeZ_a@UZrdeto>aZzc zh*2;0JE?JZ>_WZ67=2Kny9)x?O)OU#wSnSvAxEpe1tQJ9_iVeCm$?xVOj5!sS#O~G z6x2z+o_5{9m*ng4f_y8HWFG>9LDVqFaBW+0*2foxb2=6uC$b)T^pkEc(NDU(@-k*K z4NhSdouAhR8Es7iWv3K}h3+ql5I{$%t~Of1wr ziYIJQu1z&R+TF`k=)MxEz(RDM)7P^Wdg74^4j|K20;d-v;?a$fbloNub4HvWqxl9E zWC}9&Y1N{51pz5S^}Mb*Z;GUv??fI`7{;AC`@+?`13g<6fzm>y@4w@@=Q%19=w1cA zlh1~>zltlHzYX7kr|K!~=EL}%*k{ki)WLZSmq5rS2x(VBUQ(K4=lgkD8X8o3IFtMT zWBTsj?|-v5)cW-PQk;{Zxeui39t~WyCt3IC_03GF>>Sez=1&}aHGVF3j{42U zOd||)*awiO)H*xTV9=W8{&I?{tj6d^x36_wDA=$YZiYI#`{v8rX?%G*+rGT9CQ}pp zN|xoz+YpcgZ#SswPI@zY%v}A8ox!GR4ojJMZDz>7yEzSBqE&$MWl0}$v8Z#Ow;2AHba9Do)?FSgOXSk#nl*b zP=7i!(xpW>8y+Au`Y&f zIZ556-*N0@%5*P}6Fofg$yBry))y^>0u`k&k2>idKA_#@i&$PnB}>t9e`_h!O~V(FeMS39%0#BzJ&63gW=q*bZggeKE= ze?2h!&9-`zlR}?^V|Q|ChiS_A^t@_n-eCb%`-E+9A zAZZumBW9vH3y7X*00$&3-T-;w>Ni}fbA?#}_tuWob3g^jqDgCK*-kC)3Z*(~!l}zat~Zsc$g1BFWf<8YlfVj#r%Il@n&y;?ML5j=_oG zrV=-J_r4O-T**Zf#^4mX+6nl=ST;em2#kH#+6rH6oJxlj<`&w^(T1s^eo7sQWd;oA zg|@%KhF87ZC=aLFDG&5aQ3=B)RfkbyRUHPUitk_y#=%bsDD_-^=IuAYsbDO z&bQ)2FeY1rwaF(EFZe_E`B|{$1>gR4C~)uZOF~CK65=O=GwX2b%v%o*55cB*Xy=Q= zdiLH^0XE@4?IRI<6rWjzqpW(DX2|)&s{8#|(8MX<52Jh0(B-w&-(zT}zCRVkQDCKk z#CrIKaEMl#E9-oir~YDH@)x1Ri+&xC2bY<6)E*=>9b+r}w- zd{pj=eFXI)KBKRv9jT3ei0$cSG;XFPs@5Ku#dCR}w?xMj1#3+K%?l}NQ|l@*c^^vr z;a#ZVk6#cPfdef?gzeirKFjc{9%jJz_~V!(&mBhu4@*G(MH&;7_QybWrVvYhe z14nSG&w#OU$>`5sjPjCSCTUMC$Hduk-Ta_rHOKwXBh z4BWo6eCNjKue$J-@e!5;KhL8~t=q;U%it?T#2PQvoCW3#6VkL(G60@(`KmLG+? z6T8+u>ccmbKjVI6>MmyA;A8i4DI<>US~EKNx^2T!$Ne(wf7(R#@?2DLgZZ-|u?qBj z1hI!QTU69?LqARm^^AiIh&%Gq^vbx;sK(P4k*0U8g&%})y5-|xyD-aBi29C;7!MJW zT8zo4dr$x=2Oog$w6d~j6r5z;ogfIO>jFJbBL5%4iI#!Hx}S4F;XovP&8VKeOp#nE zQ2O-7E=5FF^wpGg#`=6bb7@b_@L*rf5!@@)S2J?us=4FA2gdAIZ4RfSuOsf8a<4r2 z#H))^=P{7VL-#gjC$OsS<^(97M0vG^bsLxUhS!6DUnTyPb0F!K(iNe;vf<;Wg!a@9 zFF~z%&mWtDMR?Q7#?S97n}*F*b3=W#!^^q-AC$GjM`_Zdf-qGdfEHcre&vfbLx+*h zJ$AR+#mQ0AR?P3KomReTE))zY4 zmba~HY+X&(WfRG{oSe(UlOIBq?gaBZ%W}c;NX-(1vBbLFzSv~vp61xx#fuh9oqcgK zGI5x5Pg4tz=ZMWkeoSP3OdLHWi1}+(GD(hO9_I4!Ekkbiu(`?6c#L(nb;cT3HiMix zl2>`WS#cZ1gnHli02c$BHV##?`+SULkY^D0{zC`#LS!C(yr-tZr^XM6eV1DCr50-) zh$dgqfiWR_D)Ms2KdailxJ#pfJ%tJfy? znosa`spFDWI3;iAHNI?JwINk+Dk?pF9=43-_z@zzFn*) zSa^wrpFeVm}>i!Z*y^Vj1e1oL`P%?D5X} zTguhPASA=!Hhk#t1?FS<2!^$V2?q~46`zk^jv*q~Vwa<2MB*oBKZ2@?B~dn!Ug!5I z_{4_e@02(usBWJ5#tt^Mn!-sO9EI0GuC~VN!`xbq9RJ*S6l-RX0BC*hWEpkv!6#7r z%(flSH1q(!Y=ogpSn56ww0IUO7gj=*z}=Aj4o>`y_G1{?+c8!hW4U6}?iX)5 zFmMtMaz3hR0B8S(s~?NM>?GqD+T6DdA*-Hz`|VKjDQEqzUOXXIT44?@VgN2pPgx$` z`Nv_GrYD>oNv<2X6iaR^kkn|O@q%q;p)m9sHNWfTi98ONAG||d7y4pxoZzf=HeNl$ zzz?IlI2Ng!K_P|#VW!$h{GAf$`2)hD(4X@L7j?Q*uV)Vv1YhZ#v+A~T91*y8-`SzS z7yCjxUn&bF`kv2xm!cnd9;uZ13U5=RCV(ExC3kj?OFlUH;lw)^uK73=AK3k^%-fM^ z7Y6$KrI{_v9?Hv~)H4L-lZmKs7%flx?zx(>(gOAZ@Ht_P& zJNU(3KBuSRuP;1j0lvC_5qD^6!>Q{X)&l!U5H;Xtj$iy?|MStFKj6Irts~AGHb<nJv(weM)T{#Chb*7lfE4AE>G1MV z1)9f9MpCM^w9B&f4u$LqNNFs~=GpsBYOEsW9`wXbXwzQFD2Rr&?eAbih&6<3JL+Is&cRogJ6|^FW^RNmieWT_(3v5Y0q{Z$sVLnvxIKvS)U{Uj$pxC#=TlkL1R3-~@*tcqrCCF^27 zs$^C`vsAPOD;=jXyNbm#^9!V9(G)<{v(@Srqyu&u za5(J?)a}|>w^>H*bRD%o_uI@C*3)0A&mHLO7$BD*nFsP;K?;2^3=Ja3#^kxi)-kb8 zRNTIRV0k9p1y9$1084!Bicc3TRcEPL&ef$)XH@3wf~Ro>PsbOC8>amVOV@t&fo4c- zp8%XMiP=%AS1(MEAA=+}Ub(zJk~)zuhmrIWeiL!Nm)Ka~RRQ}Fxh-^06mKQs{WqFC zkbJPJ7fY>oL@^M~obx&r)ObHo9Q+rk3Gj zjkkUk-3!I~6Zfe3{XjQI$`~*zwQNlARS2(VSoSf`AonzV`VXHR{NZ;OIaNFH1zrS%(=SfBdvuInQFR zsBK8{Ukf5>wfh0l$9yrPj)mTcx{5bfTH~817LmpRPFk%X(pqx9{4cfGQJ&bnRx}4p zE4m^18RZt___m?1>7i7Y9tVdWP?M}SJ=IV$k~)7+YE2D7&5or0bu&^wlKLX^IFkB& z7cRA_e|rWOOc`F}IM`@hoBBcS^L8Xz%kSDNCro#ekqMO!K4qf>-fX{TN0JjzdNHS( zd@z!HHk#DST~aAEL4Z~2e?}~vRD$Kx!Ge2?qlT;YMcbZXb{wFkp|TUI4#4nGxcXP| zEM^5>^OzNQ6WlNxfLVb*3}b#TOpk&x(cXpWn}Zc7T=Tkcg`jlMc3$n$Om&8FegK}_6Jj6F4%%b><%>}>)3NqF?E4pp)+TK+ zWkqA_N~Uw`YUE(+^5E*Gy!De0A)U0k$t2%lu%$7QJm<^#g#yV%5EfUOTdzlY1;Z;~ z`UR11X>4zYzQM-e%C^{);0ID-xgmM4i?rB zF!7*m?6^9<3dN)oA(ZZ_MuA@2h?zT{7Gm%>SF`8(RBi&YpR!bi$(fE(U$1=j%M`50 zT*{ULVWxW4CRzS%O@dU9Dy!;|{Vs-@iJY2bRGAd4oYdaYyrQ|IAs$;Xd(z~fIsm^p z*4&Y=w<4=mC9^e-j9RZ=jqGNPrW9RlRT0xg4@K$5W*j-Hy(g&yG$*lu#oCZ%NXlk- z8B0A%%_0=R#uZQ}IEiPcqsg3v5Yo<${WOMV(l=jK1s14|=Bryf8BD1(EjZs=H8SO~ zQ@0nYQfaN%w60vq7PfKan#LPC(UP$uPMQ|1w-rm*g3d|ct%|fxAVvhu6C0818JR1t zxMHd(InAPoHZETt)Nu_qqNyLT{2^!{KTK`W|L^V@!)-gc-qlU%Mcu@b3viIbC zN{}~jLHusPFNEJb{OE$}@6aC5GQN>~m$GFD?11Wj+DkYDFHdhZx4vh7+1H3rfJ`$qy-XrI@bC(Mh{OuTTd~ zTS2*S=Sh7f?RZT~`CJG~w~Bw<@*A{#(s9`oohlfXZncTYg1nx$8M+%tZ0Sns1ffn> z=8Jm0!gaEwU9NdCpE!D^n{hn;SY9$7kJ46><`)D>IpYiW9saTOB^QIHPUQ{bF~!jE zxSkx%yhLfq=X0!lq+4X@&c}U@uHDd>_)^E44P6pz$Z~X2#~;&nR9;6;71Di*f2@wz z1_+yzTj@FHKw z&^|<3tDEF|x7HyD@0g)oENSN_%05?G5+xPW=1xO%74^0JWIglc>lx+u8~SG@PbvRl zEuXyKFtlT3K1$xh^65_c31wvJ^ZkU0SWK5AjsSC=Pt;|Rq2J0tmfoh@!W^kew=P4g z-lHw8)a7pKqT7-m8rpyIN|U$qdM`MV!avv*v-!mkrTFJ|OsW!bin(gf3{k1TZ8)y6 z^84oa{%QagaqCKRmcA^auf=Rj(WjUVDW2o$_tp4U7 z_$KA(Ra=0k?Fv65hpYAkPpp3>x>Z(wsy)En%L+eBVf>@&K5rn8`k%rw4L40+l#M*% z4;g)I$m0w>KQ7R*e$sJOWQotl-se;82Joqd{yz-=4n>Xr&EN|S&UB>XmIcb4V5-0( z4f`%u{LeN|I-Y!JQg~GkS8WQOco+@&RN+cDL0^2=Ltcrp9-{%(rWn6cVe`vCzMBmn zTW;dUqsQR4n&$;J0IsFJvEnIzTPkdRRSdM zKTHEwgC82a)ZkXq-3qVq)tK->bA8s(*BW}8?>vyI#CM*dLVJ&Ax)P)((|LoTPiWXT z%HSi1Yk5`eiaRaT@5 z@rw+fEryS+j~@eGqO2Hcdes-=cB!F%%Fs_2>`FzwurNPWv7NUrXl}Tvm+?}^1_Cq1 zLHU*nxrW@}`SN4&O@_|}raatcJlO7(sNO^as?Rlkr2@Bncr6wEP9cs}EH3vIBX^i7 zZ{^1S5rdC5xKYdZj=_&L_>qSGOr#^z;Ug|SpEUSHgR?)TOBsBY3*T<=c`p78Q|h~r zmjd@^&`Vo>_8qAd;g3NG>(qM^9?k$>VL@@dzyq)Iz!!VqS9;(b9{45?{2LzlcHqZ| zaf^CCLp*-%LI1p>ACZgcA#?Yh!foy$ZB0_0g7&Le`b_q~t3B|j2foMyZ}Pz79ymAp z6w~u79{3ME@CSh(BgSLueG_T4PvQCT*ea85C8!9+gFs`3A$M z#)Hp74}6K@lOK<%_f7C>^Pperfq&5h|B46x?;iMW;Kzt@!gox(ey?!b>-v1^9hH6< zcpoGBeLFJdzNKSCzpvgwL4G0dV(GlV1CM&(pY*_Q_P{?6{21Rj6C3l6izlAxb&Tjw z?fBtg4?e&3z+d;k`EFG#zCL4IDXy$|3)7#Sn80jmnWiVZni^L&#qs&1xj|17&aC#C zPbcwqSU_rS;B03@Q`<^>9Z-Lb&Ca~(PQy88){|C33q%-xobGFAYH4n|wgF})ZTQ(r z&8y-oIQgtP)Rb73USPol}Dh|-1{f34cm1lglu_CFaY89mPZ-}+7!c2SPs&*@& zDrc9pDrdE{stVK4R78h?33C&Ps+_^ns+QN{W@EJ$)5xuudu_1Ru4Xp0uEuAO zX`GO6T??2d=l_NP_yX{^kn;n@-$Jh=bvXLa@TvL0a99FJZ@*6*b^tX$uMDu7O2#^` zjK1=tm-JAzPqheo;vUJoqHU(4FzrO4?N$^md^A%2N;6&Gd@v2$)P947*EYo38seDw zKX;Zj1Y5-3t1uJW(yW32u`C+en_>;io15_YtN~#$2X8saW`im+aoCj2^sVS{a zqL|C@tSE|s29-a)pCA!hW9k7PQ1I=f;2B$u8gdv^TiL9YW;oq8%8-SK4J%LvgE_m_ z&K4Q05V64oS~M2SVa3JM7xi?lqF~}9lbG-~4h_OausAxyx2k1%Lwn=u)~5VjL(|I6 z;^ev{6)_fEVC>pi3aB<+ zBQriQtn&Q8TC7TXONS2&7-T(A(NUq<9@|E%0iQxUZb0+Qo~^A(TRzt8Es0wqKdk4% zYh{H#1-`!aSPR<0(}g}#&#=Iyp4SPyQSebGyyMxO4%3AGR|$GM zFGhNqFOT4vj=0R17Zs}WMCQxe1}FV;{A|4Jn~0mgOb5yTX%GJUJ@{WN@T-N~7J>8L z>eD0eR)K%r;7q0w0^ecqGjY8};BOh6@w!&vCyRVpDR3U#LPvVOlUaQngH!IM0{?`d zm;5^IR<@rw<9+EHC_N6-=PV>n3*&g}6P|(YC zzTAVpS=8d(zDH{BfbVdi#HR5 zBY(c%Tby}8N1WdTENEvN*Q`(2;*D zeipA2xU5G#1}A@}t)-Xkq2&J)L4Sgv=Pn^S^5HiD%O_~&BdO0d0uKwE-w-YR0|IAV zw)pD;mwaY0f#Jwsmgi1^Oa5tr%X;)3fy;8_W&_i=&W3|(!09Td1s{~+cS=@>7W zzsm(K%jf3}&SW|tKg<6=1U^ULT>ebw=0E6xk3Aw!FZ+=*1>Oo0E7#6zQXhVWvG{gF z@5Y}OeB?NJez}%Q`U?b~sKKfKI)V2XoaOKofo~G@vYviJ(4Q*kw+Q?r0{@u@pMHTa z7xZr%ocdoV@S{fH0gieG@w4f3yuil^e6qmD3%uIklYz;2eO%zO9r(1sWxe>Kz-9U0 zB5+w>9yhqVzP}*oCI3Hr(7z|>rQBg75g|A?{}T;98Gcfqa}3UOo`;`J&rU%v_1P$J zDfepvm;8Sy_|F&oUljDReK;g=*$xDbL|{1TFWZd^1%5UBtp1k>yj9>!1>Pd?4FbPb z;9nQGjPG3nm+^hV;O_K)QP5v2_`mEy|GuD?a*r5=z;JH5=%qd*_>us}bdcpCByg!u ztHIsr^KTyXy96%v{Efh+KEup{CF-*pKU?0$3cOw5RRV7lxFc{me*1#JWj)$r@H4?f zzGwYJ;PO4|9)mL<85OH%ufWd`_%994c*%75qrhc4_>Tc0oV%PHYjE8Ijn<9jbbIPzfGu=p#OOg4~x8|pXWg@zkgjL=x-H#&K7t|;L`>EWe@(}7x;2P{|kZND)5X4 zzK#)sY1H=m=#e43=6?1A4P@C5i-x%UaY zTi`DloZ@E){8d3O^Y8KOOW>~>++9wNGV@NPm+5(>n2+ife177A zUm@m;WPG_!kByP)q8`1b|=8G-i-KIaPj5kW80=P7|N7xW{KzyqASeLGs< zvVE}gUDRK;5919z@$>Mr@j74dk?qfXflK~ezenfhzewP+{ah~iNdDIfT=I_#K2m?K z1GI9_z>U@a1Pv>FWPdTm;4DV#1%0)_-RW5)aH-EigS+GVF@ck()yH(#s+>!?Y>Vi~ zheguT*WjLx<$M`_7XK;k>4;y2pT$2)5RSMkCt-zZT$bm561b!%Pdf6E^j}b@#+TyW z$~{fsvb_okT+V+=K1spn0YNXvp9cjl`OEKalE3^u^;yCHcqTC1nfS@_X7>vbm-#!< z(DNe8+f;$qz|W=w_d(FP`PT|u^1npzk^C16oM~wJ%Y2mib(xYnG`~J4aG77*1pA@*1yHeni|2lz7K3fg$)^mrTm;CjivqR(cw4j%Af9JvfWkE0XvGtVs zDCNp^JCgr0Dh}t?f3?BgeAal-_Xv8)|6c?y_53#vK6iQ0A6KgNbn7!s;8L#L2Tgh@ z_bY~;Vr03p`=;FdfA2wmK**Kpd}f)})6IXj!QK38J?JkJ^fF#o8Jz8;j906`C4IZV zrJg@CIQ6W@&(_C24_tnqmGmKYx^UzZ#?SIu?18s>;M)W)^JS00nQk&(zY+K~LN1M4 z)49|6WP`i&rBcvK{V>-z8{1h?Xlj$tK+sbq}*Mq)R@R#XuhrngLzUjf|CxTw``L)0$pZx-tdcNVo zzoZ-q0LOHY{HF?B@}DDc$v-S`$>$0We5Jr8pM(egJ%LO9H!AIijuXD-fy?paI?&ki zbC#f&^~H{VST7=io;uJm-Q@V;s|wZco0s6;^511}@~INIoX3#*$aOfk3HqxIj*}} z;4=N~{0ZshIDD_5mwLV`@XsQQ)rb46>CVJYj?a%3xEw#9YH(gE@Uwg-2)st%vjiW> ze~!Q<|2n}(^0(_J=^YaMgSe+7Zlb83Id?%v+^|&7%hg|vnJ!Bqw+q}fjSA@%xM?aB zvR~k)3Mz!>8_-eak?KzWsS)@nfwu^Jw7~6pF!Biqe7m4OM&Q2@xcL;Id~N=c&m=)V z-6RSx%zNvW2;A0v`gI9>iY3N%tH5Uq{3(IkcVv3MA@DhZ-mY7t_xS>kh;h_hf!qD? zq`yGmUlsHh3j9%l&lC7TfzKCsr5Mk!{#v(0;0rB?Yq!8J7Wh_yvpvbVX`MH$!X`xD zG;FTX*A{z+6YOHXY5Y5ln?=kfkHXDO(>j`0HV&cj*ykjO&2}fVE%Jkz*bPP440w2i zA4KQgg!BO{bEImg&*2iPO+Oz*thW1n7yTkk=w)bVX_S2 zhbv_W-O7tiH9WGeaIfJ95Etyg86sV9Eg+N(O*t#RhgC$IbngAHE^pUvSC{XQjj#E% zckgn|`%r2jTfL=K@YaFF?$&&0mQS&3SVp^GmuRsNxs9v^TU9@h68zh+8M%=yMb$Ly zsx^|bl1 zcF`q^d8{fnXz6rpZfRK2fjx`9X)9M=zp4RI@91p3I@bdJT{mM9nq8jktI4p2e~LKM z4Cj2t;qHUNpPZxAHyn#dSBHmU;g=aAdv1me;|^Z~59-9LbS+K#=@|nqz?EH;9b=3! zcn7Y<^-j>rx%l7vs_d4>Wi8i+~t=4GhoH!*P8-y$b`2Scl!Sr9>wG@DHkZ36qDa;6Skn!i&jYHd0Hp=W*z#q4N2Cx|sY;Ejq+L zGKZslj!WJ0xu2|<{LN-?Yu^LOgU+4)XL`tQzedwf*B2$9<6pP@D?Q{_m_f80bCQ)? zJ}p!fi~nXL-_|q6|L7v}Ij@WVL)xEuBcJcS(z)gH{j-?-ZAShk6PWTjo_ELp8y@lp zjC{TqO6QjU6%YB&wK|lHKfj^5kC|m*?scam(j>OtJVcGxA$Z0LK4B{M_>Y zUwQ8W9!GWFjcY8xlJP~hDG1^w8rTGr5b$6~Om1kcSv;G}0tp02Lt`7+TvCILEx>IE z7%UP`WF=1HuXVq;-{&;6RYJbjX`NPp>qx8B-MU*>V@X(CWXYG+`XX8K<^TJ=XGU7D zRtahQf4=Ac{O6Ho=bSm0_q^vl?|CohoH;y2{n|>G)4VsFRC0>L=G;tpSG#Q z`Z>QQYk#AwoYM9Yeq~TmK?AC+oiv|B3bMQ`Eo9t-pM{X7!NRex8k+Z2U#t`s3SAUYc0{T~pM* z?p9Ub*MCp_pPQooCHX32eEUC@r2cPBQGcUbzjuD72S#H1zcEGqPq_6jA#vj({z+1a z?Wg@E8U1J9##|HUYpT%X{@*Y~{kvXOIaatCSwEYUSpQF_s6T75%IKZr=@v6-{QcDw z^{0GKV>t~Y^>u;K({;13N zceB#CE3tms!;;be!#`A+7P)y@{~h>GtiOMX`ggfTx+<4`++rrRzi*2Ax48Ak)8A*4 z)ISfvC!@c0uF)_4yhp;2*nXbRn5_LJKT;5HilhHKlhl8+Tfa;0DiiM2e)U*$#dwrF zcp`{7YOtVj1GTf&aw%(-DUuJn4G) zn<{Fym%&YuSU+{DWcf#aqB4vTIdNBF{#)<3ZBbU-6(3N~>i(JAZo;cAtDb@*nUj=(JnTNq!8u;NJTzt;WH3)9$jIhwht`|5teJ z-tS|7fiW;+-9kv_#J!MEf5 zP9(VbV)puv$~Q3iT|TE<-ddZ>vV)r|OYrut=Re@*)jx($bbmsXH+tzOm@iW9OSv?z zEMUCLk~h3Q80K5KzRqvX`@img;C_67cwzRLiqyR8%Fkt7f&Y85%FoTUeY;A3XNLzkHa_u|9P_*9-*unb=dBCcS`(vl|OyN)M}O%Zl88=U6zmOn&)UW1uxD7 zd|M-rJ`pSNJJo)@DUe=jYVAu4_s%(9{~x7HcX5W+ZWi2~LBO{~9?gzb`<-ULJ{ll+ zB})O{KhJsLw1Q6?LCUL`ayx*EJi0L!_B&_&dMS!sTDUd+lNH}z=D~=RnM}FE)WVTR z*TpLRPN`q7mXzCP%)fh4kq0GGE?~-?rdD|=sDxAdA9tURgENaMcL6ejTIzS2{Q6lb zGe50k$EGLa;Pf%&Yf0h!=V7xT4$g&4S(FscUw`xB#W*-`X3AeBg>zr~BTgKgiW z7frQ&+arfJlF*}my+l%M)#52F^#R|G$l-Od3*$q9<6wfqQuBN}wHksl;voaI?770D zEEkSlli`S?D8ljDWH{m}32+omhGT+)0LQPA!QoMk3&-xsaKupz;n*`7j(AD|9L1C2 zn4l2Au{RkUBo5Nh1>p#*$mh`OHrP=ki;D^Jz-Fqns2`p5=*K^LCX$O!XMV&_zF_-y zFli?7Txo(R+Dxq)oGX8J_P=JAFk#g-0kAG0!2)^qM#9;#64R;H&uTF(T$n%itAFyX zPq6x`dB_+EFNu|sONLGD1Ffh*=&um01FTiZ}ik>%X(^J_x{K5A<9GCn?nWbJxG;hxXlf0a26A3EJj7M`J<6`X1f zOjLi3*5uUd6`<9Z-~U-h!6UwHT89Nrp2o(V1(!miig{WUTZu$fV=W(`q}Nzdhc-%X zR|4>u>cUK|(izo-GrwQ=j&1^UjNm5LHVlw*zZ0zi{>~B+;POV>^v{-=s1QS?gBWT8 z^F%R6t}(Sbr(YidJO2Kx)>9^$2PTLSz9?1)*pZ}Up4RV#O}(aY>x^Sp{Yd~7?eS|( zL8q0U=NyR~zAx5@0m`J+GqqB*?>JC(`H{X~psX$IlBjl?U=3-NF&YnIx%C^2%~Y= zul(Dmq!k%pids89g&Q+a{^w>cdGEXcp6=JGLF0{1jS)8a>Nay=-)qd$yZ{)`I!veD zs5jaQ^RM_tL-$wQN`RbFr_IERio&h4SA6BIGhQWD!2*y`r&D3H8TABr-QM5sV@>s} z$=$ofR+sbm4eKrq(-A)98&q8K5Cs6K3P@Lczo`)B@0%DGw# zTcFrRtzH#Yxb@oao;o4qQ$3euRd{7BYWmasSEZ~gQC9nSS-0K$V$oVD>pCs$*BZQX z?(BX4<_nCkzFKP{=0>ziRTi4LO78n)l!M%{}^zc+ni@>FDi@@V=21|81{d;1gMQ<1=mdOnh6*LeeLg9@i22 zG?8!V?98RJvzE?YxODa+|Li5^>=hH=?fc%e)Vdk7m-uHdlJ`i3v>AR;Lw(4;hXvv4 z;LU?!;=6p+@{umSOL8gQ5OQCVE7`ZUm@L^hwb+blao?bjcDZFv{Y|YjH^sycZ2e@af?z2rRUxI?1jj?9ib0~)a#R_A%Jc&a`zOk8_wN?lWetcj()!Ha*=&B%Og ztr!3ODdOL7<8Q)md^!HO_$%@3m1Dc{iRC{wMfz8!NT21#vt9Aj!~WpKxOf}L8i`f$ z6TOIUCC0^HVpjaUYX~P+>&SwiOO_0d_gLJbCocYp>pZo-@Y2pslG;76`~TW%Ao@p1 zH<#cB;cWaTyF7aH-syN?{zO}7wwoYv?08}Cm;ITn{`=hg-uQHblg1+b8-yv_OW^)) zo1-2$-gz-ddhs}d7f*UkR{uK0^YZwB3Qgt(wDBdYzsRkBg`1H<(q&@(D-oBhe$R&; z&*xZ_hc`a+;$DSh`LkUka)+dvxFzO)7O#@QpXMf9;btZLggp`dA0dwQFT#KPmFe0* z7sf~8nQ3`>zdPcd<%N6m&eDpHKXBI5Wfc^NY zf`>9KXRoi9?_XMw%mSS)7U(QmptFKbMWhU({}sH~Uul#|=vt%7a$s6Wi$U#gu$-+v zjyuySHT9wNrh=>IEE#&hmo=v*=p4|_!hQ?op==uOEwhX;D&L9J431rGw3|+s-eo!+ zMu(|48jZHI%D2s5xP9i1TYs?B)ZPg>kw9U7Iz!qBOdSBDN`Ps+(x{QpwFd0hF&J=Y z$~k8{ulY()eEMj?i$~;ju%?9X=1SS{7&hi`8 zA*bDTw)?8wxW=mkMvd5$JDpOa)6_em!NRJdoee-WW=RC0SpXWn(rA~^wZ^FFRGKg%OmoD8 zj!NGR%reC65xd%N9CupvI;Y)e&?}7-Fb`=xIfXlCG7B+Tdj)e1UTGS261>)L95J0k z`k~0u6|tC^e%dT}E`x~3^DXkvsW)K~IvRkjPwQU>E%uw?2k&II2C4PLEVquxW8)GL`tyig9Z+B}&&X`{tK&=@= zbBDe`WHn7ArjDT2RtASytLfC~=L1fS-x&4l&3zrF{rmA*{TWv>xSRO>RnXkQa*I%-pE~$0^)gF={svR_)R#UGFIBfx=-mhN(AOWo# z*2e&BVyHKK1@B!~28=QZUK=nvgfd!aJnZ+U4;DPV07zcr`@)<$XAMlTgQj*6gDJE1 zTMJ%iE!|RSH!3|SK~#FsbWWOjOTZZp80`VQ!Ef{gv>x~&0x(9Rx=N|E$E&nbRodd$ z$0CQbW1ar=g9YEp5{k;6QwxIH10$H$K`ZW#Urz5}EtS)F@0mrg8N>*Koovk1PX?T^ zfN?UQw*ZWQR_51AVXt9t0K-UG3NkK{AjlYArjdYNMGIh;KfR;iTRy4OluCDMopd4O zr)l5ZJdZhQrOq;pqbdduVi1)DoQ{A#VmcVnXTi2iqg3mJxe26%6u>QN40|<(S!2Md z3g|FUFO2m_jSHnlOKRN8p%(@j?R(V_rx?g67a*fXvCcN3MtHDLK!;NcbesAZK+sxX zL{d#u47Tk`Bh2b6t~DCr4>9#vWNBKg)JzYeRt;9 zIo?`iyo}8P7h>pY5UbNckDYVKZ`1|!Ljj}QueJKMO21alTF{rcx4U&#N}b@NqmiX4 zu`uc^cySSGe8G3$oCfgEVlV@kd0}Tt%lp%P>zTDx&{{5yWRQ&vIQ@RTBj6nM8*lsd z{Q)E5*AAc`{aS=s%B0Q~x6U%DbJWzkB1^Mk6;kKzQs)Cw=evGw)UP$8&WsDc?%u=# z4oIC5ug(Li&fb9DZ#o~C#tFU0G=LYaR2k3J;A~=jedrI=hkgfAXj^Xgr#BWnxCHe* z;CpyZjbCfS$Upe=5W-o!Aaim4QxDZS*^%0sSy|P{4R6pdSesP2fIko|@%k zc$5j4!2xwygtp)IA zmOlB@cWuZ8$kQem>IQ~dBnS+3`JIzCp>7Gm4{J2iDX`10k6@SwXqE&$2XlCpn<$#eudKY~LEV_FxJMj2?Fi2G3FCCl#4rvwKE~D+ZG~moUHtuxk zu~cas{4(@jz`=1wJ8o*-^gI-CzGwmoe{b2o6E;SX@PjHrd?OIABnlwDDd2>~Ar;VT z0tOwMg8C}0lClJ*suJejMwl>+aBrY&#E{5F`MzD8lAU+-vk^E~%F|0BXzbv8UWO!d zd2g5>a?Tly-;Q{Awe~Q3skG!QT2hIqoo*CfG|hwLwB5JOEu&&O%V<-PTU7!16RD5P zGs=;_cp^sfKj7=7|Lk4nt(Fpo<{9eABB+=ttaEiO5$;^L;L^ zcS`KLUM#x>PL4hBkC?u#LV@RLIhUmez$=%NU&Y^+&apw*+t~VgnZny2(LY|ela(Dc1)!lRJ~Z>dvJdVGe#6$Tp@gB*do zywVe?M!U>HaJK*%rq+zL2l*LmZ$9$r5JYlRv0u92fZGN8r3(&Y>V_<1-T;p-gm=GI zD?D4I8Srf6s&jRzazGw(Mr?2uO!-it;ML5Cfp?xz4H%LJG`S6k3EoGg0c~yrWWhu| z8USGijba1T$Xl$2W5He-fYK5Z*o4RUJiJ3}4xDlWXwKG*U*_k1nNUGX!<||he@|Y` z{_P?wE;9AQrgP9V`XHzoE!s&7<9?e4HIP5Gq!6fOxQklGkf>#&;BjnP6}7XCv1q!? zY%yum=zL?CwVa;LAzBBvGh{l)(I|L0O^vKdYeTC*i)iT#bQNmc%M2rup$Zw`Z>&VS zpw*Buba?$F>vkHoMtJ|;{>AP`2$m9#PR=sgBy_bAbGl8v+vzZk4h|BuZ^Vdl(A8@) zC)7(XK_HVUp&qTFFK!#iol;piEp|$^<@8*E9`ouDVM7O@F^2)$DS;cXy>Du3xMbxx z8go=yh{?B}9YE*eajaC?YIJQm`HF)xy zfY{*a!6Ls^5$i=}dX0c1FxJe6$U@%yp78l&nC{>6Ls|o?3>f{yct0j+ik6uH=YYTT z=!}4|pLpFG&<+#WDs+fI`?arrX$PTgm)XAo^QK}Em^Yy;bD5TN!Kl!?*-Y@ATDa%| zF0?}2A^HipwTeDm(GS{jjesUnN}WKO13U^g2MB2Z%XSo`z-9)7AOgBo!4E*IK-d_^ z<*8y4X(G@YS<4O+`yETH{Fkr4?6Y9pXTjzI<_`&c4(0+m4nE?%k3e59$>hv*4tjj9_{cN0gzE6S}DXz|bhsj4*Kj9}SPz&QuX^6TdyR|mBHT9seh z&z`{8%Y_0AVX8`k5T>wXO_q{C_9~$UTpM)CI9f{r=>li#II5diTdSb@G*FEpKOnPh z44B@DMF;ToiojTh0nn@Ui`b}PxlFil>)gthzVTaTj|j;7AqbXA5Fl3toWlXiuI~g4 z(8Q1{Duatx6Gl)kK(6#aZXn1an~!k8T}vRnkp&$Rw+|4seEp z?9^^y-N)w{hhVMZlsSN@r&z?HEtvnohX8Ls*BpR-VH^tkTK40AY-Q#WftnI(n2qRA zP=_I$LXt9#DpT);_)JY3%mGZff|-C}q-__#86@DMz6ggnL=MqGSn&?hHIjA6=O{5RH-8O^6|?U@~be+^c;xx8@3>VVB@eI7A!Z zmf_t^xcyEnpobl5+@@X)m`utB=U{3AAm_%lf>8+q=JtT7T+|9Mo4UyD66AIzLvBxLq%T_AL41=uDaSb#mNfQ3bFl`jKb6M1wIAWnv2z76XQQyr7(`Oti0kf`Yweip@yc3g&>X<$UH zp{0<64h!p!Vc3DF3vTxLwPWs}!?5f!3wK_#ME}SwED{z(+`DF}dIzrNAZXD~V%@PZ ztTz}vR4-v=>LC^O$UM;ldzx6KdSFk3RjLdo6Uuc*T!~^=`XG@2`K}KzLM=Sayh@fh z4=x4?PjRtP4706D=-uXbDxlp$b36{b76aD=Hv>kWE?7w*cDh0oqMKom%}Q*MP3^CC4VTy&MclLK<-1ckKc|CuW@r z0=jbopPbC10qt~v)`<=Pn)<+o8LOEc47Uu30iYuN9+AGUrHK(X4J^eS@xyGXLGHjXT|GNZI8YO9ZJEBl}N>F+GS2~+baVX}Cs zb)e%@-O>mn|KzZdY)!~;}Bdis;14`+5Ldn5V=6A|r;0x$=eppDf zW1!D~c8EO>d?LNVCxe2|F`zU2L~LLZI!)&+J7HM5{-Pq%dbjI|(xQO&KKp*;Qlvsg zJY{O{gWL*tE`Igq^?ylBo)&x_nq{11=$PPhP%ncFY+wOxh0(3SqK%Q%%^ES1kVuUr z1_jI(V4pVL6M!=pY+6S95wF{mqEoYddm+UW#;D&R=rZ0RcbQyI2s2+7$aDVB`hWX( zEE1AoA4UhrQ%3u7q7%e6$XUw3s1%w><~CRJo4-yoFhTxu{rp!RyRJyah08--zSyO#_28oL5crKV0sS}> zes~DT?JtBJSwjhik2WfXk7l|IzsygDzfsKfZ2b{IYbP0g85o{){V*B6>6};AG$6GE z>w=+*J9WbDX)Mu>(BjesN7%Z8ufSTi3Ufa4pA%W-ZOo-I$(+Nygh{3kcKv{Hz^|VQ zz%Z=6Oir)q)PSxq;QYDW7CiTA6dZp zAOO(y_J9GQ^&(XnF|D`BfVx0{`#?bA?mM9mQwpqtmyZ~)7V)GLVrwmf&4Jp-p;d|3Hx`?he;Oz9Cwubn__5tgMx_QbReV5eQ%|Cdb!_M)JbO2LQ(0c<6d z0vdjt`EH$dhJ7+6bt0VZ>36ihYQGwBS&F-eDHxtU%`*vbXeLjYCWNXh_N4N`>y zQKeL_Dk=i5%2hP3a&-W$Fk_W#{Tfz_PxD>zH&P`A6e_+zHw1p$;D&%5$J8&6;I6(Tuo`btMBN$Q+5cnd%OE09463|ki(z6)+3T`2SIt8e!#a3xE zA%s*>HQWny!ae|WLZ`15!&55_Pp{rFTSf+4LZ}Cp4iV~WVYP9(pxOJKgW`i4^Q<;7 zSIfKwb9EVPJ+9RzB8D=|o2GNb)ZdAOGh@xlPIg|PY@P3lgff;&L8&m#G>EC9638sp zPEdPrPL!UQVYCB}CE9sd0_x#=Shwrj8LSEL;V$qoBvvJHl=sjQFg$J!W2(uvFxc;0 zJ6P)^Gg6<3NxA5GfE9HuE)^!o5p!leMRy2w%8*0@>NYIXATog*!vryI0YMJT_+XlKrUQ}s3{5GK^a_@#D6t%)9L9A~ zy+_(&AP;tMogmcSfD#zt-j=1>9VkguJFm<%xlmbaVM=KlRg z0-{vEVb}iJPBZZZy#ibfhL-@j8XPmtqzpA{$ndz-Mi_&6FuWo*oE{_j3*vy4986z? zhiJ(rK#);{)oxSh0Z7!Kw!khQ(2l}m4xsd_Hdf^m<;^l$Vg!mI00q;set||>~15JHXn{6q60DoZ0|ZR_shVW;og1b}5ofC4F$y9Hb9A6N=!UhP(qf?o69jxs~O@ z^^W@~7mfo0$NMI>-#PEWQ>~vjPJ_Oxv^pX(nKPgZPJqK$ijy7-00tBV7;@Z>GSO3( z3xo+$*&E>AEl4tA7#+R1Ph727aDcK;yWP{u?m2Gi@1sfLjfc_;3BQSsBG1H#><@_Nr%kYq7VP~QTyx)ROs*CP4Y^oo z5-ebgo2aw>kjBu<;=IG;C%s=I!=~9CHZ=qS^x8~i7VZ#mJQg}EY!u!#m_)GPLMbgU ztZ^>Z&JZ~dpidr#sssc4c4PSGXZJB1R6*P^Zt6udfkuG*+?z;Gl2NT6flGzPwFB4( zh=d0Olv7tKLOO7*5EAf5(^`+2E@~JIu1I+ZQr1D*Q=v>!9NretupH?T-y0#_eO0%)HB=_OL%lV77o#XqFun0u$ zNLnTvlF|w`%q;j0R%hm1WfpuT(=51u0d^(%kqMiWaDOn3_vdEv{$fS|_q(s+{hmzT zA6ziF)ZN6yH?ob153-So4>JpLGMM%53{)TwR~6)B%0p&B&H{N@;B9x};!m~R$*Rm* z0b~j`|Ilqu%$IVN+_8rHFTR$dZOqUh0R^*!-l{N+(<0%{AMpZpoMae3-pY z(k?gKAF}s}dp+X!K6$w28CmmWcY-R^+w;KVh}buYmx+k@y-$K0#65`rWa%gNK5ckn zB)Fs;!RfhM;_C!_P>}E{(Nra!_cz)+4_wr}C8QAZC$eyVFPpgvt z)GN^aO{{;aJyDz7_BZ{W{I}lmS;O59B|pD+Pt=k{i~i6(Q62sXAhP9A?TNa1_*3V$ z>&ErrRd&_Smw)|#fA!b*ul=*)pWN^t1KHoW_W31$)pzlSMTft%@UQ;z&hOp-@sECM z-!F?_z4_eVXrKDKo6BE*`_unEJAThp-1D+5kq1ZSe!m2j#ciTWvWMz@q=-A8>qpGt zU=2czt&LjFUo*HNEx7r6Rd`6--20NX@1nXsW);4uS$B@E$A+YKtMtSdgW5hOvh=o~ z^KZ=eYKgZ8YZF43p6`{t`JI<|zE}2#*n{=*Mdn}sk;k@Oa=zE#CY=bkRLL8P27ikRaK)YP_3}|3Tx}J6%*F;RyI^^SU2t!vRj@3}E?BnEDtKrSw_&Z5 zBrh$&KCJ0^pNTsOEaO2);u+ss0dah%Zx>3&!*<^$^=fuy&)2g#u}~kcDvwdQInwl2j|q;&M{jXwzU%$ zoC9yxtv+!B_gDcmwkW)S_ffzB?+t>01M4Q+EggE*R^P)YI^;A3jZW@}%4SG^Cup1v zYNbJ~$%gX|5QPPvq<^|!2Velp!37oers{Kh)Tom`d%H}zPwY60681zKJpcSvuGJX#dHs32IVAb7%sU>kUjjgwJO z$XnMoUjA>~)n#e$?1C5tf+0ZAMhMO-2tWl7A%76ygIWMVr$8{|LC~on zXbb7}k)^w1V+w*r3W9Ym1iNu^38=%;daSp8dhfOW%ne?aHbw|W1%enLxIhR-6$EWT z9hSg$%V@ClN*fEFwTnTl_`zBjK+qu&L_G*P6a@7^TV!dm*9%J&1RGrl(1T+k?IgP1 zdMoqgr@FY?3v|IMdjx{v>qF>N1_1#(HAsegK4`QC^}3L8I;0)4G>|4%4+sQ(xX-h( z8i&D~f(G_xlv#RNWa&t3$WA|L7d)3u2=)kf3eKswVXBITv>3WFq;&<~S~@ND=iL1j zLPz9`MO%d!4_$A=RwEec$9MTT3)*1n#89-ny8-f4=>i}zlu;o44 zAL|IEcVSH4M@;PWZ37VQu*?W?Of`nIs^A-2|K;6#xI-+2-9i8&B0wAf5LnfRAb@BL zIfp}fEadc|YY2_e64J_Sts#VQgjyAkXaEq{@<<*LGOB{$dT`2sF*JqJu}t~FhY7@X z**6fJQ)6?PmW@-GaB33RP4VG97hAb!47`UV2JVi!YeAJVZIppwVL^H)n5XR=w2eMn zKWQ7a;3^@kuBAU@ELtv9Sq`d{63Ri9B|&E-r1wW2-4?3}rDGGpJu3*rR^Kkc1U9>F z#X>7Ef34cqN-g{quXVl?<4!V*%Pawb&}JFnP(i>^8YCQ@L8m8V^n~;eLPkSS!(T;E z@!ATR@#?)9uYxn4?HsZ7p~$0KVhwhBwOw%c6NDpQ?2o}YcnwFQjd>17R^eX!>%Y4C z^W0iyacePVPod3rFiJQ%5X2PIWILlW)s4nYbu~dPf(eglA_ByI4~U2YV#uafct@<& zO2-LL53VC^ZWmLgH3v1f2c1SsYv3$be8;@Xk8{VFrNOZex)KnYJrHUX2+f$bG1u7! z=FT3=Xh-HCOsNVFWdcI22SS+w;T@a4!dU7%GfpFr+9;Dhjdx>p=xpar2jl{+H}V)1p8q3jp?Tk9ln%_RxklOTSrlixE2M4pXj>___-D#H+ZW}#QjP5ANLtWWXw`2#q}UdnGHM( zVTC1K4bqizXH+rsR%pDpv07%UmuwXXqTxeU=@HNu4nxDyscguI#@45>T87dX8X=$% z45I`JOGSZdOzxm2I5ll2YL)h*h(32$ZsM&`@;5Ob#1n|Ym-%dr zeq^WQ1z*<)0c}9`t?JwXgifS|9Ed^}!4p{T2(%+q*24y;F?EfkEqQBCo#DO%;N$PuQQQo+#U>qM6JD_N z=yZGWYtpgI6a~S$>20GQ(wv2@Mx$aROQu8KDkCEqK;9;-~T1E?`Qnp|hCnEFo^f(C;+!m0t#h_L->6+osc`~VILEjPFl-7Un72o(g%VbH*2hS>zWSfC^Vr!sWQDX#TNAL6e1kU{ogP(K<8 zH^y3n=~z&S8C+V}?zQlYwD5vz;hFIk;#fyp!+eOf2tiO~(10rb0Jid?fadYu#t|mX zij+tBc6X4{FenupNFf;8*cV12>cE))Ke*A(Z6I_#6w>H*VU_AaC|ETirxG$;Nbf;y zkmNAxD9NE2=tA6;1jC@3pN<5bqZWMMAnwk{;a+S;^*Zs4G_lQV;uPeW2Ue)z&`Hb) zHV&VZ$r-(awPKcbT4rD+2mR*$xtqBIk8%(opF#+f-WdxSWg)#bhyz*3LeNJXUW$7_ z90lx39L0l(qn6WYK^zTN#SUeT)+H#JwgKP|AY+!*tEhM;GjX7`* za3gS&AQ!L$8G?UBW3Tr-cAVSt+%5n!L_-ua#Dg$H8#_65Y{={m8BpUZpa+W>1?xx! z6DO17EaxmIlr0qI4)2b&5PkwIoUhfx{wbM#j}m^{dEbTK!oDm^t-9&8N{<0{Y`wu| z3riay+5jkY&Q@?J;Lj?~xNXm;xmOR2kFY>H!@bR;pn63?F;cXDy$lYzdG;+8&24b#c3v$My2ZVkOe34Qu&A3$j1pZygv&jX#Q2=iw;FMGVHHtr!23?v^17s@G z+@e8o03bt-2#+(cM>ynLC=)1ox{3y@;&*4C*vD;rP!4|w=pjrIn8`4+97YpD#{Q6g z3aAj76{9#p;FB|AGy$V`SFD{)0L*nR_1H>}t`+KU0pdlkz>EmJ+QP!MqM&w!-Io<~ zj$on$;-N`l(G+I6sj9oi=qIO~m%|Kp6GaEqVC&2M5E$pK4; z3M|TKD^y@i2>l_w7b+1{af_-rls+t5D98jgP`_x72ZVIa0re^f z)MJi>>SgO6L>}D%nQ@cN#r9~DKwcr_gTjG()Hpz}U6sHx05;|;kpQt%k&~8fK(eMB z4=tC{7C82WAZCW&p1ZaAZtezzy^-a#izTO0$OnZt+=w2NqXmHc4gtOlLV8d?$T>`_ z4Ql6uFiaxj`Eh%Ws3PZKSKAUdDVwdvr@eOPsbT!aA)fB^y1VhF1i9#o1(K$I7? zigOoKB~f`gRKvjk`-yuDYT4n6xvLQjM|uZ>?kB20@d)<{QqToJCuIPSp$~>xXPN4Q z9$UX?41oF79HMLU2qqqu+)EQ3XjV67G#fg6YEK!oq_F zFoWSFB&f%6`s282W}y|mq*LlX5Q5Nz0ZMtW*h7fG_eR8Cu9^TL=-4MCf5IJvoPkmM z1sMhv=!_8wVi;iLN6{0)KHm<}zz7@CIjA6HpU8q4I2U&h{>bsSj~jg?bd z*}+B-YPT!gMnK`s0fk{2E_KyY>X+OHD_SRsP}-)t!iHcA1ry7F?R^g{!nFC~t9&=1%Nf0n)>XEbCS4q{Tk%tKQ(28GNQn8pB3t=L%c zP(~Xo4L>EebKceu(f@%?;M@SUVw;^V)5jrcOdT2{&Wmno49yJ~0G_$Q23N%le1t72 zvSq$NOJD=QI(g{~Ow6>>I*=*Qm=e(ei~i;LFK~k*hX$a56Abqn*o;dhh~9v?mImOE z(-JhsLOLwRwP*|m#e`g%3&KEel#;+I*d7b$)lX9{g-8_F8}(=ax=Ng7Wiqf2q767W zKnxb*Boe6_`Y9%~@!mii@I?kHn`&TyiH$el{eL>PjC&W|26*;nHlPfCCU%I}o6+TP zi8TiG5x^(*J`4{bbeLGt=KazDJe)%VaHQjDTYoQdnA~+6o6si%A{V$}6Ie71Pq-f< z{0iCA0Y69eLK)SU`8cQ{g@}gl4(bw*l3;fMU;6wVuUy65j4oe-W|M=d6~t7{qB|7q zrLa-k^kTv2*<>5l^nYVZDvVtyN66Z3!`ENNBhkj;ILE=y7#uxdarQhXDjhsaeO(qU(B2!Z8e zilc=c(>e?n%Ev00uMy0n!OdVv5OgpKT4^0a)6baesDYN(l3={6$20doN?$`>phekRzXYoM0FNMX~20-6_-v^RiV zIyecak+_v(7jmda@E;cEK)m35%cVHa0?x%~3%l(ptN6!%J<=%KAhlkSVocah4RAfg zV3%S$O(7i$RU2k7f^R_g>81!iuEC&vRUVc1f>Pj_KV;(o%W!cl{0HJX!^L&~rMS)% zT*FL!0#0YEc+tKGuHbG+%)p|L0xX){7cMN9;^SbxQ19DxCX1GG_5EERy)D<4|ac>jMGYEPCakW6T zp@iRVr$ayG;UPI5`rilo4@irqLjQ;h`nGY<53>w(H(bcz6{o?F;dczaS={v2ZQNgp zbt>%11a4jhx`Dl*%!YvMl)@hz1Y^XV9?N!@)EWf(c2K(*nHzw9_<& zrZ^ac$kBT&oMHnQVV6RAMEXf0`?M(M??JOY6~xK{*wsSD`lqva;QYp=xOF>0zpyaTNy?=+u)Bx>1?w#U z?-0-}ZEXVJXe;c~_4MhES?L!h(0v|&4@07nMP!Ut=D>F+qa9pC&<-=&F+h(460tSY z#+fk`S|GnST5sn5Np(3liE<(btXNEi`w&1E1+NsKLx8Baba;*Hxk!XdMb2PK6QM<5 zRc5qyfG(l{SHU&He*nuT9k|3fySj+&J1^vN8cHBO#)P0tE5~Vw+y)et6a3TeIHW(3kr>H=|-j1W^zbe2)O?Vb)bbz1zaamf%`O z?}Og3REd5cDBWiw0)l{=3l(54i7f4<*{o8)l-Y=8Ct-tt8pV^w z-&WueYNC2KFiNP4Rbw!d!pSQG_E1Q}YBr(KH-BFIFKyhxifNH`#;e*Ww*E$_7ErZ= zIus~KEd*aFsGx3)5oS>fil}OfvfczfNF!AcTK3YYtYC3*jq>UMb?5KI^)?sRy)Ley zfN}ocf@vNiM+kBStwrtDo9F)J#Gi7{E8Jf!-_uR03L(hlSkz5}`Vdyr&<&)QP`l&O z2iWR`NZLejp)Mx_wGDtP8D5sW91Nukq@e5^GQtqpk{X#?7;#RBg(LG^&^ZCG56~_Y zj#(b3;eNq~Qzz*Q!fG309pe=g4v`C@b+h&6id(PA;XYY#brz;(&qmDsvY@I8z(a!z zV=A9CItU@;cjfO^qxIw{avfDXJPrNTRd3h$-pDvB-LF5WRX%hUvf zqpQ#e!S^`@HNgYE0X61Fm&~`gWX?5puot4MdoZ^{Rw1RndGyXz*KzMH=1>-kr7b9v zDupPYH56Aw^T&}`twG~hNG}f=aA*PH(BK5&5Lfyz!D4W_;tHls_=34w4B|>-P`RU& zGvsaX!4}rjE>QQtj?_X83qA##J_Wjo;qRlEOIy0w!yqj@LbV?W@r%WJA$puKcP{*B z?hV|u3;ByhV#yysuLI~pwKQy__pF8>aIIKIw+=(?! z3RWSLVQBpDjM-Srft*bOf2V@KW*mN;+DxxA;D>U-W3qOE`bpU@=)|*HE zNnc%Yva z^AKeF!N}o8`a%T$CV_v5@N+$ayO4yWCh&7*s)v7^76X1q_+fTow1OXtQDk{DbxA0a zR`DPGdBwkQe{d4@8OUh|=$OhetGrKrPO0qf9PPecxH<6=B9&;xX&7y`k= zy$VoR7pNxJ!#eDaH0A(!OqbP6vdu*~!2s}^0KAau2p6X{TE#n8eqx~hOE=Pr%A(uG zXMd4N+7!|;ePY!$W+WQ2DTHyHMqHDrT1I%lLpqlc0_iAR#z`O75{9wxM0}@&7sgY- ztBj`z0({&{VKG83o-u%vaHLuDiTgCBt^T6)fLizjt+m%(fU{}b#{iYpjl*vpBn1m6 zRiky&!zFrU@%J!!$~wVeVW0FfL|Mf!Ml)8J!19Q-#IW6A+EPo~qZkmb1y4z3!)TrI zb)t1q_=+JsQ{O&hr+3>pLM2U6H9jUPE_w_lsQg$)3{%!e2Yc(4kTmD`$ZKq2&qspaaq(CBTj%gH9*_$|X%z zP$4iiVEkcm`(5Y|vW#HLg`7~1TOim3q2|jn0+C;3VQsPntyn?81+C#N z%7KcOK()u6aw|YsUp^j%i>{aLn{stPGYzqr z#;N#njSXm%Yiv*(IuLi|on{anh-qNRQZoq`25{Py)gx*;IYscO6FkhRV`9p{_<hH?Gn>zz`OM;iM1ZW7O2PHv-hjv@7tgKZ3v>~yb2}f4me`;DH z_0#*0aWD$oAZ=%7sA-{K=!ZFw^TBN)i?8vmP{O?|xd2rsUCWf1-%33(m-5_>MNWx?Z@7!NWA zm9w5IwX&HKWmxS)l{&mjDW_$VP_|BlbbA~y5fcSvCq(?KhAOWT4;!9VIz3IjHoDhe_Mz>(Wg+tM%9?mJL!QwKz;u(u#Mh2X@wHnP0v+MRNw_}w;_7odZ+ht)uF$S{897Eh0qlfE zebRQoF~HHl%V2ydh4BSDU1azOT)2!63;Glf|N`{SRwOjBjnKsgJuOBEjc#BAtz^{g>z+A zNS5y`vJn4-Jm)OIAu}8CnEa5L@%^#h88cRaY>2fBeRb%76l_|>cdxSxd4leo>`hM1 z=GaS{N9W+X*JoeyzI)v~{z>bJ6Jv}L@FeZxo9j?U+&8ZaHdi5nn@cvcf4SA==f#Yf z$jPlAJZxrq-VONtb(&Rhe}+}CAv1_?U?cTCX}mv}!TWQWgF2!ud7ElK)nO0n=3S_bznj!=4mYOeWb>AV+kfht*(m8logKsDUU>2Rghld{l5!n- zX8hci`0r*PnfW`vn>});%9rrn>}9ier(SY)Oy`}y|Lm9r@i2^kH#>FKf9C8Meg~Vo z>&Ty^8f3oxwXUe!A);3ab!pI%QZOfA$Fyp;=GVYKWFD~gpGv3R@!)ACc z0xzCVKoGsNT09sT&wnqTXF>2HUf6eD{4W@Zi{4$&#LH2w6YKvG;*#e7JX25bI~AIo{|9)H4E{ygD#r@-Bi}hE?1}Kd zjyTru;n_`|a+Hi3*FyC(es`NCc^J6||6bg9B0OC6#rV*~b7IF+re9KR>xZ>lqCqS-3TJL5UkLt_40KeOnzKjciBI~Lupj-<)@@Zae!o;?9X zwmfD-Zks=G&Z2y08=Gz~{t@3=Jk8}89||(9R}ap~XB+H-6=|VY-<^|x0D+M60o+g1 zzEb$YOZs@8yxgx8&U`6|_2y0`j%&#h(H6$*Q8xu_>aUjM-H#>O`##6Qovw+jE3t^r zz6ndNYOGdh>WkM0on@C>#Y2(kef?u_}s~O^8;vgmR0cG#(h7=*yBdi zOS<{u$E8CrE!-omq*!8lb>Y+MM)MIq2iC7&yFP2x>fE)fo_zZ8EY(W?vw2UfUH{}? ztjv3I?bBH+5nBCp-jlf!yk$np-7BA5vwBrl-rB5{Yu2nq^y(}eow#=WpEGLR`n9>M zH*EMXmV{b7gi9a%jyfL${1aeL0Gjp0>XoZjuSZD_J@nA0*(CSf>iEJ|t@=Hg1!33U zoR#~;%Jmyo=Y8?|uRm}%`!(h3k3Rc!-m_V`YgPhp&#hj+fw(f3++y6aIBTKtth_aD zQuw|~{Y*NilyjtaPU%OD|LMl^GuQCP4^WsFhkv0fl=0~)(%&xWCnR>EEu?>BiuAct#6L4dyfa1oPQ=IS^5c|ri+#(6 zy!E#jP~Q3A{@ik#9Q*prv#Xz7z5G!!?&V}+%h#`d=GiCLuU>_R4eQoEy^J>2o3%Uid8^wQ>&M+Te)Gw^J~|y zS}dvfYW*{Sk^rt-xqjtS8+yibKR> zm^#L>p8`ovU1XCSJD#m!SzJ8zColfVxOmdD7yn9JJjb#Z|E3#HIh+4peAta=z4PMY z8{BxNrEKk`_s%CxOyB3GXFS{Dr59-wVd@vN;^IC2!}Rg(x*uU)jAvf2oYjoPm6-lz z6+J2a58~qE;qh!nY!`J=ul%3KrH{wMuif~>^pqTV5uW(;@%W6dw^mZC^zre`&x^m; z;NOEMhmp7v+xr(PTH>j{d+E2j@r08$ATQqI_l)O!=*4^RGd?{oz8ufISnsv?_tG~p z5*Op+;Xfm>D*ie=d+9F+pW?;x$)mjZS#CVbiN~AANl7PH$EDB0GcT6oW|golcNNb( z-nG$vV0y1iM*S)-eqwe+X1Hg8F;_&(Uc1A5>_v%<(n6NLGKZTYr{Y z4(n&S#QMLFxMcO;M__Sz@`wseuKyLhNLGK!OqGN35HHrxK1!^g^GUM$H*vDSKj$0Pe;fYeuOGPe>n{A>J1^+{#_%Fp{@nx$7kOO# z<-zaepN0oMFN#lu=Q20{!i0D)pZ9yEn?E60%AlJ+G2YAP#b>GflWcxbH-E90(EauB z=S6=6`I$7^i*SFlT>P(a!^A)35ih^jFP}vIWH!GdPO3?+MEDtYN%fM{UjAL~OU@Al lDY1UeS#DQflHYO@{x+e)grLxMvizIe_Iox*ukghD{||j&rR@L! literal 0 HcmV?d00001