gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [libmicrohttpd] branch master updated: propsing NG API for


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] branch master updated: propsing NG API for MHD
Date: Tue, 18 Jul 2017 11:56:47 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository libmicrohttpd.

The following commit(s) were added to refs/heads/master by this push:
     new 66066283 propsing NG API for MHD
66066283 is described below

commit 66066283bd3733b168db454dd9297ba4262e407d
Author: Christian Grothoff <address@hidden>
AuthorDate: Tue Jul 18 11:43:25 2017 +0200

    propsing NG API for MHD
---
 src/include/microhttpd.h  |    7 -
 src/include/microhttpd2.h | 1960 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1960 insertions(+), 7 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index c5bf9a05..f8210d9b 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -1477,13 +1477,6 @@ enum MHD_OPTION
    * the "be as liberal as possible in what you accept" norm.  It is
    * recommended to set this to 1 if you are testing clients against
    * MHD, and 0 in production.
-   * if set to -1 - be opposite to strict and be permissive about the
-   * protocol, allowing slight deviations that are technically not
-   * allowed by the RFC. Specifically, at the moment, this flag
-   * causes MHD to allow spaces in header field names. This is
-   * disallowed by the standard.
-   * It is not recommended to set it to -1 on publicly available
-   * servers as it may potentially lower level of protection.
    * This option should be followed by an `int` argument.
    */
   MHD_OPTION_STRICT_FOR_CLIENT = 29
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
new file mode 100644
index 00000000..e97d748b
--- /dev/null
+++ b/src/include/microhttpd2.h
@@ -0,0 +1,1960 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2006-2017 Christian Grothoff (and other contributing 
authors)
+
+     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
+*/
+
+/**
+ * Just includes the NEW definitions for the NG-API.
+ * Note that we do not indicate which of the OLD APIs
+ * simply need to be kept vs. deprecated.
+ *
+ * The goal is to provide a basis for discussion!
+ * None of this is implemented yet.
+ *
+ * Main goals:
+ * - simplify application callbacks by splitting header/upload/post
+ *   functionality currently provided by calling the same 
+ *   MHD_AccessHandlerCallback 3+ times into separate callbacks.
+ * - avoid repeated scans for URL matches via the new
+ *   struct MHD_RequestHandlerCallbacks construction
+ * - provide default logarithmic implementation of URL scan
+ *   => reduce strcmp(url) from >= 3n operations to "log n"
+ *      per request.
+ * - better types, in particular avoid varargs for options
+ * - make it harder to pass inconsistent options
+ * - combine options and flags into more uniform API (at least
+ *   exterally!)
+ * - simplify API use by using sane defaults (benefiting from
+ *   breaking backwards compatibility) and making all options
+ *   really optional, and where applicable avoid having options
+ *   where the default works if nothing is specified
+ * - simplify API by moving rarely used http_version into
+ *   MHD_request_get_information()
+ * - avoid 'int' for MHD_YES/MHD_NO by introducing `enum MHD_Bool`
+ * - improve terminology by eliminating confusion between
+ *   'request' and 'connection'
+ * - prepare API for having multiple TLS backends
+ * - use more consistent prefixes for related functions
+ *   by using MHD_subject_verb_object naming convention, also
+ *   at the same time avoid symbol conflict with legacy names
+ *   (so we can have one binary implementing old and new 
+ *   library API at the same time via compatibility layer).
+ */
+
+
+/**
+ * Representation of 'bool' in the public API as stdbool.h may not
+ * always be available.
+ */
+enum MHD_Bool
+{
+
+  /**
+   * MHD-internal return code for "NO".
+   */
+  MHD_NO = 0,
+
+  /**
+   * MHD-internal return code for "YES".
+   */
+  MHD_YES = 1
+};
+
+
+/**
+ * @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.
+ *
+ * Replaces `struct MHD_Connection`, renamed to better reflect
+ * what this object truly represents to the application using
+ * MHD.
+ *
+ * @ingroup request
+ */
+struct MHD_Request;
+
+
+/**
+ * Enumeration used to define options in 
+ * `struct MHD_Option`. Opaque to the application.
+ */
+enum MHD_OptionValue;
+
+
+/**
+ * Option configuring the service.
+ */
+struct MHD_Option
+{
+  /**
+   * Which option is being given.  #MHD_OPTION_VALUE_END
+   * terminates the array.
+   */
+  enum MHD_OptionValue option;
+
+  /**
+   * Option value.
+   */
+  intptr_t value1;
+
+  /**
+   * Option value.
+   */
+  intptr_t value2;
+  
+  /**
+   * Option value.
+   */
+  intptr_t value3;
+
+};
+
+
+/**
+ * Returns terminating element of an option array.
+ *
+ * @return MHD option array terminator
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_end (void);
+
+
+/**
+ * Set logging method.  Specify NULL to disable logging entirely.  By
+ * default (if this option is not given), we log error messages to
+ * stderr.
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_log (MHD_LogCallback logger,
+               void *cls logger_cls);
+
+
+/**
+ * Convenience macro used to disable logging.
+ *
+ * @return MHD option that disables logging
+ */
+#define MHD_option_disable_logging() MHD_option_log (NULL, NULL)
+
+
+/**
+ * Suppress use of "Date" header as this system has no RTC.
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_suppress_date_no_clock (void);
+
+
+/**
+ * Use inter-thread communication channel.  #MHD_option_enable_itc()
+ * can be used with #MHD_option_thread_internal() and is ignored with
+ * any "external" mode.  It's required for use of
+ * #MHD_daemon_quiesce() or #MHD_connection_add().  This option is
+ * enforced by #MHD_option_allow_suspend_resume() and if there is no
+ * listen socket.  #MHD_option_enable_itc() is always used
+ * automatically on platforms where select()/poll()/other ignore
+ * shutdown of listen socket.
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_enable_itc (void);
+
+
+/**
+ * Enable `turbo`.  Disables certain calls to `shutdown()`,
+ * enables aggressive non-blocking optimistic reads and
+ * other potentially unsafe optimizations.
+ * Most effects only happen with #MHD_ELS_EPOLL.
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_enable_turbo (void);
+
+
+/**
+ * Enable suspend/resume functions, which also implies setting up
+ * #MHD_option_enable_itc() to signal resume.
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_allow_suspend_resume (void);
+
+
+/**
+ * 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.
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_allow_upgrade (void);
+
+
+/**
+ * Possible levels of enforcement for TCP_FASTOPEN.
+ */
+enum MHD_FastOpenMethod
+{
+  /** 
+   * Disable use of TCP_FASTOPEN.
+   */
+  MHD_FOM_DISABLE = -1,
+  
+  /**
+   * Enable TCP_FASTOPEN where supported (Linux with a kernel >= 3.6).
+   * This is the default.
+   */
+  MHD_FOM_AUTO = 0,
+
+  /**
+   * If TCP_FASTOPEN is not available, cause #MHD_daemon_start() to
+fail.
+  */
+  MHD_FOM_REQUIRE = 1
+};
+
+
+/**
+ * Configure TCP_FASTOPEN option, including setting a 
+ * custom @a queue_length.
+ *
+ * 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. 
+ *
+ * @param fom under which conditions should we use TCP_FASTOPEN?
+ * @param queue_length queue length to use, default is 50 if this
+ *        option is never given.
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_tcp_fastopen (enum MHD_FastOpenMethod fom,
+                        unsigned int queue_length);
+
+
+/**
+ * Bind to the given TCP port.
+ * Ineffective in conjunction with #MHD_option_listen_socket().
+ * Ineffective in conjunction with #MHD_option_bind_sa().
+ *
+ * If neither this option nor the other two mentioned above
+ * is specified, MHD will simply not listen on any socket!
+ *
+ * @param port port to use, 0 to bind to a random (free) port
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_bind_port (uint16_t port);
+
+
+/**
+ * Bind to the given socket address.
+ * Ineffective in conjunction with #MHD_option_listen_socket().
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_bind_socket_address (const struct sockaddr *sa);
+
+
+/**
+ * Use the given backlog for the listen() call.
+ * Ineffective in conjunction with #MHD_option_listen_socket().
+ *
+ * @param listen_backlog backlog to use
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_listen_queue (int listen_backlog);
+
+
+/**
+ * If present 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 plaform, but uses SO_EXCLUSIVEADDRUSE on
+ * Windows).
+ * Ineffective in conjunction with #MHD_option_listen_socket().
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_listen_allow_address_reuse (void);
+
+
+/**
+ * Accept connections from the given socket.  Socket
+ * must be a TCP or UNIX domain (stream) socket.
+ * 
+ * Disables other listen options, including
+ * #MHD_option_bind_sa(), #MHD_option_bind_port(),
+ * #MHD_option_listen_queue() and
+ * #MHD_option_listen_allow_address_reuse().
+ *
+ * @param listen_socket listen socket to use
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_listen_socket (int listen_socket);
+
+
+/**
+ * Event loop syscalls supported by MHD.
+ */
+enum MHD_EventLoopSyscall
+{
+  /**
+   * Automatic selection of best-available method. This is also the
+   * default.
+   */ 
+  MHD_ELS_AUTO = 0,
+
+  /**
+   * Use select().
+   */
+  MHD_ELS_SELECT = 1,
+  
+  /**
+   * Use poll().
+   */
+  MHD_ELS_POLL = 2,
+  
+  /**
+   * Use epoll().
+   */
+  MHD_ELS_EPOLL = 3
+};
+
+
+/**
+ * Force use of a particular event loop system call.
+ * 
+ * @param els event loop syscall to use
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_event_loop (enum MHD_EventLoopSyscall els);
+
+
+/**
+ * Protocol strictness enforced by MHD on clients.
+ */
+enum MHD_ProtocolStrictLevel
+{
+  /**
+   * Be particularly permissive about the protocol, allowing slight
+   * deviations that are technically not allowed by the
+   * RFC. Specifically, at the moment, this flag causes MHD to allow
+   * spaces in header field names. This is disallowed by the standard.
+   * It is not recommended to set this value on publicly available
+   * servers as it may potentially lower level of protection.
+   */
+  MHD_SL_PERMISSIVE = -1,
+
+  /**
+   * Sane level of protocol enforcement for production use.
+   */
+  MHD_SL_DEFAULT = 0,
+
+  /**
+   * Be strict about the protocol (as opposed to as tolerant as
+   * possible).  Specifically, at the moment, this flag causes MHD to
+   * reject HTTP 1.1 connections without a "Host" header.  This is
+   * required by the standard, but of course in violation of the "be
+   * as liberal as possible in what you accept" norm.  It is
+   * recommended to set this if you are testing clients against
+   * MHD, and to use default in production.
+   */
+  MHD_SL_STRICT = 1
+};
+
+
+/**
+ * Set how strictly MHD will enforce the HTTP protocol.
+ * 
+ * @param sl how strict should we be
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_protocol_strict_level (enum MHD_ProtocolStrictLevel sl);
+
+
+/**
+ * Enable TLS.
+ *
+ * @param tls_backend which TLS backend should be used,
+ *    currently only "gnutls" is supported.  You can
+ *    also specify "NULL" for best-available (which is the default).
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_tls (const char *tls_backend);
+
+
+/**
+ * Provide TLS key and certificate data in-memory.
+ *
+ * @param mem_key private key (key.pem) to be used by the
+ *     HTTPS daemon.  Must be the actual data in-memory, not a filename.
+ * @param mem_cert certificate (cert.pem) to be used by the
+ *     HTTPS daemon.  Must be the actual data in-memory, not a filename.
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_tls_key_and_cert_from_memory (const char *mem_key,
+                                        const char *mem_cert);
+
+
+/**
+ * Provide passphrase to decrypt 'key.pem' (if required).
+ *
+ * @param pass passphrase phrase to decrypt 'key.pem'
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_tls_key_passphrase (const char *pass);
+
+
+/**
+ * Configure TLS ciphers to use.  Default is "NORMAL".
+ *
+ * @param ciphers which ciphers should be used by TLS
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_tls_ciphers (const char *ciphers);
+
+
+/**
+ * Configure DH parameters (dh.pem) to use for the TLS key
+ * exchange. 
+ *
+ * @param dh parameters to use
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_tls_mem_dhparams (const char *dh);
+
+
+/**
+ * Memory pointer for the certificate (ca.pem) to be used by the
+ * HTTPS daemon for client authentification.  
+ *
+ * @param mem_trust memory pointer to the certificate
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_tls_mem_trust (const char *mem_trust);
+
+
+/**
+ * Configure daemon credentials type for GnuTLS.
+ *
+ * @param gnutls_credentials must be a value of
+ *   type `gnutls_credentials_type_t`
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_gnutls_credentials (int gnutls_credentials);
+
+
+/**
+ * Provide TLS key and certificate data via callback.
+ *
+ * Use a callback to determine which X.509 certificate should be used
+ * for a given HTTPS connection.  This option provides an alternative
+ * to #MHD_option_tls_key_and_cert_from_memory().  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.
+   *
+ * @param cb must be of type `gnutls_certificate_retrieve_function2 *`.
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_gnutls_key_and_cert_from_callback (void *cb);
+
+
+/**
+ * Run using a specific address family (by default, MHD will support
+ * dual stack if supported by the operating system).
+ *
+ * @param af address family to use, i.e. #AF_INET or #AF_INET6,
+ *           or #AF_UNSPEC for dual stack
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_address_family (int af);
+
+
+/**
+ * Enable use of one thread per connection.
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_thread_per_connection (void);
+
+
+/**
+ * Enable use of MHD-internal worker thread.
+ *
+ * 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 option is set,
+ * #MHD_run() and #MHD_run_from_select() cannot be used.   
+ *
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_thread_iternal (void);
+
+
+/**
+ * Enable use of a thread pool of the given size.
+ *
+ * @param num_threads number of threads to run in the pool
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_thread_pool_size (unsigned int num_threads);
+
+
+/**
+ * Allow or deny a client to connect.
+ *
+ * @param cls closure
+ * @param addr address information from the client
+ * @param addrlen length of @a addr
+ * @see #MHD_option_accept_policy()
+ * @return #MHD_YES if connection is allowed, #MHD_NO if not
+ */
+typedef enum MHD_Bool
+(*MHD_AcceptPolicyCallback) (void *cls,
+                             const struct sockaddr *addr,
+                             socklen_t addrlen);
+
+
+/**
+ * Return option setting a policy that accepts/rejects connections
+ * based on the client's IP address.  This function will be called
+ * before a connection object is created.
+ *
+ * @param apc function to call to check the policy
+ * @param apc_cls closure for @a apc
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_accept_policy (MHD_AcceptPolicyCallback apc,
+                         void *apc_cls);
+
+
+/**
+ * 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 "con_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_ConnectionCompletedCallback) (void *cls,
+                                   struct MHD_Connection *connection,
+                                   enum MHD_ConnectionNotificationCode toe);
+
+
+/**
+ * Register a function that should be called whenever a connection is
+ * started or closed.
+ *
+ * @param ncc function to call to check the policy
+ * @param ncc_cls closure for @a apc
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_set_notify_connection (MHD_NotifyConnectionCallback ncc,
+                                 void *ncc_cls);
+
+
+/**
+ * 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.
+ *
+ * @param memory_limit_b connection memory limit to use in bytes
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_connection_memory_limit (size_t memory_limit_b);
+
+
+/**
+ * Increment to use for growing the read buffer (followed by a
+ * `size_t`). Must fit within #MHD_option_connection_memory_limit()).
+ *
+ * @param memory_limit_b connection memory limit to use in bytes
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_connection_memory_increment (size_t memory_increment_b);
+
+
+/**
+ * Desired size of the stack for threads created by MHD.  Use 0 for
+ * system default.
+ *
+ * @param stack_limit_b stack size to use in bytes
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_thread_stack_size (size_t stack_limit_b);
+
+
+/**
+ * Set maximum number of concurrent connections to accept.  If not
+ * given, MHD will not enforce any global limit (modulo running into
+ * OS limits).
+ *
+ * @param connection_limit maximum number of concurrent connections
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_connection_global_limit (unsigned int connection_limit);
+
+
+/**
+ * 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 default is
+ * zero, which means no limit on the number of connections
+ * from the same IP address.
+ *
+ * @param connection_limit maximum number of concurrent connections
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_connection_ip_limit (unsigned int connection_limit);
+
+
+/**
+ * After how many seconds of inactivity should a
+ * connection automatically be timed out? 
+ * Use zero for no timeout, which is also the (unsafe!) default.
+ *
+ * @param timeout_s number of seconds of timeout to use
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_connection_default_timeout (unsigned int timeout_s);
+
+
+/**
+ * Signature of functions performing unescaping of strings.
+ * The return value must be "strlen(s)" and @a s  should be
+ * updated.  Note that the unescape function must not lengthen @a s
+ * (the result must be shorter than the input and still be
+ * 0-terminated).  
+ *
+ * @param cls closure
+ * @param req the request for which unescaping is performed
+ * @param[in,out] s string to unescape
+ * @return number of characters in @a s (excluding 0-terminator)
+ */
+typedef size_t
+MHD_UnescapeCallback (void *cls,
+                     struct MHD_Request *req,
+                     char *s);
+
+
+/**
+ * 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". 
+ *
+ * @param unescape_cb function to use, NULL for default
+ * @param unescape_cb_cls closure for @a unescape_cb
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_unescape_cb (MHD_UnescapeCallback unescape_cb,
+                       void *unescape_cb_cls);
+
+
+/**
+ * Set random values to be used by the Digest Auth module.  Note that
+ * the application must ensure that @a buf remains allocated and
+ * unmodified while the deamon is running.
+ *
+ * @param buf_size number of bytes in @a buf
+ * @param buf entropy buffer
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_digest_auth_random (size_t buf_size,
+                              const void *buf);
+
+
+/**
+ * Size of the internal array holding the map of the nonce and
+ * the nonce counter. 
+ *
+ * @param nc_length desired array length
+ * @return MHD option
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_digest_auth_nc_size (size_t stack_limit_b);
+
+
+/**
+ * Return option setting a callback to call upon connection
+ * completion.
+ *
+ * @param ccc function to call
+ * @param ccc_cls closure for @a ccc
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_connection_completion (MHD_ConnectionCompledCallback ccc,
+                                 void *ccc_cls;)
+
+  
+/**
+ * Signature of the callback used by MHD to notify the application
+ * that we have received the full header of a request.  Can be used to
+ * send error responses to a "Expect: 100-continue" request.
+ * Note that regular responses should be set in the
+ * #MHD_RequestCompletedCallback.
+ *
+ * @param cls client-defined closure
+ * @ingroup request
+ * @return #MHD_YES if the upload was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serios
+ *         error while handling the request
+ */
+typedef enum MHD_Bool
+(*MHD_RequestHeaderCallback) (void *cls);
+
+
+/**
+ * A client has uploaded data.
+ *
+ * @param cls argument given together with the function
+ *        pointer when the handler was registered with MHD
+ * @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;
+ * @return #MHD_YES if the upload was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serios
+ *         error while handling the request
+ */
+typedef enum MHD_Bool
+(*MHD_UploadCallback) (void *cls,
+                      const char *upload_data,
+                      size_t *upload_data_size);
+
+
+/**
+ * Signature of the callback used by MHD to notify the application
+ * that we now expect a response.  The application can either
+ * call #MHD_response_queue() or suspend the request or return
+ * #MHD_NO.
+ *
+ * @param cls client-defined closure
+ * @ingroup request
+ * @return #MHD_YES if the upload was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serios
+ *         error while handling the request
+ */
+typedef enum MHD_Bool
+(*MHD_RequestFetchResponseCallback) (void *cls);
+
+
+/**
+ * Signature of the callback used by MHD to notify the
+ * application about completed requests.
+ *
+ * @param cls client-defined closure
+ * @param toe reason for request termination
+ * @see #MHD_option_request_completion()
+ * @ingroup request
+ */
+typedef void
+(*MHD_RequestCompletedCallback) (void *cls,
+                                 enum MHD_RequestTerminationCode toe);
+
+
+/**
+ * Functions called for an MHD request to process it.
+ * Not all functions must be implemented for each request.
+ */
+struct MHD_RequestHandlerCallbacks
+{
+  /**
+   * Closure argument passed to all callbacks in this struct.
+   */
+  void *cls;
+
+  /** 
+   * Function called after we have received the full HTTP header.
+   */
+  MHD_RequestHeaderCallback header_cb;
+
+  /**
+   * Function called if we receive uploaded data.
+   */
+  MHD_UploadCallback upload_cb;
+
+  /**
+   * Function called when we expect the application to
+   * generate a response (mandatory to be set; if not
+   * set and #MHD_NO is not returned, MHD will generate
+   * 500 internal error and log an error).
+   */
+  MHD_RequestFetchResponseCallback fetch_response_cb;
+
+  /**
+   * Function called last to clean up.  Gives the
+   * application a chance to check on the final status of
+   * the request (and to clean up @e cls).
+   */
+  MHD_RequestCompletedCallback completed_cb;
+
+};
+
+
+/**
+ * A client has requested the given url using the given method
+ * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
+ * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc).  The callback
+ * must initialize @a rhp to provide further callbacks which will
+ * process the request further and ultimately to provide the response
+ * to give back to the client.
+ *
+ * @param cls argument given together with the function
+ *        pointer when the handler was registered with MHD
+ * @param url the requested url (without arguments after "?")
+ * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
+ *        #MHD_HTTP_METHOD_PUT, etc.)
+ * @param[out] must be set to function pointers to be used to
+ *        handle the request further; can be assumed to have
+ *        been initialized to all-NULL values already.
+ * @return #MHD_YES if the request was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serios
+ *         error while handling the request
+ */
+typedef enum MHD_Bool
+(*MHD_RequestCallback) (void *cls,
+                       struct MHD_Request *request,
+                       const char *url,
+                       const char *method,
+                       struct MHD_RequestHandlerCallbacks *rhp);
+
+
+/**
+ * Generic option to set a global URL handler which
+ * will be called for all requests.  You may prefer the
+ * more convenient, but less generic #MHD_option_url_table().
+ *
+ * @param rc function to call for requests
+ * @param rc_cls closure to give to @a rc
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_url_handler (MHD_RequestCallback rc,
+                       void *rc_cls);
+
+
+/**
+ * A client has requested the given url using the given method
+ * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
+ * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc).  The callback
+ * must initialize @a rhp to provide further callbacks which will
+ * process the request further and ultimately to provide the response
+ * to give back to the client.
+ *
+ * @param cls argument given together with the function
+ *        pointer when the handler was registered with MHD
+ * @param request HTTP request handle
+ * @param[out] must be set to function pointers to be used to
+ *        handle the request further; can be assumed to have
+ *        been initialized to all-NULL values already.
+ * @return #MHD_YES if the request was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serious
+ *         error while handling the request
+ */
+typedef enum MHD_Bool
+(*MHD_RequestStartCallback) (void *cls,
+                            struct MHD_Request *request,
+                            struct MHD_RequestHandlerCallbacks *rhp);
+
+
+/**
+ * Definition of a request handler for a URL and method.
+ */
+struct MHD_UrlHandler;
+
+
+/**
+ * Create URL handler array terminator.
+ */
+_MHD_EXTERN struct MHD_UrlHandler
+MHD_url_handler_end (void);
+
+
+/**
+ * Create a generic URL handler array entry.
+ *
+ * @param method HTTP method to which this handler
+ *   matches. Case-insensitive, i.e. "GET".
+ * @param url Which URL does this handler match. Case-sensitive,
+ *   i.e. "/favicon.ico".
+ * @param start_cb function to call for matching requests
+ * @param start_cb_cls closure for @a start_cb
+ * @return url handler array entry
+ */
+_MHD_EXTERN struct MHD_UrlHandler
+MHD_url_handler_generic (const char *method,
+                        const char *url,
+                        MHD_RequestStartCallback start_cb,
+                        void *start_cb_cls);
+
+
+/**
+ * Create a simple URL handler array entry for requests
+ * where the application simply returns a response and
+ * has no state to initialize or clean up and where there
+ * is no upload.
+ *
+ * @param method HTTP method to which this handler
+ *   matches. Case-insensitive, i.e. "GET".
+ * @param url Which URL does this handler match. Case-sensitive,
+ *   i.e. "/favicon.ico".
+ * @param fetch_cb function to call for matching requests
+ * @param fetch_cb_cls closure for @a fetch_cb
+ * @return url handler array entry
+ */
+_MHD_EXTERN struct MHD_UrlHandler
+MHD_url_handler_simple (const char *method,
+                       const char *url,
+                       MHD_RequestFetchResponseCallback fetch_cb,
+                       void *fetch_cb_cls);
+
+
+/**
+ * Set a table of @a handlers to process requests of matching methods
+ * and URLs.  Requests that do not match any entry will yield a 404
+ * NOT FOUND response.  Note that this function may sort the @a
+ * handlers array in-place for faster (logarithmic) lookups later,
+ * hence the argument must be muteable.  The @a handlers array must
+ * remain allocated by the application throughout the lifetime of the
+ * daemon!
+ *
+ * @param[in,out] handlers url handler table, terminated
+ *     by #MHD_url_handler_end()
+ * @return option array entry
+ */
+_MHD_EXTERN struct MHD_Option
+MHD_option_url_table (struct MHD_UrlHandler handlers[]);
+
+
+/* **************** Daemon handling functions ***************** */
+
+/**
+ * Start a webserver on the given port.
+ *
+ * @param options array of options, does NOT have to
+ *        persist in memory past this call (note that individual
+ *        arguments passed to the functions may need to
+ *        be preserved)
+ * @return NULL on error, handle to daemon on success
+ * @ingroup event
+ */
+_MHD_EXTERN struct MHD_Daemon *
+MHD_daemon_start (const struct MHD_Option options[]);
+
+
+/**
+ * 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 select 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_daemon_quiesce (struct MHD_Daemon *daemon);
+
+
+/**
+ * Shutdown an HTTP daemon.
+ *
+ * @param daemon daemon to stop
+ * @ingroup event
+ */
+_MHD_EXTERN void
+MHD_daemon_stop (struct MHD_Daemon *daemon);
+
+
+/* ********************* connection options ************** */
+
+/**
+ * MHD connection options.  Given to #MHD_set_connection_option() to
+ * set custom options for a particular connection.
+ */
+struct MHD_ConnectionOption;
+
+
+/**
+ * Generate array terminator for connection options.
+ */
+struct MHD_ConnectionOption
+MHD_connection_option_end (void);
+
+
+/**
+ * Generate option to set a custom timeout for the given connection.
+ * Specified as the number of seconds.  Use zero for no timeout.  If
+ * timeout was set to zero (or unset) before, setting of a new value
+ * by MHD_connection_set_option() will reset timeout timer.
+ * 
+ * @param timeout_s new timeout in seconds
+ */
+struct MHD_ConnectionOption
+MHD_connection_option_timeout (unsigned int timeout_s);
+
+
+/**
+ * Set a custom option for the given connection, overriding defaults.
+ *
+ * @param connection connection to modify
+ * @param options array of options to set, does NOT have to
+ *        persist past this call
+ * @ingroup specialized
+ * @return #MHD_YES on success
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_connection_set_options (struct MHD_Connection *connection,
+                           struct MHD_ConnectionOption options[]);
+
+
+/* **************** Request handling functions ***************** */
+
+/**
+ * Get all of the headers from the request.
+ *
+ * @param request request to get values from
+ * @param kind types of values to iterate over, can be a bitmask
+ * @param iterator callback to call on each header;
+ *        maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over
+ * @ingroup request
+ */
+_MHD_EXTERN unsigned int
+MHD_request_get_values (struct MHD_Request *request,
+                       enum MHD_ValueKind kind,
+                       MHD_KeyValueIterator iterator,
+                       void *iterator_cls);
+
+
+/**
+ * This function can be used to add an entry to the HTTP headers of a
+ * request (so that the #MHD_request_get_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
+ * request callbacks (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 request the request 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_Bool
+MHD_request_set_value (struct MHD_Request *request,
+                      enum MHD_ValueKind kind,
+                      const char *key,
+                      const char *value);
+
+
+/**
+ * Get a particular header value.  If multiple
+ * values match the kind, return any one of them.
+ *
+ * @param request request 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_request_lookup_value (struct MHD_Request *request,
+                         enum MHD_ValueKind kind,
+                         const char *key);
+
+
+/**
+ * Queue a response to be transmitted to the client (as soon as
+ * possible but after the current callback returns).
+ *
+ * @param request the request identifying the client
+ * @param status_code HTTP status code (i.e. #MHD_HTTP_OK)
+ * @param response response to transmit
+ * @return #MHD_NO on error (i.e. reply already sent),
+ *         #MHD_YES on success or if message has been queued
+ * @ingroup response
+ */
+_MHD_EXTERN int
+MHD_request_queue_response (struct MHD_Request *request,
+                           unsigned int status_code,
+                           struct MHD_Response *response);
+
+
+/**
+ * Suspend handling of network data for a given request.  This can
+ * be used to dequeue a request from MHD's event loop for a while.
+ *
+ * If you use this API in conjunction with a internal select or a
+ * thread pool, you must set the option #MHD_USE_ITC to
+ * ensure that a resumed request is immediately processed by MHD.
+ *
+ * Suspended requests continue to count against the total number of
+ * requests allowed (per daemon, as well as per IP, if such limits
+ * are set).  Suspended requests will NOT time out; timeouts will
+ * restart when the request handling is resumed.  While a
+ * request is suspended, MHD will not detect disconnects by the
+ * client.
+ *
+ * The only safe time to suspend a request is from the
+ * #MHD_AccessHandlerCallback.
+ *
+ * Finally, it is an API violation to call #MHD_stop_daemon while
+ * having suspended requests (this will at least create memory and
+ * socket leaks or lead to undefined behavior).  You must explicitly
+ * resume all requests before stopping the daemon.
+ *
+ * @param request the request to suspend
+ */
+_MHD_EXTERN void
+MHD_request_suspend (struct MHD_Request *request);
+
+
+/**
+ * Resume handling of network data for suspended request.  It is
+ * safe to resume a suspended request at any time.  Calling this
+ * function on a request that was not previously suspended will
+ * result in undefined behavior.
+ *
+ * If you are using this function in ``external'' select mode, you must
+ * make sure to run #MHD_run() 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
+ * request that is stuck until the next network activity.
+ *
+ * @param request the request to resume
+ */
+_MHD_EXTERN void
+MHD_request_resume (struct MHD_Request *request);
+
+
+/* **************** Response manipulation functions ***************** */
+
+
+/**
+ * MHD response option.
+ */
+struct MHD_ResponseOption;
+
+
+/**
+ * End of options array.
+ */
+struct MHD_ResponseOption
+MHD_response_option_end (void);
+
+
+/**
+ * Only respond in conservative HTTP 1.0-mode.   In particular,
+ * do not (automatically) sent "Connection" headers and always
+ * close the connection after generating the response.
+ */
+struct MHD_ResponseOption
+MHD_response_option_v10_only (void);
+
+
+/**
+ * Set special @a options for a @a response.
+ *
+ * @param response the response to modify
+ * @param options options to set for the response
+ * @return #MHD_YES on success, #MHD_NO on error
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_response_set_options (struct MHD_Response *response,
+                          enum MHD_ResponseOption options[]);
+
+
+/**
+ * Create a response object.  The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @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_response_from_callback (uint64_t size,
+                           size_t block_size,
+                           MHD_ContentReaderCallback crc,
+                           void *crc_cls,
+                           MHD_ContentReaderFreeCallback crfc);
+
+
+/**
+ * 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).
+   * @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
+
+};
+
+
+/**
+ * Create a response object.  The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @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_response_from_buffer (size_t size,
+                         void *buffer,
+                         enum MHD_ResponseMemoryMode mode);
+
+
+/**
+ * Create a response object based on an @a fd from which
+ * data is read.  The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @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
+ * @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
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_response_from_fd (int fd,
+                     uint64_t offset,
+                     uint64_t size);
+
+
+/**
+ * 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
+
+};
+
+
+/**
+ * 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_Bool
+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 con_cls last value left in `con_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 *con_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_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 immediatley.
+ *
+ * @param response response to destroy
+ * @ingroup response
+ */
+_MHD_EXTERN void
+MHD_response_destroy (struct MHD_Response *response);
+
+
+/**
+ * Add a header line to the response.
+ *
+ * @param response response to add a header to
+ * @param header the header to add
+ * @param content value to add
+ * @return #MHD_NO on error (i.e. invalid header or content format),
+ *         or out of memory
+ * @ingroup response
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_response_add_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_Bool
+MHD_response_add_footer (struct MHD_Response *response,
+                         const char *footer,
+                        const char *content);
+
+
+/**
+ * Delete a header (or footer) line from the response.
+ *
+ * @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_Bool
+MHD_response_del_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;
+ *        maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over
+ * @ingroup response
+ */
+_MHD_EXTERN unsigned int
+MHD_response_get_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_response_get_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_post_processor_create (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_Bool
+MHD_post_processor_run (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_Bool
+MHD_post_processor_destroy (struct MHD_PostProcessor *pp);
+
+
+/* ********************** generic query functions ********************** */
+
+
+/**
+ * Select which member of the `struct ConnectionInformation`
+ * union is desired to be returned by #MHD_connection_get_info().
+ */
+enum MHD_ConnectionInformationType
+{
+  /**
+   * What cipher algorithm is being used.
+   * Takes no extra arguments.
+   * @ingroup request
+   */
+  MHD_CONNECTION_INFORMATION_CIPHER_ALGO,
+
+  /**
+   *
+   * Takes no extra arguments.
+   * @ingroup request
+   */
+  MHD_CONNECTION_INFORMATION_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_INFORMATION_CLIENT_ADDRESS,
+
+  /**
+   * Get the gnuTLS session handle.
+   * @ingroup request
+   */
+  MHD_CONNECTION_INFORMATION_GNUTLS_SESSION,
+
+  /**
+   * Get the gnuTLS client certificate handle.  Dysfunctional (never
+   * implemented, deprecated).  Use #MHD_CONNECTION_INFORMATION_GNUTLS_SESSION
+   * to get the `gnutls_session_t` and then call
+   * gnutls_certificate_get_peers().
+   */
+  MHD_CONNECTION_INFORMATION_GNUTLS_CLIENT_CERT,
+
+  /**
+   * Get the `struct MHD_Daemon *` responsible for managing this connection.
+   * @ingroup request
+   */
+  MHD_CONNECTION_INFORMATION_DAEMON,
+
+  /**
+   * Request the file descriptor for the connection socket.
+   * No extra arguments should be passed.
+   * @ingroup request
+   */
+  MHD_CONNECTION_INFORMATION_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 "con_cls"
+   * argument of the #MHD_AccessHandlerCallback.  The "con_cls" is
+   * fresh for each HTTP request, while the "socket_context" is fresh
+   * for each socket.
+   */
+  MHD_CONNECTION_INFORMATION_SOCKET_CONTEXT,
+
+  /**
+   * Get connection timeout
+   * @ingroup request
+   */
+  MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT
+
+};
+
+
+/**
+ * Information about a connection.
+ */
+union MHD_ConnectionInformation
+{
+
+  /**
+   * 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;
+
+  /**
+   * Amount of second that connection could spend in idle state
+   * before automatically disconnected.
+   * Zero for no timeout (unlimited idle time).
+   */
+  unsigned int connection_timeout;
+
+  /**
+   * Connect socket
+   */
+  MHD_socket connect_fd;
+
+  /**
+   * 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;
+};
+
+
+/**
+ * Obtain information about the given connection.
+ *
+ * @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_ConnectionInformation *
+MHD_connection_get_information (struct MHD_Connection *connection,
+                               enum MHD_ConnectionInformationType info_type,
+                               ...);
+
+
+/**
+ * Information we return about a request.
+ */
+union MHD_RequestInformation
+{
+
+  /**
+   * Connection via which we received the request.
+   */
+  struct MHD_Connection *connection;
+
+  /**
+   * The suspended status of a request.
+   */
+  enum MHD_Bool suspended;
+
+  /**
+   * HTTP version requested by the client.
+   */
+  const char *http_version;
+  
+  /**
+   * Size of the client's HTTP header.
+   */
+  size_t header_size;
+
+};
+
+
+/**
+ * Select which member of the `struct RequestInformation`
+ * union is desired to be returned by #MHD_request_get_info().
+ */
+enum MHD_RequestInformationType
+{
+  /**
+   * Return which connection the request is associated with.
+   */
+  MHD_REQUEST_INFORMATION_CONNECTION,
+  
+  /**
+   * Check whether the connection is suspended.
+   * @ingroup request
+   */
+  MHD_REQUEST_INFORMATION_SUSPENDED,
+  
+  /**
+   * Return the HTTP version string given by the client.
+   * @ingroup request
+   */
+  MHD_REQUEST_INFORMATION_HTTP_VERSION,
+  
+  /**
+   * Return length of the client's HTTP request header.
+   * @ingroup request
+   */
+  MHD_REQUEST_INFORMATION_HEADER_SIZE
+};
+
+
+/**
+ * Obtain information about the given connection.
+ *
+ * @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_RequestInformation *
+MHD_request_get_information (struct MHD_Request *request,
+                            enum MHD_RequestInformationType info_type,
+                            ...);
+
+
+/**
+ * Values of this enum are used to specify what
+ * information about a deamon is desired.
+ */
+enum MHD_DaemonInformationType
+{
+
+  /**
+   * Request the file descriptor for the listening socket.
+   * No extra arguments should be passed.
+   */
+  MHD_DAEMON_INFORMATION_LISTEN_FD,
+
+  /**
+   * Request the file descriptor for the external epoll.
+   * No extra arguments should be passed.
+   */
+  MHD_DAEMON_INFORMATION_EPOLL_FD,
+
+  /**
+   * 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_INFORMATION_CURRENT_CONNECTIONS,
+
+  /**
+   * Request the port number of daemon's listen socket.
+   * No extra arguments should be passed.
+   * Note: if port '0' was specified for #MHD_option_port(), returned
+   * value will be real port number.
+   */
+  MHD_DAEMON_INFORMATION_BIND_PORT
+};
+
+
+/**
+ * Information about an MHD daemon.
+ */
+union MHD_DaemonInformation
+{
+
+  /**
+   * Socket, returned for #MHD_DAEMON_INFORMATION_LISTEN_FD.
+   */
+  MHD_socket listen_fd;
+
+  /**
+   * Bind port number, returned for #MHD_DAEMON_INFORMATION_BIND_PORT.
+   */
+  uint16_t port;
+
+  /**
+   * epoll FD, returned for #MHD_DAEMON_INFORMATION_EPOLL_FD.
+   */
+  int epoll_fd;
+
+  /**
+   * Number of active connections, for 
#MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS.
+   */
+  unsigned int num_connections;
+
+};
+
+
+/**
+ * Obtain information about the given daemon
+ * (not fully implemented!).
+ *
+ * @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_DaemonInformation *
+MHD_daemon_get_information (struct MHD_Daemon *daemon,
+                           enum MHD_DaemonInformationType info_type,
+                           ...);
+

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]