|
|
@@ -2614,1624 +2614,1987 @@ MHD_EXTERN_ void
|
|
|
MHD_daemon_destroy (struct MHD_Daemon *daemon)
|
|
|
MHD_FN_PAR_NONNULL_ALL_;
|
|
|
|
|
|
+/* ******************* External event loop ************************ */
|
|
|
|
|
|
-/* ********************* daemon options ************** */
|
|
|
-
|
|
|
-/**
|
|
|
- * Type of a callback function used for logging by MHD.
|
|
|
- *
|
|
|
- * @param cls closure
|
|
|
- * @param sc status code of the event
|
|
|
- * @param fm format string (`printf()`-style)
|
|
|
- * @param ap arguments to @a fm
|
|
|
- * @ingroup logging
|
|
|
- */
|
|
|
-typedef void
|
|
|
-(MHD_FN_PAR_NONNULL_(3)
|
|
|
- MHD_FN_PAR_CSTR_(3)
|
|
|
- *MHD_LoggingCallback)(void *cls,
|
|
|
- enum MHD_StatusCode sc,
|
|
|
- const char *fm,
|
|
|
- va_list ap);
|
|
|
-
|
|
|
-// FIXME: convert
|
|
|
/**
|
|
|
- * Convenience macro used to disable logging.
|
|
|
+ * The network status of the socket.
|
|
|
+ * When set by MHD (by #MHD_get_watched_fds(), #MHD_get_watched_fds_update() and
|
|
|
+ * similar) it indicates a request to watch for specific socket state:
|
|
|
+ * readiness for receiving the data, readiness for sending the data and/or
|
|
|
+ * exception state of the socket.
|
|
|
+ * When set by application (and provided for #MHD_process_watched_fds() and
|
|
|
+ * similar) it must indicate the actual status of the socket.
|
|
|
*
|
|
|
- * @param daemon which instance to disable logging for
|
|
|
- */
|
|
|
-#define MHD_daemon_disable_logging(daemon) \
|
|
|
- MHD_daemon_set_logger ((daemon), \
|
|
|
- MHD_STATIC_CAST_(MHD_LoggingCallback,NULL), \
|
|
|
- NULL)
|
|
|
-
|
|
|
-/**
|
|
|
- * Parameter for listen socket binding type
|
|
|
+ * Any actual state is a bitwise OR combination of #MHD_FD_STATE_RECV,
|
|
|
+ * #MHD_FD_STATE_SEND, #MHD_FD_STATE_EXCEPT.
|
|
|
+ * @ingroup event
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOptionBindType
|
|
|
+enum MHD_FIXED_ENUM_ MHD_FdState
|
|
|
{
|
|
|
/**
|
|
|
- * The listen socket bind to the networks address without sharing the address.
|
|
|
- * Default.
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_BIND_TYPE_NOT_SHARED = 0
|
|
|
- ,
|
|
|
- /**
|
|
|
- * The listen socket bind to the networks address with sharing the address.
|
|
|
- * Several sockets can bind to the same address.
|
|
|
+ * The socket is not ready for receiving or sending and
|
|
|
+ * does not have any exceptional state.
|
|
|
+ * The state never set by MHD, except de-registration of the sockets
|
|
|
+ * for #MHD_SocketRegistrationUpdateCallback().
|
|
|
*/
|
|
|
- MHD_DAEMON_OPTION_BIND_TYPE_SHARED = 1
|
|
|
+ MHD_FD_STATE_NONE = 0
|
|
|
,
|
|
|
- /**
|
|
|
- * The list socket bind to the networks address in explicit exclusive mode.
|
|
|
- * Ignored on platforms without support for the explicit exclusive socket use.
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_BIND_TYPE_EXCLUSIVE = 2
|
|
|
-};
|
|
|
-
|
|
|
+ /* ** Three bit-flags ** */
|
|
|
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOption
|
|
|
-{
|
|
|
- /**
|
|
|
- * Not a real option.
|
|
|
- * Should not be used directly.
|
|
|
- * This value indicates the end of the list of the options.
|
|
|
- */
|
|
|
- MHD_D_O_END = 0
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Suppresses use of "Date:" header.
|
|
|
- * According to RFC should be used only if the system has no RTC.
|
|
|
- * The "Date:" is not suppressed (the header is enabled) by default.
|
|
|
- */
|
|
|
- MHD_D_O_BOOL_SUPPRESS_DATE_HEADER = 100
|
|
|
- ,
|
|
|
/**
|
|
|
- * Enable `turbo`. Disables certain calls to `shutdown()`,
|
|
|
- * enables aggressive non-blocking optimistic reads and
|
|
|
- * other potentially unsafe optimisations.
|
|
|
- * Most effects only happen with internal threads with epoll.
|
|
|
- * The 'turbo' mode is not enabled (mode is disabled) by default.
|
|
|
+ * Indicates that socket should be watched for incoming data
|
|
|
+ * (when set by #MHD_get_watched_fds())
|
|
|
+ * / socket has incoming data ready to read (when used for
|
|
|
+ * #MHD_process_watched_fds())
|
|
|
*/
|
|
|
- MHD_D_O_BOOL_TURBO = 102
|
|
|
- ,
|
|
|
+ MHD_FD_STATE_RECV = 1 << 0,
|
|
|
/**
|
|
|
- * Disable some internal thread safety.
|
|
|
- * 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 any internal threads mode.
|
|
|
- * Thread safety is not disabled (safety is enabled) by default.
|
|
|
+ * Indicates that socket should be watched for availability for sending
|
|
|
+ * (when set by #MHD_get_watched_fds())
|
|
|
+ * / socket has ability to send data (when used for
|
|
|
+ * #MHD_process_watched_fds())
|
|
|
*/
|
|
|
- MHD_D_O_DISABLE_THREAD_SAFETY = 103
|
|
|
- ,
|
|
|
+ MHD_FD_STATE_SEND = 1 << 1,
|
|
|
/**
|
|
|
- * You need to set this option if you want to disable use of HTTP "Upgrade".
|
|
|
- * "Upgrade" may require usage of additional internal resources,
|
|
|
- * which we can avoid providing if they will not be used.
|
|
|
- *
|
|
|
- * You should only use this function if you do not use "Upgrade" functionality
|
|
|
- * and need a generally minor boost in performance.
|
|
|
- * The "Upgrade" is not disallowed ("upgrade" is allowed) by default.
|
|
|
+ * Indicates that socket should be watched for disconnect, out-of-band
|
|
|
+ * data available or high priority data available (when set by
|
|
|
+ * #MHD_get_watched_fds())
|
|
|
+ * / socket has been disconnected, has out-of-band data available or
|
|
|
+ * has high priority data available (when used for
|
|
|
+ * #MHD_process_watched_fds()). This status must not include "remote
|
|
|
+ * peer shut down writing" status.
|
|
|
+ * Note: #MHD_get_watched_fds() always set it as exceptions must be
|
|
|
+ * always watched.
|
|
|
*/
|
|
|
- MHD_D_O_BOOL_DISALLOW_UPGRADE = 104
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Disable #MHD_action_suspend() functionality.
|
|
|
- *
|
|
|
- * You should only use this function if you do not use suspend functionality
|
|
|
- * and need a generally minor boost in performance.
|
|
|
- * The suspend is not disallowed (suspend is allowed) by default.
|
|
|
+ MHD_FD_STATE_EXCEPT = 1 << 2,
|
|
|
+
|
|
|
+ /* The rest of the list is a bit-wise combination of three main
|
|
|
+ * states. Application may use three main states directly as
|
|
|
+ * a bit-mask instead of using of following values
|
|
|
*/
|
|
|
- MHD_D_O_BOOL_DISALLOW_SUSPEND_RESUME
|
|
|
- ,
|
|
|
+
|
|
|
/**
|
|
|
- * Use SHOUTcast. This will cause *all* responses to begin
|
|
|
- * with the SHOUTcast "ICY" line instead of "HTTP".
|
|
|
+ * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_SEND states.
|
|
|
*/
|
|
|
- MHD_D_O_BOOL_ENABLE_SHOUTCAST
|
|
|
- ,
|
|
|
+ MHD_FD_STATE_RECV_SEND = MHD_FD_STATE_RECV | MHD_FD_STATE_SEND,
|
|
|
/**
|
|
|
- * Disable converting plus ('+') character to space in GET
|
|
|
- * parameters (URI part after '?').
|
|
|
- * TODO: Add explanation, RFCs, HTML
|
|
|
+ * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
|
|
|
*/
|
|
|
- MHD_D_O_BOOL_DISABLE_GET_PARAM_PLUS_AS_SPACE,
|
|
|
-
|
|
|
+ MHD_FD_STATE_RECV_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT,
|
|
|
/**
|
|
|
- * Bind to the given socket address.
|
|
|
+ * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
|
|
|
*/
|
|
|
- MHD_D_O_SA
|
|
|
- ,
|
|
|
+ MHD_FD_STATE_SEND_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT,
|
|
|
/**
|
|
|
- * 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 platform, but uses SO_EXCLUSIVEADDRUSE on
|
|
|
- * Windows).
|
|
|
- * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
+ * Combination of #MHD_FD_STATE_RECV, #MHD_FD_STATE_SEND and
|
|
|
+ * #MHD_FD_STATE_EXCEPT states.
|
|
|
*/
|
|
|
- MHD_D_O_BOOL_LISTEN_ALLOW_ADDRESS_REUSE
|
|
|
+ MHD_FD_STATE_RECV_SEND_EXCEPT = \
|
|
|
+ MHD_FD_STATE_RECV | MHD_FD_STATE_SEND | MHD_FD_STATE_EXCEPT
|
|
|
};
|
|
|
|
|
|
-// FIXME: transform everything to option
|
|
|
-
|
|
|
/**
|
|
|
- * Possible levels of enforcement for TCP_FASTOPEN.
|
|
|
+ * Checks whether specific @a state is enabled in @a var
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_TCPFastOpenType
|
|
|
-{
|
|
|
- /**
|
|
|
- * Disable use of TCP_FASTOPEN.
|
|
|
- */
|
|
|
- MHD_FOM_DISABLE = -1
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Enable TCP_FASTOPEN where supported.
|
|
|
- * On GNU/Linux it works with a kernel >= 3.6.
|
|
|
- * This is the default.
|
|
|
- */
|
|
|
- MHD_FOM_AUTO = 0
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Require TCP_FASTOPEN.
|
|
|
- * Also causes #MHD_daemon_start() to fail if setting
|
|
|
- * the option fails later.
|
|
|
- */
|
|
|
- MHD_FOM_REQUIRE = 1
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
+#define MHD_FD_STATE_IS_SET(var,state) \
|
|
|
+ (MHD_FD_STATE_NONE != \
|
|
|
+ (((enum MHD_FdState) (var)) & ((enum MHD_FdState) (state))))
|
|
|
|
|
|
/**
|
|
|
- * Address family to be used by MHD.
|
|
|
+ * Checks whether RECV is enabled in @a var
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_AddressFamily
|
|
|
-{
|
|
|
- /**
|
|
|
- * Option not given, do not listen at all
|
|
|
- * (unless listen socket or address specified by
|
|
|
- * other means).
|
|
|
- */
|
|
|
- MHD_AF_NONE = 0
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Pick "best" available method automatically.
|
|
|
- */
|
|
|
- MHD_AF_AUTO = 1
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Use IPv4.
|
|
|
- */
|
|
|
- MHD_AF_INET4 = 2
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Use IPv6.
|
|
|
- */
|
|
|
- MHD_AF_INET6 = 3
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Use dual stack.
|
|
|
- */
|
|
|
- MHD_AF_DUAL = 4
|
|
|
-};
|
|
|
+#define MHD_FD_STATE_IS_SET_RECV(var) \
|
|
|
+ MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_RECV)
|
|
|
+/**
|
|
|
+ * Checks whether SEND is enabled in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_IS_SET_SEND(var) \
|
|
|
+ MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_SEND)
|
|
|
+/**
|
|
|
+ * Checks whether EXCEPT is enabled in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_IS_SET_EXCEPT(var) \
|
|
|
+ MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_EXCEPT)
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Bind to the given socket address.
|
|
|
- * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
- *
|
|
|
- * @param[in,out] daemon which instance to configure the binding address for
|
|
|
- * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
|
|
|
- * or even a UNIX domain socket (AF_UNIX)
|
|
|
- * @param sa_len number of bytes in @a sa
|
|
|
- * @return #MHD_SC_OK on on success,
|
|
|
- * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
- * #MHD_SC_FEATURE_DISABLED,
|
|
|
- * #MHD_SC_FEATURE_NOT_AVAILABLE,
|
|
|
- * #MHD_SC_OPTIONS_CONFLICT
|
|
|
+ * Enable specific @a state in @a var
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
|
|
|
- const struct sockaddr *sa,
|
|
|
- size_t sa_len)
|
|
|
-MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_;
|
|
|
-
|
|
|
-// TODO: Sort values and assign numbers
|
|
|
-enum MHD_DeamonOptionUInt
|
|
|
-{
|
|
|
- /**
|
|
|
- * Use the given backlog for the listen() call.
|
|
|
- * Ineffective in conjunction with #MHD_daemon_listen_socket()
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_UINT_LISTEN_BACKLOG,
|
|
|
- /**
|
|
|
- * Maximum number of (concurrent) network connections served
|
|
|
- * by daemon
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_UINT_GLOBAL_CONNECTION_LIMIT,
|
|
|
- /**
|
|
|
- * Limit on the number of (concurrent) network 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.
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_UINT_IP_CONNECTION_LIMIT,
|
|
|
+#define MHD_FD_STATE_SET(var,state) \
|
|
|
+ (var) = (enum MHD_FdState) ((var) | (state))
|
|
|
+/**
|
|
|
+ * Enable RECV state in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_SET_RECV(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_RECV)
|
|
|
+/**
|
|
|
+ * Enable SEND state in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_SET_SEND(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_SEND)
|
|
|
+/**
|
|
|
+ * Enable EXCEPT state in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_SET_EXCEPT(var) \
|
|
|
+ MHD_FD_STATE_SET ((var),MHD_FD_STATE_EXCEPT)
|
|
|
|
|
|
- /**
|
|
|
- * After how many seconds of inactivity should a
|
|
|
- * connection automatically be timed out?
|
|
|
- * Use zero for no timeout, which is also the (unsafe!) default.
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_UINT_DEFAULT_TIMEOUT,
|
|
|
+/**
|
|
|
+ * Clear/disable specific @a state in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_CLEAR(var,state) \
|
|
|
+ (var) = (enum MHD_FdState) ((var) & (((enum MHD_FdState))(~state)))
|
|
|
+/**
|
|
|
+ * Clear/disable RECV state in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_CLEAR_RECV(var) \
|
|
|
+ MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_RECV)
|
|
|
+/**
|
|
|
+ * Clear/disable SEND state in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_CLEAR_SEND(var) \
|
|
|
+ MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_SEND)
|
|
|
+/**
|
|
|
+ * Clear/disable EXCEPT state in @a var
|
|
|
+ */
|
|
|
+#define MHD_FD_STATE_CLEAR_EXCEPT(var) \
|
|
|
+ MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_EXCEPT)
|
|
|
|
|
|
- /**
|
|
|
- * The number of worker threads.
|
|
|
- * Only useful if the selected threading mode
|
|
|
- * is #MHD_TM_WORKER_THREADS.
|
|
|
- * Zero number is silently ignored.
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_UINT_NUM_WORKERS
|
|
|
|
|
|
-};
|
|
|
+/* Changes:
|
|
|
+ * + status update callback replaced with function
|
|
|
+ * + status update accepts array of updates
|
|
|
+ */
|
|
|
|
|
|
/**
|
|
|
- * Set unsigned integer MHD option.
|
|
|
- *
|
|
|
- * @param[in,out] daemon which instance to set uint @a option for
|
|
|
- * @param option option to modify
|
|
|
- * @param value new value for the option
|
|
|
- * @return #MHD_SC_OK on on success,
|
|
|
- * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
- * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
- * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system
|
|
|
- * #MHD_SC_OPTIONS_CONFLICT
|
|
|
+ * The context data to be used for updates of the socket state
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_option_uint (struct MHD_Daemon *daemon,
|
|
|
- enum MHD_DeamonOptionUInt option,
|
|
|
- unsigned int value)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+struct MHD_EventUpdateContext;
|
|
|
|
|
|
-// FIXME: Alternative or additional implementation.
|
|
|
|
|
|
-struct MHD_DaemonOptioniUIntEntry
|
|
|
-{
|
|
|
- /**
|
|
|
- * The option to update the @a value
|
|
|
- */
|
|
|
- enum MHD_DeamonOptionUInt option;
|
|
|
- /**
|
|
|
- * The value to update for the @a option
|
|
|
- */
|
|
|
- unsigned int value;
|
|
|
- // TODO: union
|
|
|
-};
|
|
|
+/* Define MHD_APP_SOCKET_CNTX_TYPE to the socket context type before
|
|
|
+ * including this header.
|
|
|
+ * This is optional, but improves the types safety.
|
|
|
+ * For example:
|
|
|
+ * #define MHD_APP_SOCKET_CNTX_TYPE struct my_structure
|
|
|
+ */
|
|
|
+#ifndef MHD_APP_SOCKET_CNTX_TYPE
|
|
|
+# define MHD_APP_SOCKET_CNTX_TYPE void
|
|
|
+#endif
|
|
|
|
|
|
-#if 0
|
|
|
/**
|
|
|
- * Set unsigned integer MHD options.
|
|
|
+ * The callback for registration/de-registration of the sockets to watch.
|
|
|
*
|
|
|
- * @param[in,out] daemon which instance to set uint @a option for
|
|
|
- * @param num_entries the number of entries in the @a opt_val array
|
|
|
- * and in @a results (if not NULL)
|
|
|
- * @param[in] opt_val the array with options and values to modify
|
|
|
- * @param[out] results the results for the applying the options,
|
|
|
- * can be NULL,
|
|
|
- * if not NULL must have @a num_entries entries
|
|
|
- * @return #MHD_YES if all options have applied successfully
|
|
|
- * #MHD_NO if at least single option failed (for more
|
|
|
- * details check @a results)
|
|
|
+ * This callback must not call #MHD_daemon_destroy(), #MHD_daemon_quiesce(),
|
|
|
+ * #MHD_daemon_add_connection().
|
|
|
+ *
|
|
|
+ * @param cls the closure
|
|
|
+ * @param fd the socket to watch
|
|
|
+ * @param watch_for the states of the @a fd to watch, if set to
|
|
|
+ * #MHD_FD_STATE_NONE the socket must be de-registred
|
|
|
+ * @param app_cntx_old the old application defined context for the socket,
|
|
|
+ * NULL if @a fd socket was not registered before
|
|
|
+ * @param ecb_cntx the context handle to be used
|
|
|
+ * with #MHD_daemon_event_update()
|
|
|
+ * @return NULL if error (to connection will be closed),
|
|
|
+ * or the new socket context
|
|
|
+ * @ingroup event
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode // First failed // TODO: Document that rest may be used
|
|
|
-MHD_daemon_set_option_uint (
|
|
|
+typedef MHD_APP_SOCKET_CNTX_TYPE *
|
|
|
+(MHD_FN_PAR_NONNULL_(5)
|
|
|
+ *MHD_SocketRegistrationUpdateCallback)(
|
|
|
+ void *cls,
|
|
|
+ MHD_socket fd,
|
|
|
+ enum MHD_FdState watch_for,
|
|
|
+ MHD_APP_SOCKET_CNTX_TYPE *app_cntx_old,
|
|
|
+ struct MHD_EventUpdateContext *ecb_cntx);
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Update the sockets state.
|
|
|
+ * Must be called for every socket that got state updated.
|
|
|
+ * For #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL mode should be called for each
|
|
|
+ * socket.
|
|
|
+ * Available only for daemons stated in #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
|
|
|
+ * #MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
|
|
|
+ * @param daemon the daemon handle
|
|
|
+ * @param ecb_cntx the context handle provided
|
|
|
+ * for #MHD_SocketRegistrationUpdateCallback
|
|
|
+ * @param fd_current_state the current state of the socket
|
|
|
+ */
|
|
|
+MHD_EXTERN_ void
|
|
|
+MHD_daemon_event_update (
|
|
|
struct MHD_Daemon *daemon,
|
|
|
- size_t num_entries,
|
|
|
- struct MHD_DaemonOptioniUIntEntry opt_val[MHD_C99_ (static num_entries)])
|
|
|
-MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3);
|
|
|
-#endif
|
|
|
-// TODO: combine all types of options into single list with union
|
|
|
+ struct MHD_EventUpdateContext *ecb_cntx,
|
|
|
+ enum MHD_FdState fd_current_state)
|
|
|
+MHD_FN_PAR_NONNULL_(1) MHD_FN_PAR_NONNULL_(2);
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
- * Accept connections from the given socket. Socket
|
|
|
- * must be a TCP or UNIX domain (stream) socket.
|
|
|
+ * Perform sockets registration, process registered network events.
|
|
|
*
|
|
|
- * Unless MHD_INVALID_SOCKET is given, this disables
|
|
|
- * other listen options.
|
|
|
+ * This function first processes all registered (by MHD_daemon_event_update())
|
|
|
+ * network events (if any) and then calls #MHD_SocketRegistrationUpdateCallback
|
|
|
+ * callback for every socket that needs to be added/updated/removed.
|
|
|
*
|
|
|
- * @param daemon daemon to set listen socket for
|
|
|
- * @param listen_socket listen socket to use,
|
|
|
- * MHD_INVALID_SOCKET value will cause this call to be
|
|
|
- * ignored (other binding options may still be effective)
|
|
|
- * @return #MHD_SC_OK on on success,
|
|
|
- * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
- * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
- * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system
|
|
|
- * #MHD_SC_OPTIONS_CONFLICT
|
|
|
+ * Available only for daemons stated in #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
|
|
|
+ * #MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
|
|
|
+ *
|
|
|
+ * @param daemon the daemon handle
|
|
|
+ * @param[out] next_max_wait the optional pointer to receive the next maximum
|
|
|
+ * wait time in microseconds to be used for sockets
|
|
|
+ * polling function, can be NULL
|
|
|
+ * @return MHD_SC_OK on success,
|
|
|
+ * error code otherwise
|
|
|
*/
|
|
|
MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
|
|
|
- MHD_socket listen_socket)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+MHD_deamon_process_reg_events(struct MHD_Daemon *daemon,
|
|
|
+ uint_fast64_t *next_max_wait)
|
|
|
+MHD_FN_PAR_NONNULL_(1);
|
|
|
+
|
|
|
+/* ********************* daemon options ************** */
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
- * Event loop internal syscalls supported by MHD.
|
|
|
+ * Which threading and polling mode should be used by MHD?
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_EventLoopSyscall
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_WorkMode
|
|
|
{
|
|
|
/**
|
|
|
- * Automatic selection of best-available method. This is also the
|
|
|
- * default.
|
|
|
+ * Work mode with no internal threads.
|
|
|
+ * The application periodically calls #MHD_daemon_process_blocking(), where
|
|
|
+ * MHD internally checks all sockets automatically.
|
|
|
+ * This is the default mode.
|
|
|
*/
|
|
|
- MHD_ELS_AUTO = 0
|
|
|
+ MHD_WM_EXTERNAL_PERIODIC = 0
|
|
|
,
|
|
|
/**
|
|
|
- * Use select().
|
|
|
+ * Work mode with an external event loop with level triggers.
|
|
|
+ * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
|
|
|
+ * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
|
|
|
*/
|
|
|
- MHD_ELS_SELECT = 1
|
|
|
+ MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL = 8
|
|
|
,
|
|
|
/**
|
|
|
- * Use poll().
|
|
|
+ * Work mode with an external event loop with edge triggers.
|
|
|
+ * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
|
|
|
+ * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
|
|
|
*/
|
|
|
- MHD_ELS_POLL = 2
|
|
|
+ MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE = 9
|
|
|
,
|
|
|
/**
|
|
|
- * Use epoll.
|
|
|
+ * Work mode with no internal threads and aggregate watch FD.
|
|
|
+ * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
|
|
|
+ * that gets triggered by any MHD event.
|
|
|
+ * This FD can be watched as an aggregate indicator for all MHD events.
|
|
|
+ * This mode is available only on selected platforms (currently
|
|
|
+ * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
|
|
|
+ * When the FD is triggered, #MHD_daemon_process_nonblocking() should
|
|
|
+ * be called.
|
|
|
*/
|
|
|
- MHD_ELS_EPOLL = 3
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Force use of a particular event loop system call.
|
|
|
- *
|
|
|
- * @param daemon daemon to set event loop style for
|
|
|
- * @param els event loop syscall to use
|
|
|
- * @return #MHD_SC_OK on on success,
|
|
|
- * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
- * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
- * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system
|
|
|
- * #MHD_SC_OPTIONS_CONFLICT
|
|
|
- */
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_event_loop (struct MHD_Daemon *daemon,
|
|
|
- enum MHD_EventLoopSyscall els)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Protocol strictness enforced by MHD on clients.
|
|
|
- * All levels have different parsing settings for the headers.
|
|
|
- */
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_ProtocolStrictLevel
|
|
|
-{
|
|
|
-
|
|
|
- /* * Basic levels * */
|
|
|
- /**
|
|
|
- * Sane level of protocol enforcement for production use.
|
|
|
- * A balance between extra security and broader compatibility,
|
|
|
- * as allowed by RFCs for HTTP servers.
|
|
|
- */
|
|
|
- MHD_PSL_DEFAULT = 0
|
|
|
+ MHD_WM_EXTERNAL_SINGLE_FD_WATCH = 16
|
|
|
,
|
|
|
/**
|
|
|
- * Be strict about the protocol (as opposed to as tolerant as
|
|
|
- * possible), within the limits set by RFCs for HTTP servers.
|
|
|
- * This level (and more strict) forbids use of bare LF as
|
|
|
- * CRLF. It also rejects requests with both "Transfer-Encoding:"
|
|
|
- * and "Content-Length:".
|
|
|
- * It is suitable for public servers.
|
|
|
+ * Work mode with one or more worker threads.
|
|
|
+ * If #MHD_DAEMON_OPTION_UINT_NUM_WORKERS is not specified
|
|
|
+ * then daemon starts with single worker thread that process
|
|
|
+ * all connections.
|
|
|
+ * If #MHD_DAEMON_OPTION_UINT_NUM_WORKERS used with value more
|
|
|
+ * than one, then that number of worker threads and distributed
|
|
|
+ * processing of requests among the workers.
|
|
|
*/
|
|
|
- MHD_PSL_STRICT = 1
|
|
|
+ MHD_WM_WORKER_THREADS = 24
|
|
|
,
|
|
|
/**
|
|
|
- * Be particularly permissive about the protocol, within
|
|
|
- * the limits set by RFCs for HTTP servers.
|
|
|
+ * Work mode with one internal thread for listening and additional threads
|
|
|
+ * per every connection. Use this if handling requests is CPU-intensive or
|
|
|
+ * blocking, your application is thread-safe and you have plenty of
|
|
|
+ * memory (per connection).
|
|
|
*/
|
|
|
- MHD_PSL_PERMISSIVE = -1,
|
|
|
+ MHD_WM_THREAD_PER_CONNECTION = 32
|
|
|
+};
|
|
|
|
|
|
- /* * Special levels * */
|
|
|
+/**
|
|
|
+ * Work mode parameters for #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL and
|
|
|
+ * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes
|
|
|
+ */
|
|
|
+struct MHD_WorkModeExternalEventLoopCBParam
|
|
|
+{
|
|
|
/**
|
|
|
- * 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.
|
|
|
- * For chunked encoding parsing this level (and more strict)
|
|
|
- * forbids whitespace in chunk extension.
|
|
|
- * For cookies parsing this (and more strict) level rejects
|
|
|
- * cookie in full even if a single value is encoded incorrectly
|
|
|
- * in it.
|
|
|
- * This level is recommended for testing clients against
|
|
|
- * MHD. Also can be used for security-centric application,
|
|
|
- * however it is slight violation of RFCs' requirements.
|
|
|
+ * Socket registration callback
|
|
|
*/
|
|
|
- MHD_PSL_VERY_STRICT = 2
|
|
|
- ,
|
|
|
+ MHD_SocketRegistrationUpdateCallback reg_cb;
|
|
|
/**
|
|
|
- * The most strict interpretation of the HTTP protocol,
|
|
|
- * much stricter that defined for HTTP servers by RFC.
|
|
|
- * However it should be absolutely compatible with clients
|
|
|
- * following RFCs' "SHOULD" and "MUST" types of requirements
|
|
|
- * for HTTP clients.
|
|
|
- * This level can be used for testing clients against MHD.
|
|
|
- * It is not recommended for any public services as it may
|
|
|
- * reject legitimate clients (clients not following "SHOULD"
|
|
|
- * type of RFC requirements).
|
|
|
+ * Closure for the @a reg_cb
|
|
|
*/
|
|
|
- MHD_PSL_EXTRA_STRICT = 3
|
|
|
- ,
|
|
|
+ void *reg_cb_cls;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * MHD work mode parameters
|
|
|
+ */
|
|
|
+union MHD_WorkModeParam
|
|
|
+{
|
|
|
/**
|
|
|
- * More relaxed protocol interpretation, violating RFCs'
|
|
|
- * "SHOULD" type of requirements for HTTP servers.
|
|
|
- * For cookies parsing this (and more permissive) level
|
|
|
- * allows whitespaces in cookie values.
|
|
|
- * This level can be used in isolated environments.
|
|
|
+ * Work mode parameters for #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL and
|
|
|
+ * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes
|
|
|
*/
|
|
|
- MHD_PSL_VERY_PERMISSIVE = -2,
|
|
|
-
|
|
|
+ MHD_SocketRegistrationUpdateCallback v_external_event_loop_cb;
|
|
|
/**
|
|
|
- * The most flexible protocol interpretation, beyond
|
|
|
- * RFCs' "MUST" type of requirements for HTTP server.
|
|
|
- * The level allow HTTP/1.1 requests without "Host:" header.
|
|
|
- * For cookies parsing this level adds allowance of
|
|
|
- * whitespaces before and after '=' character.
|
|
|
- * This level is not recommended unless it is absolutely
|
|
|
- * necessary to communicate with some client(s) with
|
|
|
- * badly broken HTTP implementation.
|
|
|
+ * Number of worker threads for #MHD_WM_WORKER_THREADS.
|
|
|
+ * If set to one, then daemon starts with single worker thread that process
|
|
|
+ * all connections.
|
|
|
+ * If set to value larger than one, then that number of worker threads
|
|
|
+ * and distributed handling of requests among the workers.
|
|
|
+ * Zero is treated as one.
|
|
|
*/
|
|
|
- MHD_PSL_EXTRA_PERMISSIVE = -3,
|
|
|
+ unsigned int num_worker_threads;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * The way Strict Level is enforced.
|
|
|
- * MHD can be compiled with limited set of strictness levels.
|
|
|
- * These values instructs MHD how to apply the request level.
|
|
|
+ * Parameter for #MHD_DAEMON_OPTION_WORK_MODE().
|
|
|
+ * Not recommended to be used directly, better use macro/functions to create it:
|
|
|
+ * #MHD_WM_OPTION_EXTERNAL_PERIODIC(),
|
|
|
+ * #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(),
|
|
|
+ * #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(),
|
|
|
+ * #MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH(),
|
|
|
+ * #MHD_WM_OPTION_WORKER_THREADS(),
|
|
|
+ * #MHD_WM_OPTION_THREAD_PER_CONNECTION()
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_UseStictLevel
|
|
|
+struct MHD_WorkModeWithParam
|
|
|
{
|
|
|
/**
|
|
|
- * Use requested level if available or the nearest stricter
|
|
|
- * level.
|
|
|
- * Fail if only more permissive levels available.
|
|
|
- */
|
|
|
- MHD_USL_THIS_OR_STRICTER = 0
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Use requested level only.
|
|
|
- * Fail if this level is not available.
|
|
|
+ * The work mode for MHD
|
|
|
*/
|
|
|
- MHD_USL_PRECISE = 1
|
|
|
- ,
|
|
|
+ enum MHD_WorkMode mode;
|
|
|
/**
|
|
|
- * Use requested level if available or the nearest level (stricter
|
|
|
- * or more permissive).
|
|
|
+ * The parameters used for specified work mode
|
|
|
*/
|
|
|
- MHD_USL_NEAREST = 2
|
|
|
+ union MHD_WorkModeParam params;
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+#if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)
|
|
|
/**
|
|
|
- * Set how strictly MHD will enforce the HTTP protocol.
|
|
|
- *
|
|
|
- * @param[in,out] daemon daemon to configure strictness for
|
|
|
- * @param sl the level of strictness
|
|
|
- * @param how the way how to use the requested level
|
|
|
- * @return #MHD_SC_OK on on success,
|
|
|
- * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
- * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
- */
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
|
|
|
- enum MHD_ProtocolStrictLevel sl,
|
|
|
- enum MHD_UseStictLevel how)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * no internal threads.
|
|
|
+ * The application periodically calls #MHD_daemon_process_blocking(), where
|
|
|
+ * MHD internally checks all sockets automatically.
|
|
|
+ * This is the default mode.
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
+ */
|
|
|
+# define MHD_WM_OPTION_EXTERNAL_PERIODIC() \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_WorkModeWithParam) \
|
|
|
+ { \
|
|
|
+ .mode = (MHD_WM_EXTERNAL_PERIODIC) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_option_string (struct MHD_Daemon *daemon,
|
|
|
- enum foo,
|
|
|
- const char *value)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+/**
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * an external event loop with level triggers.
|
|
|
+ * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
|
|
|
+ * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
|
|
|
+ * @param cb_val the callback for sockets registration
|
|
|
+ * @param cb_cls_val the closure for the @a cv_val callback
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
+ */
|
|
|
+# define MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(cb_val,cb_cls_val) \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_WorkModeWithParam) \
|
|
|
+ { \
|
|
|
+ .mode = (MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL), \
|
|
|
+ .params.v_external_event_loop_cb.reg_cb = (cb_val), \
|
|
|
+ .params.v_external_event_loop_cb.reg_cb_cls = (cb_cls_val) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
|
|
|
/**
|
|
|
- * Provide TLS key and certificate data in-memory.
|
|
|
- *
|
|
|
- * @param daemon which instance should be configured
|
|
|
- * @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.
|
|
|
- * @param pass passphrase phrase to decrypt 'key.pem', NULL
|
|
|
- * if @param mem_key is in cleartext already
|
|
|
- * @return #MHD_SC_OK upon success;
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * an external event loop with edge triggers.
|
|
|
+ * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
|
|
|
+ * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
|
|
|
+ * @param cb_val the callback for sockets registration
|
|
|
+ * @param cb_cls_val the closure for the @a cv_val callback
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
+ */
|
|
|
+# define MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(cb_val,cb_cls_val) \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_WorkModeWithParam) \
|
|
|
+ { \
|
|
|
+ .mode = (MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE), \
|
|
|
+ .params.v_external_event_loop_cb.reg_cb = (cb_val), \
|
|
|
+ .params.v_external_event_loop_cb.reg_cb_cls = (cb_cls_val) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
+
|
|
|
+/**
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * no internal threads and aggregate watch FD.
|
|
|
+ * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
|
|
|
+ * that gets triggered by any MHD event.
|
|
|
+ * This FD can be watched as an aggregate indicator for all MHD events.
|
|
|
+ * This mode is available only on selected platforms (currently
|
|
|
+ * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
|
|
|
+ * When the FD is triggered, #MHD_daemon_process_nonblocking() should
|
|
|
+ * be called.
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
|
|
|
- const char *mem_key,
|
|
|
- const char *mem_cert,
|
|
|
- const char *pass)
|
|
|
-MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2)
|
|
|
-MHD_FN_PAR_NONNULL_ (3);
|
|
|
+# define MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH() \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_WorkModeWithParam) \
|
|
|
+ { \
|
|
|
+ .mode = (MHD_WM_EXTERNAL_SINGLE_FD_WATCH) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
|
|
|
+/**
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * one or more worker threads.
|
|
|
+ * If number of threads is one, then daemon starts with single worker thread
|
|
|
+ * that handles all connections.
|
|
|
+ * If number of threads is larger than one, then that number of worker threads,
|
|
|
+ * and handling of connection is distributed among the workers.
|
|
|
+ * @param num_workers the number of worker threads, zero is treated as one
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
+ */
|
|
|
+# define MHD_WM_OPTION_WORKER_THREADS(num_workers) \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_WorkModeWithParam) \
|
|
|
+ { \
|
|
|
+ .mode = (MHD_WM_WORKER_THREADS), \
|
|
|
+ .params.num_worker_threads = (num_workers) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
|
|
|
/**
|
|
|
- * Configure DH parameters (dh.pem) to use for the TLS key
|
|
|
- * exchange.
|
|
|
- *
|
|
|
- * @param daemon daemon to configure tls for
|
|
|
- * @param dh parameters to use
|
|
|
- * @return #MHD_SC_OK upon success; TODO: define failure modes
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * one internal thread for listening and additional threads per every
|
|
|
+ * connection. Use this if handling requests is CPU-intensive or blocking,
|
|
|
+ * your application is thread-safe and you have plenty of memory (per
|
|
|
+ * connection).
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
|
|
|
- const char *dh)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+# define MHD_WM_OPTION_THREAD_PER_CONNECTION() \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_WorkModeWithParam) \
|
|
|
+ { \
|
|
|
+ .mode = (MHD_WM_THREAD_PER_CONNECTION) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
+
|
|
|
+#else /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
|
|
|
+MHD_NOWARN_UNUSED_FUNC_
|
|
|
|
|
|
/**
|
|
|
- * Memory pointer for the certificate (ca.pem) to be used by the
|
|
|
- * HTTPS daemon for client authentication.
|
|
|
- *
|
|
|
- * @param daemon daemon to configure tls for
|
|
|
- * @param mem_trust memory pointer to the certificate
|
|
|
- * @return #MHD_SC_OK upon success; TODO: define failure modes
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * no internal threads.
|
|
|
+ * The application periodically calls #MHD_daemon_process_blocking(), where
|
|
|
+ * MHD internally checks all sockets automatically.
|
|
|
+ * This is the default mode.
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
|
|
|
- const char *mem_trust)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+static MHD_INLINE struct MHD_WorkModeWithParam
|
|
|
+MHD_WM_OPTION_EXTERNAL_PERIODIC(void)
|
|
|
+{
|
|
|
+ struct MHD_WorkModeWithParam wm_val;
|
|
|
|
|
|
+ wm_val.mode = MHD_WM_EXTERNAL_PERIODIC;
|
|
|
|
|
|
-/* ********************** (d) TLS support ********************** */
|
|
|
+ return wm_val;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * The TLS backend choice
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * an external event loop with level triggers.
|
|
|
+ * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
|
|
|
+ * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
|
|
|
+ * @param cb_val the callback for sockets registration
|
|
|
+ * @param cb_cls_val the closure for the @a cv_val callback
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_TlsBackend
|
|
|
+static MHD_INLINE struct MHD_WorkModeWithParam
|
|
|
+MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(
|
|
|
+ MHD_SocketRegistrationUpdateCallback cb_val,
|
|
|
+ void *cb_cls_val)
|
|
|
{
|
|
|
- /**
|
|
|
- * Disable TLS, use plain TCP connections
|
|
|
- */
|
|
|
- MHD_TLS_BACKEND_NONE = 0
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Use best available TLS backend.
|
|
|
- * Currently this is equivalent to GnuTLS (if TLS is enabled
|
|
|
- * for MHD build).
|
|
|
- */
|
|
|
- MHD_TLS_BACKEND_ANY = 1
|
|
|
- ,
|
|
|
- /**
|
|
|
- * Use GnuTLS as TLS backend.
|
|
|
- */
|
|
|
- MHD_TLS_BACKEND_GNUTLS = 2
|
|
|
-};
|
|
|
+ struct MHD_WorkModeWithParam wm_val;
|
|
|
+
|
|
|
+ wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL;
|
|
|
+ wm_val.params.v_external_event_loop_cb.reg_cb = cb_val;
|
|
|
+ wm_val.params.v_external_event_loop_cb.reg_cb_cls = cb_cls_val;
|
|
|
+
|
|
|
+ return wm_val;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * 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_check() (and similar functions) to check nonce by
|
|
|
- * re-generating it again with the same parameters, which is CPU-intensive
|
|
|
- * operation.
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * an external event loop with edge triggers.
|
|
|
+ * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
|
|
|
+ * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
|
|
|
+ * @param cb_val the callback for sockets registration
|
|
|
+ * @param cb_cls_val the closure for the @a cv_val callback
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
*/
|
|
|
-enum MHD_FIXED_FLAGS_ENUM_APP_SET_ MHD_DaemonOptionValueDAuthBindNonce
|
|
|
+static MHD_INLINE struct MHD_WorkModeWithParam
|
|
|
+MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(
|
|
|
+ MHD_SocketRegistrationUpdateCallback cb_val,
|
|
|
+ void *cb_cls_val)
|
|
|
{
|
|
|
- /**
|
|
|
- * 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_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_NONE = 0,
|
|
|
+ struct MHD_WorkModeWithParam wm_val;
|
|
|
|
|
|
- /**
|
|
|
- * Generated nonces are valid only for the same realm.
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_REALM = 1 << 0,
|
|
|
+ wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE;
|
|
|
+ wm_val.params.v_external_event_loop_cb.reg_cb = cb_val;
|
|
|
+ wm_val.params.v_external_event_loop_cb.reg_cb_cls = cb_cls_val;
|
|
|
|
|
|
- /**
|
|
|
- * 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_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_URI = 1 << 1,
|
|
|
+ return wm_val;
|
|
|
+}
|
|
|
|
|
|
- /**
|
|
|
- * 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_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_URI_PARAMS = 1 << 2,
|
|
|
+/**
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * no internal threads and aggregate watch FD.
|
|
|
+ * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
|
|
|
+ * that gets triggered by any MHD event.
|
|
|
+ * This FD can be watched as an aggregate indicator for all MHD events.
|
|
|
+ * This mode is available only on selected platforms (currently
|
|
|
+ * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
|
|
|
+ * When the FD is triggered, #MHD_daemon_process_nonblocking() should
|
|
|
+ * be called.
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
+ */
|
|
|
+static MHD_INLINE struct MHD_WorkModeWithParam
|
|
|
+MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH(void)
|
|
|
+{
|
|
|
+ struct MHD_WorkModeWithParam wm_val;
|
|
|
|
|
|
- /**
|
|
|
- * 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_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_CLIENT_IP = 1 << 3
|
|
|
-};
|
|
|
+ wm_val.mode = MHD_WM_EXTERNAL_SINGLE_FD_WATCH;
|
|
|
+
|
|
|
+ return wm_val;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * Enable and configure TLS.
|
|
|
- *
|
|
|
- * @param daemon which instance should be configured
|
|
|
- * @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).
|
|
|
- * @return status code, #MHD_SC_OK upon success
|
|
|
- * #MHD_TLS_BACKEND_UNSUPPORTED if the @a backend is unknown
|
|
|
- * #MHD_TLS_DISABLED if this build of MHD does not support TLS
|
|
|
- * #MHD_TLS_CIPHERS_INVALID if the given @a ciphers are not supported
|
|
|
- * by this backend
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * one or more worker threads.
|
|
|
+ * If number of threads is one, then daemon starts with single worker thread
|
|
|
+ * that handles all connections.
|
|
|
+ * If number of threads is larger than one, then that number of worker threads,
|
|
|
+ * and handling of connection is distributed among the workers.
|
|
|
+ * @param num_workers the number of worker threads, zero is treated as one
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
|
|
|
- enum MHD_TlsBackend backend)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+static MHD_INLINE struct MHD_WorkModeWithParam
|
|
|
+MHD_WM_OPTION_WORKER_THREADS(unsigned int num_workers)
|
|
|
+{
|
|
|
+ struct MHD_WorkModeWithParam wm_val;
|
|
|
|
|
|
+ wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE;
|
|
|
+ wm_val.params.num_worker_threads = num_workers;
|
|
|
+
|
|
|
+ return wm_val;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * Context required to provide a pre-shared key to the
|
|
|
- * server.
|
|
|
- *
|
|
|
- * @param ...
|
|
|
- * @param psk_size the number of bytes in @a psk
|
|
|
- * @param psk the pre-shared-key; should be allocated with malloc(),
|
|
|
- * will be freed by MHD
|
|
|
+ * Create parameter for #MHD_DAEMON_OPTION_WORK_MODE() for work mode with
|
|
|
+ * one internal thread for listening and additional threads per every
|
|
|
+ * connection. Use this if handling requests is CPU-intensive or blocking,
|
|
|
+ * your application is thread-safe and you have plenty of memory (per
|
|
|
+ * connection).
|
|
|
+ * @return the object of struct MHD_WorkModeWithParam with requested values
|
|
|
*/
|
|
|
-struct MHD_ServerCredentialsContext;
|
|
|
+static MHD_INLINE struct MHD_WorkModeWithParam
|
|
|
+MHD_WM_OPTION_THREAD_PER_CONNECTION(void)
|
|
|
+{
|
|
|
+ struct MHD_WorkModeWithParam wm_val;
|
|
|
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_connection_set_psk (struct MHD_ServerCredentialsContext *mscc,
|
|
|
- size_t psk_size,
|
|
|
- const /*void? */ char psk[MHD_C99_ (psk_size)]);
|
|
|
+ wm_val.mode = MHD_WM_THREAD_PER_CONNECTION;
|
|
|
|
|
|
-#define MHD_connection_set_psk_unavailable(mscc) \
|
|
|
- MHD_connection_set_psk (mscc, 0, NULL)
|
|
|
+ return wm_val;
|
|
|
+}
|
|
|
+
|
|
|
+MHD_RESTORE_WARN_UNUSED_FUNC_
|
|
|
+#endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Function called to lookup the pre-shared key (PSK) for a given
|
|
|
- * HTTP connection based on the @a username. MHD will suspend handling of
|
|
|
- * the @a connection until the application calls #MHD_connection_set_psk().
|
|
|
- * If looking up the PSK fails, the application must still call
|
|
|
- * #MHD_connection_set_psk_unavailable().
|
|
|
+ * Specify threading mode to use.
|
|
|
+ *
|
|
|
+ * @param[in,out] daemon daemon to configure
|
|
|
+ * @param tm mode to use
|
|
|
+ */
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_threading_mode (struct MHD_Daemon *daemon,
|
|
|
+ enum MHD_ThreadingMode tm)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Type of a callback function used for logging by MHD.
|
|
|
*
|
|
|
* @param cls closure
|
|
|
- * @param connection the HTTPS connection
|
|
|
- * @param username the user name claimed by the other side
|
|
|
- * @param mscc context to pass to #MHD_connection_set_psk().
|
|
|
- * @return 0 on success, -1 on errors
|
|
|
+ * @param sc status code of the event
|
|
|
+ * @param fm format string (`printf()`-style)
|
|
|
+ * @param ap arguments to @a fm
|
|
|
+ * @ingroup logging
|
|
|
*/
|
|
|
typedef void
|
|
|
-(*MHD_PskServerCredentialsCallback)(void *cls,
|
|
|
- const struct MHD_Connection *connection,
|
|
|
- const struct MHD_String *username,
|
|
|
- struct MHD_ServerCredentialsContext *mscc);
|
|
|
-
|
|
|
+(MHD_FN_PAR_NONNULL_(3)
|
|
|
+ MHD_FN_PAR_CSTR_(3)
|
|
|
+ *MHD_LoggingCallback)(void *cls,
|
|
|
+ enum MHD_StatusCode sc,
|
|
|
+ const char *fm,
|
|
|
+ va_list ap);
|
|
|
|
|
|
+// FIXME: convert
|
|
|
/**
|
|
|
- * Configure PSK to use for the TLS key exchange.
|
|
|
+ * Convenience macro used to disable logging.
|
|
|
*
|
|
|
- * @param daemon daemon to configure tls for
|
|
|
- * @param psk_cb function to call to obtain pre-shared key
|
|
|
- * @param psk_cb_cls closure for @a psk_cb
|
|
|
- * @return #MHD_SC_OK upon success; TODO: define failure modes
|
|
|
+ * @param daemon which instance to disable logging for
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_tls_psk_callback (struct MHD_Daemon *daemon,
|
|
|
- MHD_PskServerCredentialsCallback psk_cb,
|
|
|
- void *psk_cb_cls)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+#define MHD_daemon_disable_logging(daemon) \
|
|
|
+ MHD_daemon_set_logger ((daemon), \
|
|
|
+ MHD_STATIC_CAST_(MHD_LoggingCallback,NULL), \
|
|
|
+ NULL)
|
|
|
|
|
|
+/**
|
|
|
+ * Parameter for listen socket binding type
|
|
|
+ */
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOptionBindType
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * The listen socket bind to the networks address without sharing the address.
|
|
|
+ * Default.
|
|
|
+ */
|
|
|
+ MHD_DAEMON_OPTION_BIND_TYPE_NOT_SHARED = 0
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * The listen socket bind to the networks address with sharing the address.
|
|
|
+ * Several sockets can bind to the same address.
|
|
|
+ */
|
|
|
+ MHD_DAEMON_OPTION_BIND_TYPE_SHARED = 1
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * The list socket bind to the networks address in explicit exclusive mode.
|
|
|
+ * Ignored on platforms without support for the explicit exclusive socket use.
|
|
|
+ */
|
|
|
+ MHD_DAEMON_OPTION_BIND_TYPE_EXCLUSIVE = 2
|
|
|
+};
|
|
|
|
|
|
|
|
|
-// Callback invoked between full initialization of MHD
|
|
|
-// during MHD_daemon_start() and actual event loop
|
|
|
-// starting to accept incoming connections. So at this
|
|
|
-// point, the listen socket (and if applicable TLS context)
|
|
|
-// will be available for introspection.
|
|
|
-typedef void
|
|
|
-(*MHD_DaemonReadyCallback)(void *cls);
|
|
|
-
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOption
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * Not a real option.
|
|
|
+ * Should not be used directly.
|
|
|
+ * This value indicates the end of the list of the options.
|
|
|
+ */
|
|
|
+ MHD_D_O_END = 0
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Suppresses use of "Date:" header.
|
|
|
+ * According to RFC should be used only if the system has no RTC.
|
|
|
+ * The "Date:" is not suppressed (the header is enabled) by default.
|
|
|
+ */
|
|
|
+ MHD_D_O_BOOL_SUPPRESS_DATE_HEADER = 100
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Enable `turbo`. Disables certain calls to `shutdown()`,
|
|
|
+ * enables aggressive non-blocking optimistic reads and
|
|
|
+ * other potentially unsafe optimisations.
|
|
|
+ * Most effects only happen with internal threads with epoll.
|
|
|
+ * The 'turbo' mode is not enabled (mode is disabled) by default.
|
|
|
+ */
|
|
|
+ MHD_D_O_BOOL_TURBO = 102
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Disable some internal thread safety.
|
|
|
+ * 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 any internal threads mode.
|
|
|
+ * Thread safety is not disabled (safety is enabled) by default.
|
|
|
+ */
|
|
|
+ MHD_D_O_DISABLE_THREAD_SAFETY = 103
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * You need to set this option if you want to disable use of HTTP "Upgrade".
|
|
|
+ * "Upgrade" may require usage of additional internal resources,
|
|
|
+ * which we can avoid providing if they will not be used.
|
|
|
+ *
|
|
|
+ * You should only use this function if you do not use "Upgrade" functionality
|
|
|
+ * and need a generally minor boost in performance.
|
|
|
+ * The "Upgrade" is not disallowed ("upgrade" is allowed) by default.
|
|
|
+ */
|
|
|
+ MHD_D_O_BOOL_DISALLOW_UPGRADE = 104
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Disable #MHD_action_suspend() functionality.
|
|
|
+ *
|
|
|
+ * You should only use this function if you do not use suspend functionality
|
|
|
+ * and need a generally minor boost in performance.
|
|
|
+ * The suspend is not disallowed (suspend is allowed) by default.
|
|
|
+ */
|
|
|
+ MHD_D_O_BOOL_DISALLOW_SUSPEND_RESUME
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Use SHOUTcast. This will cause *all* responses to begin
|
|
|
+ * with the SHOUTcast "ICY" line instead of "HTTP".
|
|
|
+ */
|
|
|
+ MHD_D_O_BOOL_ENABLE_SHOUTCAST
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Disable converting plus ('+') character to space in GET
|
|
|
+ * parameters (URI part after '?').
|
|
|
+ * TODO: Add explanation, RFCs, HTML
|
|
|
+ */
|
|
|
+ MHD_D_O_BOOL_DISABLE_GET_PARAM_PLUS_AS_SPACE,
|
|
|
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_daemon_ready_callback (struct MHD_Daemon *daemon,
|
|
|
- MHD_DaemonReadyCallback cb,
|
|
|
- void *cb)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+ /**
|
|
|
+ * Bind to the given socket address.
|
|
|
+ */
|
|
|
+ MHD_D_O_SA
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * 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 platform, but uses SO_EXCLUSIVEADDRUSE on
|
|
|
+ * Windows).
|
|
|
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
+ */
|
|
|
+ MHD_D_O_BOOL_LISTEN_ALLOW_ADDRESS_REUSE
|
|
|
+};
|
|
|
|
|
|
+// FIXME: transform everything to option
|
|
|
|
|
|
/**
|
|
|
- * Allow or deny a client to connect.
|
|
|
- *
|
|
|
- * @param cls closure
|
|
|
- * @param addrlen length of @a addr
|
|
|
- * @param addr address information from the client
|
|
|
- * @see #MHD_daemon_accept_policy()
|
|
|
- * @return #MHD_YES if connection is allowed, #MHD_NO if not
|
|
|
+ * Possible levels of enforcement for TCP_FASTOPEN.
|
|
|
*/
|
|
|
-typedef enum MHD_Bool
|
|
|
-(*MHD_AcceptPolicyCallback)(void *cls,
|
|
|
- size_t addr_len,
|
|
|
- const struct sockaddr *addr);
|
|
|
-
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_TCPFastOpenType
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * Disable use of TCP_FASTOPEN.
|
|
|
+ */
|
|
|
+ MHD_FOM_DISABLE = -1
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Enable TCP_FASTOPEN where supported.
|
|
|
+ * On GNU/Linux it works with a kernel >= 3.6.
|
|
|
+ * This is the default.
|
|
|
+ */
|
|
|
+ MHD_FOM_AUTO = 0
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Require TCP_FASTOPEN.
|
|
|
+ * Also causes #MHD_daemon_start() to fail if setting
|
|
|
+ * the option fails later.
|
|
|
+ */
|
|
|
+ MHD_FOM_REQUIRE = 1
|
|
|
+};
|
|
|
|
|
|
-/**
|
|
|
- * Set a policy callback that accepts/rejects connections
|
|
|
- * based on the client's IP address. This function will be called
|
|
|
- * before a connection object is created.
|
|
|
- *
|
|
|
- * @param daemon daemon to set policy for
|
|
|
- * @param apc function to call to check the policy
|
|
|
- * @param apc_cls closure for @a apc
|
|
|
- */
|
|
|
-MHD_EXTERN_ void
|
|
|
-MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
|
|
|
- MHD_AcceptPolicyCallback apc,
|
|
|
- void *apc_cls)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Function called by MHD to allow the application to log
|
|
|
- * the @a full_uri of a @a request.
|
|
|
- * This is the only moment when unmodified URI is provided.
|
|
|
- * After this callback MHD parses the URI and modifies it
|
|
|
- * by extracting GET parameters in-place.
|
|
|
- *
|
|
|
- * @param cls client-defined closure
|
|
|
- * @param[in,out] request the HTTP request handle (headers are
|
|
|
- * not yet available)
|
|
|
- * @param uri the full URI from the HTTP request including parameters (after '?')
|
|
|
+ * Address family to be used by MHD.
|
|
|
*/
|
|
|
-typedef void
|
|
|
-(MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3)
|
|
|
- *MHD_EarlyUriLogCallback)(void *cls,
|
|
|
- struct MHD_Request *request,
|
|
|
- const struct MHD_String *full_uri);
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_AddressFamily
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * Option not given, do not listen at all
|
|
|
+ * (unless listen socket or address specified by
|
|
|
+ * other means).
|
|
|
+ */
|
|
|
+ MHD_AF_NONE = 0
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Pick "best" available method automatically.
|
|
|
+ */
|
|
|
+ MHD_AF_AUTO = 1
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Use IPv4.
|
|
|
+ */
|
|
|
+ MHD_AF_INET4 = 2
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Use IPv6.
|
|
|
+ */
|
|
|
+ MHD_AF_INET6 = 3
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Use dual stack.
|
|
|
+ */
|
|
|
+ MHD_AF_DUAL = 4
|
|
|
+};
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Register a callback to be called first for every request
|
|
|
- * (before any parsing of the header). Makes it easy to
|
|
|
- * log the full URL.
|
|
|
+ * Bind to the given socket address.
|
|
|
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
*
|
|
|
- * @param daemon daemon for which to set the logger
|
|
|
- * @param cb function to call
|
|
|
- * @param cb_cls closure for @a cb
|
|
|
+ * @param[in,out] daemon which instance to configure the binding address for
|
|
|
+ * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
|
|
|
+ * or even a UNIX domain socket (AF_UNIX)
|
|
|
+ * @param sa_len number of bytes in @a sa
|
|
|
+ * @return #MHD_SC_OK on on success,
|
|
|
+ * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
+ * #MHD_SC_FEATURE_DISABLED,
|
|
|
+ * #MHD_SC_FEATURE_NOT_AVAILABLE,
|
|
|
+ * #MHD_SC_OPTIONS_CONFLICT
|
|
|
*/
|
|
|
MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
|
|
|
- MHD_EarlyUriLogCallback cb,
|
|
|
- void *cb_cls)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
-
|
|
|
+MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
|
|
|
+ const struct sockaddr *sa,
|
|
|
+ size_t sa_len)
|
|
|
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_;
|
|
|
|
|
|
-/**
|
|
|
- * The `enum MHD_ConnectionNotificationCode` specifies types
|
|
|
- * of connection notifications.
|
|
|
- * @ingroup request
|
|
|
- */
|
|
|
-enum MHD_FIXED_ENUM_MHD_SET_ MHD_ConnectionNotificationCode
|
|
|
+// TODO: Sort values and assign numbers
|
|
|
+enum MHD_DeamonOptionUInt
|
|
|
{
|
|
|
+ /**
|
|
|
+ * Use the given backlog for the listen() call.
|
|
|
+ * Ineffective in conjunction with #MHD_daemon_listen_socket()
|
|
|
+ */
|
|
|
+ MHD_DAEMON_OPTION_UINT_LISTEN_BACKLOG,
|
|
|
+ /**
|
|
|
+ * Maximum number of (concurrent) network connections served
|
|
|
+ * by daemon
|
|
|
+ */
|
|
|
+ MHD_DAEMON_OPTION_UINT_GLOBAL_CONNECTION_LIMIT,
|
|
|
+ /**
|
|
|
+ * Limit on the number of (concurrent) network 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.
|
|
|
+ */
|
|
|
+ MHD_DAEMON_OPTION_UINT_IP_CONNECTION_LIMIT,
|
|
|
|
|
|
/**
|
|
|
- * A new connection has been started.
|
|
|
- * @ingroup request
|
|
|
+ * After how many seconds of inactivity should a
|
|
|
+ * connection automatically be timed out?
|
|
|
+ * Use zero for no timeout, which is also the (unsafe!) default.
|
|
|
*/
|
|
|
- MHD_CONNECTION_NOTIFY_STARTED = 0
|
|
|
- ,
|
|
|
+ MHD_DAEMON_OPTION_UINT_DEFAULT_TIMEOUT,
|
|
|
+
|
|
|
/**
|
|
|
- * A connection is closed.
|
|
|
- * @ingroup request
|
|
|
+ * The number of worker threads.
|
|
|
+ * Only useful if the selected threading mode
|
|
|
+ * is #MHD_TM_WORKER_THREADS.
|
|
|
+ * Zero number is silently ignored.
|
|
|
*/
|
|
|
- MHD_CONNECTION_NOTIFY_CLOSED = 1
|
|
|
+ MHD_DAEMON_OPTION_UINT_NUM_WORKERS
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * Extra details for connection notifications.
|
|
|
- * Currently not used
|
|
|
+ * Set unsigned integer MHD option.
|
|
|
+ *
|
|
|
+ * @param[in,out] daemon which instance to set uint @a option for
|
|
|
+ * @param option option to modify
|
|
|
+ * @param value new value for the option
|
|
|
+ * @return #MHD_SC_OK on on success,
|
|
|
+ * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
+ * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
+ * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system
|
|
|
+ * #MHD_SC_OPTIONS_CONFLICT
|
|
|
*/
|
|
|
-union MHD_ConnectionNotificationDetails
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_option_uint (struct MHD_Daemon *daemon,
|
|
|
+ enum MHD_DeamonOptionUInt option,
|
|
|
+ unsigned int value)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
+
|
|
|
+// FIXME: Alternative or additional implementation.
|
|
|
+
|
|
|
+struct MHD_DaemonOptioniUIntEntry
|
|
|
{
|
|
|
/**
|
|
|
- * Unused
|
|
|
+ * The option to update the @a value
|
|
|
*/
|
|
|
- int reserved1;
|
|
|
+ enum MHD_DeamonOptionUInt option;
|
|
|
+ /**
|
|
|
+ * The value to update for the @a option
|
|
|
+ */
|
|
|
+ unsigned int value;
|
|
|
+ // TODO: union
|
|
|
};
|
|
|
|
|
|
+#if 0
|
|
|
+/**
|
|
|
+ * Set unsigned integer MHD options.
|
|
|
+ *
|
|
|
+ * @param[in,out] daemon which instance to set uint @a option for
|
|
|
+ * @param num_entries the number of entries in the @a opt_val array
|
|
|
+ * and in @a results (if not NULL)
|
|
|
+ * @param[in] opt_val the array with options and values to modify
|
|
|
+ * @param[out] results the results for the applying the options,
|
|
|
+ * can be NULL,
|
|
|
+ * if not NULL must have @a num_entries entries
|
|
|
+ * @return #MHD_YES if all options have applied successfully
|
|
|
+ * #MHD_NO if at least single option failed (for more
|
|
|
+ * details check @a results)
|
|
|
+ */
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode // First failed // TODO: Document that rest may be used
|
|
|
+MHD_daemon_set_option_uint (
|
|
|
+ struct MHD_Daemon *daemon,
|
|
|
+ size_t num_entries,
|
|
|
+ struct MHD_DaemonOptioniUIntEntry opt_val[MHD_C99_ (static num_entries)])
|
|
|
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3);
|
|
|
+#endif
|
|
|
+// TODO: combine all types of options into single list with union
|
|
|
+/**
|
|
|
+ * Accept connections from the given socket. Socket
|
|
|
+ * must be a TCP or UNIX domain (stream) socket.
|
|
|
+ *
|
|
|
+ * Unless MHD_INVALID_SOCKET is given, this disables
|
|
|
+ * other listen options.
|
|
|
+ *
|
|
|
+ * @param daemon daemon to set listen socket for
|
|
|
+ * @param listen_socket listen socket to use,
|
|
|
+ * MHD_INVALID_SOCKET value will cause this call to be
|
|
|
+ * ignored (other binding options may still be effective)
|
|
|
+ * @return #MHD_SC_OK on on success,
|
|
|
+ * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
+ * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
+ * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system
|
|
|
+ * #MHD_SC_OPTIONS_CONFLICT
|
|
|
+ */
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
|
|
|
+ MHD_socket listen_socket)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
/**
|
|
|
- * The connection notification data structure
|
|
|
+ * Sockets polling internal syscalls used by MHD.
|
|
|
*/
|
|
|
-struct MHD_ConnectionNotificationData
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_SockPollSyscall
|
|
|
{
|
|
|
/**
|
|
|
- * The connection handle
|
|
|
+ * Automatic selection of best-available method. This is also the
|
|
|
+ * default.
|
|
|
*/
|
|
|
- struct MHD_Connection *connection;
|
|
|
- /**
|
|
|
- * The connection-specific application context data (opaque for MHD).
|
|
|
- * Initially set to NULL (for connections added by MHD) or set by
|
|
|
- * @a connection_cntx parameter for connections added by
|
|
|
- * #MHD_daemon_add_connection().
|
|
|
+ MHD_ELS_AUTO = 0
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Use select().
|
|
|
*/
|
|
|
- void *application_context;
|
|
|
+ MHD_ELS_SELECT = 1
|
|
|
+ ,
|
|
|
/**
|
|
|
- * The code of the event
|
|
|
+ * Use poll().
|
|
|
*/
|
|
|
- enum MHD_ConnectionNotificationCode code;
|
|
|
+ MHD_ELS_POLL = 2
|
|
|
+ ,
|
|
|
/**
|
|
|
- * Event details
|
|
|
+ * Use epoll.
|
|
|
*/
|
|
|
- union MHD_ConnectionNotificationDetails details;
|
|
|
+ MHD_ELS_EPOLL = 3
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Signature of the callback used by MHD to notify the
|
|
|
- * application about started/stopped network connections
|
|
|
- *
|
|
|
- * @param cls client-defined closure
|
|
|
- * @param[in,out] data the details about the event
|
|
|
- * @see #MHD_daemon_set_notify_connection()
|
|
|
- * @ingroup request
|
|
|
- */
|
|
|
-typedef void
|
|
|
-(MHD_FN_PAR_NONNULL_ (2)
|
|
|
- *MHD_NotifyConnectionCallback)(void *cls,
|
|
|
- struct MHD_ConnectionNotificationData *data);
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Register a function that should be called whenever a connection is
|
|
|
- * started or closed.
|
|
|
+ * Force use of a particular event loop system call.
|
|
|
*
|
|
|
- * @param daemon daemon to set callback for
|
|
|
- * @param ncc function to call to check the policy
|
|
|
- * @param ncc_cls closure for @a apc
|
|
|
+ * @param daemon daemon to set event loop style for
|
|
|
+ * @param els event loop syscall to use
|
|
|
+ * @return #MHD_SC_OK on on success,
|
|
|
+ * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
+ * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
+ * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system
|
|
|
+ * #MHD_SC_OPTIONS_CONFLICT
|
|
|
*/
|
|
|
MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
|
|
|
- MHD_NotifyConnectionCallback ncc,
|
|
|
- void *ncc_cls)
|
|
|
+MHD_daemon_event_loop (struct MHD_Daemon *daemon,
|
|
|
+ enum MHD_EventLoopSyscall els)
|
|
|
MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * The type of stream notifications.
|
|
|
- * @ingroup request
|
|
|
+ * Protocol strictness enforced by MHD on clients.
|
|
|
+ * All levels have different parsing settings for the headers.
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_MHD_SET_ MHD_StreamNotificationCode
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_ProtocolStrictLevel
|
|
|
{
|
|
|
+
|
|
|
+ /* * Basic levels * */
|
|
|
/**
|
|
|
- * A new connection has been started.
|
|
|
- * @ingroup request
|
|
|
+ * Sane level of protocol enforcement for production use.
|
|
|
+ * A balance between extra security and broader compatibility,
|
|
|
+ * as allowed by RFCs for HTTP servers.
|
|
|
*/
|
|
|
- MHD_STREAM_NOTIFY_STARTED = 0
|
|
|
+ MHD_PSL_DEFAULT = 0
|
|
|
,
|
|
|
/**
|
|
|
- * A connection is closed.
|
|
|
- * @ingroup request
|
|
|
+ * Be strict about the protocol (as opposed to as tolerant as
|
|
|
+ * possible), within the limits set by RFCs for HTTP servers.
|
|
|
+ * This level (and more strict) forbids use of bare LF as
|
|
|
+ * CRLF. It also rejects requests with both "Transfer-Encoding:"
|
|
|
+ * and "Content-Length:".
|
|
|
+ * It is suitable for public servers.
|
|
|
*/
|
|
|
- MHD_STREAM_NOTIFY_CLOSED = 1
|
|
|
-
|
|
|
-};
|
|
|
+ MHD_PSL_STRICT = 1
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Be particularly permissive about the protocol, within
|
|
|
+ * the limits set by RFCs for HTTP servers.
|
|
|
+ */
|
|
|
+ MHD_PSL_PERMISSIVE = -1,
|
|
|
|
|
|
-/**
|
|
|
- * Additional information about stream started event
|
|
|
- */
|
|
|
-struct MHD_StreamNotificationDetailStarted
|
|
|
-{
|
|
|
+ /* * Special levels * */
|
|
|
/**
|
|
|
- * Set to #MHD_YES of the stream was started by client
|
|
|
+ * 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.
|
|
|
+ * For chunked encoding parsing this level (and more strict)
|
|
|
+ * forbids whitespace in chunk extension.
|
|
|
+ * For cookies parsing this (and more strict) level rejects
|
|
|
+ * cookie in full even if a single value is encoded incorrectly
|
|
|
+ * in it.
|
|
|
+ * This level is recommended for testing clients against
|
|
|
+ * MHD. Also can be used for security-centric application,
|
|
|
+ * however it is slight violation of RFCs' requirements.
|
|
|
*/
|
|
|
- enum MHD_Bool by_client;
|
|
|
-};
|
|
|
+ MHD_PSL_VERY_STRICT = 2
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * The most strict interpretation of the HTTP protocol,
|
|
|
+ * much stricter that defined for HTTP servers by RFC.
|
|
|
+ * However it should be absolutely compatible with clients
|
|
|
+ * following RFCs' "SHOULD" and "MUST" types of requirements
|
|
|
+ * for HTTP clients.
|
|
|
+ * This level can be used for testing clients against MHD.
|
|
|
+ * It is not recommended for any public services as it may
|
|
|
+ * reject legitimate clients (clients not following "SHOULD"
|
|
|
+ * type of RFC requirements).
|
|
|
+ */
|
|
|
+ MHD_PSL_EXTRA_STRICT = 3
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * More relaxed protocol interpretation, violating RFCs'
|
|
|
+ * "SHOULD" type of restrictions for HTTP servers.
|
|
|
+ * For cookies parsing this (and more permissive) level
|
|
|
+ * allows whitespaces in cookie values.
|
|
|
+ * This level can be used in isolated environments.
|
|
|
+ */
|
|
|
+ MHD_PSL_VERY_PERMISSIVE = -2,
|
|
|
|
|
|
-/**
|
|
|
- * Additional information about stream events
|
|
|
- */
|
|
|
-union MHD_StreamNotificationDetail
|
|
|
-{
|
|
|
/**
|
|
|
- * Information for event #MHD_STREAM_NOTIFY_STARTED
|
|
|
+ * The most flexible protocol interpretation, beyond
|
|
|
+ * RFCs' "MUST" type of restrictions for HTTP server.
|
|
|
+ * The level allow HTTP/1.1 requests without "Host:" header.
|
|
|
+ * For cookies parsing this level adds allowance of
|
|
|
+ * whitespaces before and after '=' character.
|
|
|
+ * This level is not recommended unless it is absolutely
|
|
|
+ * necessary to communicate with some client(s) with
|
|
|
+ * badly broken HTTP implementation.
|
|
|
*/
|
|
|
- struct MHD_StreamNotificationDetailStarted started;
|
|
|
+ MHD_PSL_EXTRA_PERMISSIVE = -3,
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * Stream notification data structure
|
|
|
+ * The way Strict Level is enforced.
|
|
|
+ * MHD can be compiled with limited set of strictness levels.
|
|
|
+ * These values instructs MHD how to apply the request level.
|
|
|
*/
|
|
|
-struct MHD_StreamNotificationData
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_UseStictLevel
|
|
|
{
|
|
|
/**
|
|
|
- * The handle of the stream
|
|
|
+ * Use requested level if available or the nearest stricter
|
|
|
+ * level.
|
|
|
+ * Fail if only more permissive levels available.
|
|
|
+ * Recommended value.
|
|
|
*/
|
|
|
- struct MHD_Stream *stream;
|
|
|
+ MHD_USL_THIS_OR_STRICTER = 0
|
|
|
+ ,
|
|
|
/**
|
|
|
- * The code of the event
|
|
|
+ * Use requested level only.
|
|
|
+ * Fail if this level is not available.
|
|
|
*/
|
|
|
- enum MHD_StreamNotificationCode code;
|
|
|
+ MHD_USL_PRECISE = 1
|
|
|
+ ,
|
|
|
/**
|
|
|
- * Detailed information about notification event
|
|
|
+ * Use requested level if available or the nearest level (stricter
|
|
|
+ * or more permissive).
|
|
|
*/
|
|
|
- union MHD_StreamNotificationDetail details;
|
|
|
+ MHD_USL_NEAREST = 2
|
|
|
};
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
- * Signature of the callback used by MHD to notify the
|
|
|
- * application about started/stopped data stream
|
|
|
- * For HTTP/1.1 it is the same like network connection
|
|
|
- * with 1:1 match.
|
|
|
+ * Set how strictly MHD will enforce the HTTP protocol.
|
|
|
*
|
|
|
- * @param cls client-defined closure
|
|
|
- * @param data the details about the event
|
|
|
- * @see #MHD_OPTION_NOTIFY_CONNECTION
|
|
|
- * @ingroup request
|
|
|
+ * @param[in,out] daemon daemon to configure strictness for
|
|
|
+ * @param sl the level of strictness
|
|
|
+ * @param how the way how to use the requested level
|
|
|
+ * @return #MHD_SC_OK on on success,
|
|
|
+ * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore
|
|
|
+ * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library,
|
|
|
*/
|
|
|
-typedef void
|
|
|
-(MHD_FN_PAR_NONNULL_ (2)
|
|
|
- *MHD_NotifyStreamCallback)(
|
|
|
- void *cls,
|
|
|
- const struct MHD_StreamNotificationData *data);
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
|
|
|
+ enum MHD_ProtocolStrictLevel sl,
|
|
|
+ enum MHD_UseStictLevel how)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_option_string (struct MHD_Daemon *daemon,
|
|
|
+ enum foo,
|
|
|
+ const char *value)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
/**
|
|
|
- * Register a function that should be called whenever a stream is
|
|
|
- * started or closed.
|
|
|
+ * Provide TLS key and certificate data in-memory.
|
|
|
*
|
|
|
- * @param daemon daemon to set callback for
|
|
|
- * @param nsc function to call to check the policy
|
|
|
- * @param nsc_cls closure for @a apc
|
|
|
+ * @param daemon which instance should be configured
|
|
|
+ * @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.
|
|
|
+ * @param pass passphrase phrase to decrypt 'key.pem', NULL
|
|
|
+ * if @param mem_key is in cleartext already
|
|
|
+ * @return #MHD_SC_OK upon success;
|
|
|
*/
|
|
|
MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_notify_stream (struct MHD_Daemon *daemon,
|
|
|
- MHD_NotifyStreamCallback nsc,
|
|
|
- void *nsc_cls)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
-
|
|
|
-enum MHD_DaemonOptionSizet
|
|
|
-{
|
|
|
- /**
|
|
|
- * Maximum memory size per connection.
|
|
|
- * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT).
|
|
|
- * Values above 128k are unlikely to result in much performance 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.
|
|
|
- * The size should be large enough to fit all request headers (together
|
|
|
- * with internal parsing information).
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_SIZET_CONN_MEM_LIMIT,
|
|
|
- /**
|
|
|
- * Desired size of the stack for threads created by MHD.
|
|
|
- * Use 0 for system default, which is also MHD default.
|
|
|
- * Only useful if the selected threading mode
|
|
|
- * is not #MHD_TM_EXTERNAL_EVENT_LOOP.
|
|
|
- */
|
|
|
- MHD_DAEMON_OPTION_SIZET_STACK_SIZE,
|
|
|
+MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
|
|
|
+ const char *mem_key,
|
|
|
+ const char *mem_cert,
|
|
|
+ const char *pass)
|
|
|
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2)
|
|
|
+MHD_FN_PAR_NONNULL_ (3);
|
|
|
|
|
|
-};
|
|
|
-MHD_EXTERN_ void
|
|
|
-MHD_daemon_option_set_sizet (struct MHD_Daemon *daemon,
|
|
|
- enum MHD_DaemonOptionSizet option,
|
|
|
- size_t value)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
/**
|
|
|
- * 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 daemon is running.
|
|
|
+ * Configure DH parameters (dh.pem) to use for the TLS key
|
|
|
+ * exchange.
|
|
|
*
|
|
|
- * @param daemon daemon to configure
|
|
|
- * @param buf_size number of bytes in @a buf
|
|
|
- * @param buf entropy buffer
|
|
|
+ * @param daemon daemon to configure tls for
|
|
|
+ * @param dh parameters to use
|
|
|
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
|
|
|
*/
|
|
|
-MHD_EXTERN_ void
|
|
|
-MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
|
|
|
- size_t buf_size,
|
|
|
- const void *buf)
|
|
|
-MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3);
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
|
|
|
+ const char *dh)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
/**
|
|
|
- * Length of the internal array holding the map of the nonce and
|
|
|
- * the nonce counter.
|
|
|
+ * Memory pointer for the certificate (ca.pem) to be used by the
|
|
|
+ * HTTPS daemon for client authentication.
|
|
|
*
|
|
|
- * @param daemon daemon to configure
|
|
|
- * @param nc_length desired array length
|
|
|
+ * @param daemon daemon to configure tls for
|
|
|
+ * @param mem_trust memory pointer to the certificate
|
|
|
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
|
|
|
*/
|
|
|
MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_digest_auth_nc_length (struct MHD_Daemon *daemon,
|
|
|
- size_t nc_length)
|
|
|
+MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
|
|
|
+ const char *mem_trust)
|
|
|
MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
-// FIXME: end of transform everything to option
|
|
|
|
|
|
-union MHD_DaemonOptionValue
|
|
|
+/* ********************** (d) TLS support ********************** */
|
|
|
+
|
|
|
+/**
|
|
|
+ * The TLS backend choice
|
|
|
+ */
|
|
|
+enum MHD_FIXED_ENUM_APP_SET_ MHD_TlsBackend
|
|
|
{
|
|
|
- enum MHD_Bool v_bool;
|
|
|
- unsigned int v_uint;
|
|
|
- size_t v_sizet;
|
|
|
- struct MHD_DaemonOptionValueSA v_sa;
|
|
|
- enum MHD_DaemonOptionAddrReuse v_addr_reuse;
|
|
|
+ /**
|
|
|
+ * Disable TLS, use plain TCP connections
|
|
|
+ */
|
|
|
+ MHD_TLS_BACKEND_NONE = 0
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Use best available TLS backend.
|
|
|
+ * Currently this is equivalent to GnuTLS (if TLS is enabled
|
|
|
+ * for MHD build).
|
|
|
+ */
|
|
|
+ MHD_TLS_BACKEND_ANY = 1
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * Use GnuTLS as TLS backend.
|
|
|
+ */
|
|
|
+ MHD_TLS_BACKEND_GNUTLS = 2
|
|
|
};
|
|
|
|
|
|
-struct MHD_DaemonOptionAndValue
|
|
|
+/**
|
|
|
+ * 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_check() (and similar functions) to check nonce by
|
|
|
+ * re-generating it again with the same parameters, which is CPU-intensive
|
|
|
+ * operation.
|
|
|
+ */
|
|
|
+enum MHD_FIXED_FLAGS_ENUM_APP_SET_ MHD_DaemonOptionValueDAuthBindNonce
|
|
|
{
|
|
|
/**
|
|
|
- * The daemon configuration option
|
|
|
+ * 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.
|
|
|
*/
|
|
|
- enum MHD_DaemonOption opt;
|
|
|
+ MHD_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_NONE = 0,
|
|
|
+
|
|
|
/**
|
|
|
- * The value for the @a opt option
|
|
|
+ * Generated nonces are valid only for the same realm.
|
|
|
*/
|
|
|
- union MHD_DaemonOptionValue val;
|
|
|
-};
|
|
|
+ MHD_DAEMON_OPTION_VALUE_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_DAEMON_OPTION_VALUE_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_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_URI_PARAMS = 1 << 2,
|
|
|
|
|
|
-#if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)
|
|
|
-/* */ // TODO: no generic form
|
|
|
-# define MHD_D_OPTION_BOOL_SET_(option,bool_val) \
|
|
|
- MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
- (const struct MHD_DaemonOptionAndValue) \
|
|
|
- { \
|
|
|
- .opt = (option), \
|
|
|
- .val.v_bool = (bool_val) \
|
|
|
- } \
|
|
|
- MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
+ /**
|
|
|
+ * 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_DAEMON_OPTION_VALUE_DAUTH_BIND_NONCE_CLIENT_IP = 1 << 3
|
|
|
+};
|
|
|
|
|
|
/**
|
|
|
- * Bind to the given socket address.
|
|
|
- * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
+ * Enable and configure TLS.
|
|
|
*
|
|
|
- * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
|
|
|
- * or even a UNIX domain socket (AF_UNIX)
|
|
|
- * @param sa_len number of bytes in @a sa
|
|
|
- * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
+ * @param daemon which instance should be configured
|
|
|
+ * @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).
|
|
|
+ * @return status code, #MHD_SC_OK upon success
|
|
|
+ * #MHD_TLS_BACKEND_UNSUPPORTED if the @a backend is unknown
|
|
|
+ * #MHD_TLS_DISABLED if this build of MHD does not support TLS
|
|
|
+ * #MHD_TLS_CIPHERS_INVALID if the given @a ciphers are not supported
|
|
|
+ * by this backend
|
|
|
*/
|
|
|
-# define MHD_D_OPTION_SOCK_ADDR(sa_len_val,sa_val) \
|
|
|
- MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
- (const struct MHD_DaemonOptionAndValue) \
|
|
|
- { \
|
|
|
- .opt = (MHD_D_O_SA), \
|
|
|
- .val.v_sa.sa_len = (sa_len_val), \
|
|
|
- .val.v_sa.sa = (sa_val) \
|
|
|
- } \
|
|
|
- MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
|
|
|
+ enum MHD_TlsBackend backend)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
- * Terminate the list of the options
|
|
|
- * @return the terminating object of struct MHD_DaemonOptionAndValue
|
|
|
+ * Context required to provide a pre-shared key to the
|
|
|
+ * server.
|
|
|
+ *
|
|
|
+ * @param ...
|
|
|
+ * @param psk_size the number of bytes in @a psk
|
|
|
+ * @param psk the pre-shared-key; should be allocated with malloc(),
|
|
|
+ * will be freed by MHD
|
|
|
*/
|
|
|
-# define MHD_D_OPTION_TERMINATE() \
|
|
|
- MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
- (const struct MHD_DaemonOptionAndValue) \
|
|
|
- { \
|
|
|
- .opt = (MHD_D_O_END) \
|
|
|
- } \
|
|
|
- MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
-
|
|
|
-#else /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
|
|
|
-MHD_NOWARN_UNUSED_FUNC_
|
|
|
+struct MHD_ServerCredentialsContext;
|
|
|
|
|
|
-/* Do not use directly */
|
|
|
-static MHD_INLINE struct MHD_DaemonOptionAndValue
|
|
|
-MHD_D_OPTION_BOOL_SET_(enum MHD_DaemonOption option,
|
|
|
- enum MHD_Bool bool_val)
|
|
|
-{
|
|
|
- struct MHD_DaemonOptionAndValue opt_val;
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_connection_set_psk (struct MHD_ServerCredentialsContext *mscc,
|
|
|
+ size_t psk_size,
|
|
|
+ const /*void? */ char psk[MHD_C99_ (psk_size)]);
|
|
|
|
|
|
- opt_val.opt = option;
|
|
|
- opt_val.val.v_bool = bool_val;
|
|
|
+#define MHD_connection_set_psk_unavailable(mscc) \
|
|
|
+ MHD_connection_set_psk (mscc, 0, NULL)
|
|
|
|
|
|
- return opt_val;
|
|
|
-}
|
|
|
|
|
|
/**
|
|
|
- * Bind to the given socket address.
|
|
|
- * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
+ * Function called to lookup the pre-shared key (PSK) for a given
|
|
|
+ * HTTP connection based on the @a username. MHD will suspend handling of
|
|
|
+ * the @a connection until the application calls #MHD_connection_set_psk().
|
|
|
+ * If looking up the PSK fails, the application must still call
|
|
|
+ * #MHD_connection_set_psk_unavailable().
|
|
|
*
|
|
|
- * @param sa_len_val the number of bytes in @a sa
|
|
|
- * @param sa_val the address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
|
|
|
- * or even a UNIX domain socket (AF_UNIX)
|
|
|
- * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
+ * @param cls closure
|
|
|
+ * @param connection the HTTPS connection
|
|
|
+ * @param username the user name claimed by the other side
|
|
|
+ * @param mscc context to pass to #MHD_connection_set_psk().
|
|
|
+ * @return 0 on success, -1 on errors
|
|
|
*/
|
|
|
-static MHD_INLINE struct MHD_DaemonOptionAndValue
|
|
|
-MHD_D_OPTION_SOCK_ADDR(size_t sa_len_val,
|
|
|
- const struct sockaddr *sa_val)
|
|
|
-{
|
|
|
- struct MHD_DaemonOptionAndValue opt_val;
|
|
|
-
|
|
|
- opt_val.opt = MHD_D_O_SA;
|
|
|
- opt_val.val.v_sa.sa_len = sa_len_val;
|
|
|
- opt_val.val.v_sa.sa = sa_val;
|
|
|
+typedef void
|
|
|
+(*MHD_PskServerCredentialsCallback)(void *cls,
|
|
|
+ const struct MHD_Connection *connection,
|
|
|
+ const struct MHD_String *username,
|
|
|
+ struct MHD_ServerCredentialsContext *mscc);
|
|
|
|
|
|
- return opt_val;
|
|
|
-}
|
|
|
|
|
|
/**
|
|
|
- * Terminate the list of the options
|
|
|
- * @return the terminating object of struct MHD_DaemonOptionAndValue
|
|
|
+ * Configure PSK to use for the TLS key exchange.
|
|
|
+ *
|
|
|
+ * @param daemon daemon to configure tls for
|
|
|
+ * @param psk_cb function to call to obtain pre-shared key
|
|
|
+ * @param psk_cb_cls closure for @a psk_cb
|
|
|
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
|
|
|
*/
|
|
|
-static MHD_INLINE struct MHD_DaemonOptionAndValue
|
|
|
-MHD_D_OPTION_TERMINATE(void)
|
|
|
-{
|
|
|
- struct MHD_DaemonOptionAndValue opt_val;
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_tls_psk_callback (struct MHD_Daemon *daemon,
|
|
|
+ MHD_PskServerCredentialsCallback psk_cb,
|
|
|
+ void *psk_cb_cls)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
- opt_val.opt = MHD_D_O_END;
|
|
|
|
|
|
- return opt_val;
|
|
|
-}
|
|
|
|
|
|
-MHD_RESTORE_WARN_UNUSED_FUNC_
|
|
|
-#endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
|
|
|
+// Callback invoked between full initialization of MHD
|
|
|
+// during MHD_daemon_start() and actual event loop
|
|
|
+// starting to accept incoming connections. So at this
|
|
|
+// point, the listen socket (and if applicable TLS context)
|
|
|
+// will be available for introspection.
|
|
|
+typedef void
|
|
|
+(*MHD_DaemonReadyCallback)(void *cls);
|
|
|
+
|
|
|
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_daemon_ready_callback (struct MHD_Daemon *daemon,
|
|
|
+ MHD_DaemonReadyCallback cb,
|
|
|
+ void *cb)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Suppresses use of "Date:" header.
|
|
|
- * According to RFC should be used only if the system has no RTC.
|
|
|
- * @param bool_val the value of the parameter
|
|
|
- * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
+ * Allow or deny a client to connect.
|
|
|
+ *
|
|
|
+ * @param cls closure
|
|
|
+ * @param addrlen length of @a addr
|
|
|
+ * @param addr address information from the client
|
|
|
+ * @see #MHD_daemon_accept_policy()
|
|
|
+ * @return #MHD_YES if connection is allowed, #MHD_NO if not
|
|
|
*/
|
|
|
-#define MHD_D_OPTION_SUPPRESS_DATE_HEADER(bool_val) \
|
|
|
- MHD_D_OPTION_BOOL_SET_(MHD_D_O_BOOL_SUPPRESS_DATE_HEADER,(bool_val))
|
|
|
+typedef enum MHD_Bool
|
|
|
+(*MHD_AcceptPolicyCallback)(void *cls,
|
|
|
+ size_t addr_len,
|
|
|
+ const struct sockaddr *addr);
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
- * Disable #MHD_action_suspend() functionality.
|
|
|
+ * Set a policy callback that accepts/rejects connections
|
|
|
+ * based on the client's IP address. This function will be called
|
|
|
+ * before a connection object is created.
|
|
|
*
|
|
|
- * You should only use this function if you are sure you do
|
|
|
- * satisfy all of its requirements and need a generally minor
|
|
|
- * boost in performance.
|
|
|
- * @param bool_val the value of the parameter
|
|
|
- * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
+ * @param daemon daemon to set policy for
|
|
|
+ * @param apc function to call to check the policy
|
|
|
+ * @param apc_cls closure for @a apc
|
|
|
*/
|
|
|
-#define MHD_D_OPTION_DISALLOW_SUSPEND_RESUME(bool_val) \
|
|
|
- MHD_D_OPTION_BOOL_SET_(MHD_D_O_BOOL_DISALLOW_SUSPEND_RESUME,(bool_val))
|
|
|
+MHD_EXTERN_ void
|
|
|
+MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
|
|
|
+ MHD_AcceptPolicyCallback apc,
|
|
|
+ void *apc_cls)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Set the requested options for the daemon.
|
|
|
+ * Function called by MHD to allow the application to log
|
|
|
+ * the @a full_uri of a @a request.
|
|
|
+ * This is the only moment when unmodified URI is provided.
|
|
|
+ * After this callback MHD parses the URI and modifies it
|
|
|
+ * by extracting GET parameters in-place.
|
|
|
*
|
|
|
- * If any option fail other options may be or may be not applied.
|
|
|
- * @param daemon the daemon to set the options
|
|
|
- * @param[in] options the pointer to the array with the options;
|
|
|
- * the array processing stops at the first ::MHD_D_O_END
|
|
|
- * option, but not later than after processing
|
|
|
- * @a options_max_num entries
|
|
|
- * @param options_max_num the maximum number of entries in the @a options,
|
|
|
- * use MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
|
|
|
- * must stop only at zero-termination option
|
|
|
- * @return ::MHD_SC_OK on success,
|
|
|
- * error code otherwise
|
|
|
+ * @param cls client-defined closure
|
|
|
+ * @param[in,out] request the HTTP request handle (headers are
|
|
|
+ * not yet available)
|
|
|
+ * @param uri the full URI from the HTTP request including parameters (after '?')
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_options_set(struct MHD_Daemon *daemon,
|
|
|
- const struct MHD_DaemonOptionAndValue *options,
|
|
|
- size_t options_max_num)
|
|
|
-MHD_FN_PAR_NONNULL_ALL_;
|
|
|
+typedef void
|
|
|
+(MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3)
|
|
|
+ *MHD_EarlyUriLogCallback)(void *cls,
|
|
|
+ struct MHD_Request *request,
|
|
|
+ const struct MHD_String *full_uri);
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Set the requested single option for the daemon.
|
|
|
+ * Register a callback to be called first for every request
|
|
|
+ * (before any parsing of the header). Makes it easy to
|
|
|
+ * log the full URL.
|
|
|
*
|
|
|
- * @param daemon the daemon to set the option
|
|
|
- * @param[in] options the pointer to the option
|
|
|
- * @return ::MHD_SC_OK on success,
|
|
|
- * error code otherwise
|
|
|
+ * @param daemon daemon for which to set the logger
|
|
|
+ * @param cb function to call
|
|
|
+ * @param cb_cls closure for @a cb
|
|
|
*/
|
|
|
-#define MHD_daemon_option_set(daemon, option_ptr) \
|
|
|
- MHD_daemon_options_set(daemon, options_ptr, 1)
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
|
|
|
+ MHD_EarlyUriLogCallback cb,
|
|
|
+ void *cb_cls)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
|
|
|
-#ifdef MHD_USE_VARARG_MACROS
|
|
|
-MHD_NOWARN_VARIADIC_MACROS_
|
|
|
-# if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_COMP_LIT_FUNC_PARAMS)
|
|
|
/**
|
|
|
- * Set the requested options for the daemon.
|
|
|
- *
|
|
|
- * If any option fail other options may be or may be not applied.
|
|
|
- *
|
|
|
- * It should be used with helpers that creates required options, for example:
|
|
|
- *
|
|
|
- * MHD_DAEMON_OPTIONS_SET(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
|
|
|
- * MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
|
|
|
- *
|
|
|
- * @param daemon the daemon to set the options
|
|
|
- * @param ... the list of the options, each option must be created
|
|
|
- * by helpers MHD_DAEMON_OPTION_NameOfOption(option_value)
|
|
|
- * @return ::MHD_SC_OK on success,
|
|
|
- * error code otherwise
|
|
|
+ * The `enum MHD_ConnectionNotificationCode` specifies types
|
|
|
+ * of connection notifications.
|
|
|
+ * @ingroup request
|
|
|
*/
|
|
|
-# define MHD_DAEMON_OPTIONS_SET(daemon,...) \
|
|
|
- MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
- MHD_daemon_options_set(daemon, \
|
|
|
- ((const struct MHD_DaemonOptionAndValue[]) \
|
|
|
- {__VA_ARGS__, MHD_D_OPTION_TERMINATE()}), \
|
|
|
- MHD_OPTIONS_ARRAY_MAX_SIZE) \
|
|
|
- MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
-# elif defined(MHD_USE_CPP_INIT_LIST)
|
|
|
-} /* extern "C" */
|
|
|
-# include <vector>
|
|
|
-extern "C"
|
|
|
+enum MHD_FIXED_ENUM_MHD_SET_ MHD_ConnectionNotificationCode
|
|
|
{
|
|
|
-/**
|
|
|
- * Set the requested options for the daemon.
|
|
|
- *
|
|
|
- * If any option fail other options may be or may be not applied.
|
|
|
- *
|
|
|
- * It should be used with helpers that creates required options, for example:
|
|
|
- *
|
|
|
- * MHD_DAEMON_OPTIONS_SET(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
|
|
|
- * MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
|
|
|
- *
|
|
|
- * @param daemon the daemon to set the options
|
|
|
- * @param ... the list of the options, each option must be created
|
|
|
- * by helpers MHD_D_OPTION_NameOfOption(option_value)
|
|
|
- * @return ::MHD_SC_OK on success,
|
|
|
- * error code otherwise
|
|
|
- */
|
|
|
-# define MHD_DAEMON_OPTIONS_SET(daemon,...) \
|
|
|
- MHD_NOWARN_CPP_INIT_LIST_ \
|
|
|
- MHD_daemon_options_set(daemon, \
|
|
|
- (std::vector<struct MHD_DaemonOptionAndValue> \
|
|
|
- {__VA_ARGS__,MHD_D_OPTION_TERMINATE()}).data(), \
|
|
|
- MHD_OPTIONS_ARRAY_MAX_SIZE) \
|
|
|
- MHD_RESTORE_WARN_CPP_INIT_LIST_
|
|
|
-# endif
|
|
|
-MHD_RESTORE_WARN_VARIADIC_MACROS_
|
|
|
-#endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
|
|
|
|
|
|
+ /**
|
|
|
+ * A new connection has been started.
|
|
|
+ * @ingroup request
|
|
|
+ */
|
|
|
+ MHD_CONNECTION_NOTIFY_STARTED = 0
|
|
|
+ ,
|
|
|
+ /**
|
|
|
+ * A connection is closed.
|
|
|
+ * @ingroup request
|
|
|
+ */
|
|
|
+ MHD_CONNECTION_NOTIFY_CLOSED = 1
|
|
|
+
|
|
|
+};
|
|
|
|
|
|
-/* ******************* Event loop ************************ */
|
|
|
+/**
|
|
|
+ * Extra details for connection notifications.
|
|
|
+ * Currently not used
|
|
|
+ */
|
|
|
+union MHD_ConnectionNotificationDetails
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * Unused
|
|
|
+ */
|
|
|
+ int reserved1;
|
|
|
+};
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Which threading and polling mode should be used by MHD?
|
|
|
+ * The connection notification data structure
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_APP_SET_ MHD_WorkMode
|
|
|
+struct MHD_ConnectionNotificationData
|
|
|
{
|
|
|
/**
|
|
|
- * The daemon has no internal threads.
|
|
|
- * The application periodically calls #MHD_daemon_process_blocking(), where
|
|
|
- * MHD internally checks all sockets automatically.
|
|
|
- * This is the default.
|
|
|
+ * The connection handle
|
|
|
*/
|
|
|
- MHD_WM_EXTERNAL_PERIODIC = 0
|
|
|
- ,
|
|
|
+ struct MHD_Connection *connection;
|
|
|
/**
|
|
|
- * Use an external event loop with level triggers.
|
|
|
- * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
|
|
|
- * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
|
|
|
+ * The connection-specific application context data (opaque for MHD).
|
|
|
+ * Initially set to NULL (for connections added by MHD) or set by
|
|
|
+ * @a connection_cntx parameter for connections added by
|
|
|
+ * #MHD_daemon_add_connection().
|
|
|
*/
|
|
|
- MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL = 8
|
|
|
- ,
|
|
|
+ void *application_context;
|
|
|
/**
|
|
|
- * Use an external event loop with edge triggers.
|
|
|
- * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
|
|
|
- * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
|
|
|
+ * The code of the event
|
|
|
*/
|
|
|
- MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE = 9
|
|
|
- ,
|
|
|
+ enum MHD_ConnectionNotificationCode code;
|
|
|
/**
|
|
|
- * The daemon has no internal threads.
|
|
|
- * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
|
|
|
- * that triggered when any MHD event happens.
|
|
|
- * This FD can be watched as an aggregate indicator for all MHD events.
|
|
|
- * This mode is available only on selected platforms (currently
|
|
|
- * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
|
|
|
- * When the FD is triggered, #MHD_daemon_process_nonblocking() should
|
|
|
- * be called.
|
|
|
+ * Event details
|
|
|
*/
|
|
|
- MHD_WM_EXTERNAL_SINGLE_FD_WATCH = 16
|
|
|
+ union MHD_ConnectionNotificationDetails details;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Signature of the callback used by MHD to notify the
|
|
|
+ * application about started/stopped network connections
|
|
|
+ *
|
|
|
+ * @param cls client-defined closure
|
|
|
+ * @param[in,out] data the details about the event
|
|
|
+ * @see #MHD_daemon_set_notify_connection()
|
|
|
+ * @ingroup request
|
|
|
+ */
|
|
|
+typedef void
|
|
|
+(MHD_FN_PAR_NONNULL_ (2)
|
|
|
+ *MHD_NotifyConnectionCallback)(void *cls,
|
|
|
+ struct MHD_ConnectionNotificationData *data);
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Register a function that should be called whenever a connection is
|
|
|
+ * started or closed.
|
|
|
+ *
|
|
|
+ * @param daemon daemon to set callback for
|
|
|
+ * @param ncc function to call to check the policy
|
|
|
+ * @param ncc_cls closure for @a apc
|
|
|
+ */
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
|
|
|
+ MHD_NotifyConnectionCallback ncc,
|
|
|
+ void *ncc_cls)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * The type of stream notifications.
|
|
|
+ * @ingroup request
|
|
|
+ */
|
|
|
+enum MHD_FIXED_ENUM_MHD_SET_ MHD_StreamNotificationCode
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * A new connection has been started.
|
|
|
+ * @ingroup request
|
|
|
+ */
|
|
|
+ MHD_STREAM_NOTIFY_STARTED = 0
|
|
|
,
|
|
|
/**
|
|
|
- * Run with one or more worker threads.
|
|
|
- * If #MHD_DAEMON_OPTION_UINT_NUM_WORKERS is not specified
|
|
|
- * then daemon starts with single worker thread that process
|
|
|
- * all connections.
|
|
|
- * If #MHD_DAEMON_OPTION_UINT_NUM_WORKERS used with value more
|
|
|
- * than one, then that number of worker threads and distributed
|
|
|
- * processing of requests among the workers.
|
|
|
+ * A connection is closed.
|
|
|
+ * @ingroup request
|
|
|
*/
|
|
|
- MHD_WM_WORKER_THREADS = 24
|
|
|
- ,
|
|
|
+ MHD_STREAM_NOTIFY_CLOSED = 1
|
|
|
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Additional information about stream started event
|
|
|
+ */
|
|
|
+struct MHD_StreamNotificationDetailStarted
|
|
|
+{
|
|
|
/**
|
|
|
- * MHD should create its own thread for listening and furthermore create
|
|
|
- * additional threads per every connection. Use this if handling requests
|
|
|
- * is CPU-intensive or blocking, your application is thread-safe and you
|
|
|
- * have plenty of memory (per connection).
|
|
|
+ * Set to #MHD_YES of the stream was started by client
|
|
|
*/
|
|
|
- MHD_WM_THREAD_PER_CONNECTION = 32
|
|
|
+ enum MHD_Bool by_client;
|
|
|
};
|
|
|
|
|
|
-union MHD_WorkModeParam
|
|
|
+/**
|
|
|
+ * Additional information about stream events
|
|
|
+ */
|
|
|
+union MHD_StreamNotificationDetail
|
|
|
{
|
|
|
-
|
|
|
+ /**
|
|
|
+ * Information for event #MHD_STREAM_NOTIFY_STARTED
|
|
|
+ */
|
|
|
+ struct MHD_StreamNotificationDetailStarted started;
|
|
|
};
|
|
|
|
|
|
-struct MHD_WorkModeWithParam
|
|
|
+/**
|
|
|
+ * Stream notification data structure
|
|
|
+ */
|
|
|
+struct MHD_StreamNotificationData
|
|
|
{
|
|
|
/**
|
|
|
- * The work mode for MHD
|
|
|
+ * The handle of the stream
|
|
|
*/
|
|
|
- enum MHD_WorkMode mode;
|
|
|
+ struct MHD_Stream *stream;
|
|
|
/**
|
|
|
- * The parameters used for specified work mode
|
|
|
+ * The code of the event
|
|
|
+ */
|
|
|
+ enum MHD_StreamNotificationCode code;
|
|
|
+ /**
|
|
|
+ * Detailed information about notification event
|
|
|
*/
|
|
|
- union MHD_WorkModeParam val;
|
|
|
+ union MHD_StreamNotificationDetail details;
|
|
|
};
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
- * Specify threading mode to use.
|
|
|
+ * Signature of the callback used by MHD to notify the
|
|
|
+ * application about started/stopped data stream
|
|
|
+ * For HTTP/1.1 it is the same like network connection
|
|
|
+ * with 1:1 match.
|
|
|
*
|
|
|
- * @param[in,out] daemon daemon to configure
|
|
|
- * @param tm mode to use
|
|
|
+ * @param cls client-defined closure
|
|
|
+ * @param data the details about the event
|
|
|
+ * @see #MHD_OPTION_NOTIFY_CONNECTION
|
|
|
+ * @ingroup request
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_daemon_set_threading_mode (struct MHD_Daemon *daemon,
|
|
|
- enum MHD_ThreadingMode tm)
|
|
|
-MHD_FN_PAR_NONNULL_ (1);
|
|
|
+typedef void
|
|
|
+(MHD_FN_PAR_NONNULL_ (2)
|
|
|
+ *MHD_NotifyStreamCallback)(
|
|
|
+ void *cls,
|
|
|
+ const struct MHD_StreamNotificationData *data);
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * The network status of the socket.
|
|
|
- * When set by MHD (by #MHD_get_watched_fds(), #MHD_get_watched_fds_update() and
|
|
|
- * similar) it indicates a request to watch for specific socket state:
|
|
|
- * readiness for receiving the data, readiness for sending the data and/or
|
|
|
- * exception state of the socket.
|
|
|
- * When set by application (and provided for #MHD_process_watched_fds() and
|
|
|
- * similar) it must indicate the actual status of the socket.
|
|
|
+ * Register a function that should be called whenever a stream is
|
|
|
+ * started or closed.
|
|
|
*
|
|
|
- * Any actual state is a bitwise OR combination of #MHD_FD_STATE_RECV,
|
|
|
- * #MHD_FD_STATE_SEND, #MHD_FD_STATE_EXCEPT.
|
|
|
- * @ingroup event
|
|
|
+ * @param daemon daemon to set callback for
|
|
|
+ * @param nsc function to call to check the policy
|
|
|
+ * @param nsc_cls closure for @a apc
|
|
|
*/
|
|
|
-enum MHD_FIXED_ENUM_ MHD_FdState
|
|
|
-{
|
|
|
- /**
|
|
|
- * The socket is not ready for receiving or sending and
|
|
|
- * does not have any exceptional state.
|
|
|
- * The state never set by MHD, except de-registration of the sockets
|
|
|
- * for #MHD_SocketRegistrationUpdateCallback().
|
|
|
- */
|
|
|
- MHD_FD_STATE_NONE = 0
|
|
|
- ,
|
|
|
- /* ** Three bit-flags ** */
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_notify_stream (struct MHD_Daemon *daemon,
|
|
|
+ MHD_NotifyStreamCallback nsc,
|
|
|
+ void *nsc_cls)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
+enum MHD_DaemonOptionSizet
|
|
|
+{
|
|
|
/**
|
|
|
- * Indicates that socket should be watched for incoming data
|
|
|
- * (when set by #MHD_get_watched_fds())
|
|
|
- * / socket has incoming data ready to read (when used for
|
|
|
- * #MHD_process_watched_fds())
|
|
|
- */
|
|
|
- MHD_FD_STATE_RECV = 1 << 0,
|
|
|
- /**
|
|
|
- * Indicates that socket should be watched for availability for sending
|
|
|
- * (when set by #MHD_get_watched_fds())
|
|
|
- * / socket has ability to send data (when used for
|
|
|
- * #MHD_process_watched_fds())
|
|
|
+ * Maximum memory size per connection.
|
|
|
+ * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT).
|
|
|
+ * Values above 128k are unlikely to result in much performance 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.
|
|
|
+ * The size should be large enough to fit all request headers (together
|
|
|
+ * with internal parsing information).
|
|
|
*/
|
|
|
- MHD_FD_STATE_SEND = 1 << 1,
|
|
|
+ MHD_DAEMON_OPTION_SIZET_CONN_MEM_LIMIT,
|
|
|
/**
|
|
|
- * Indicates that socket should be watched for disconnect, out-of-band
|
|
|
- * data available or high priority data available (when set by
|
|
|
- * #MHD_get_watched_fds())
|
|
|
- * / socket has been disconnected, has out-of-band data available or
|
|
|
- * has high priority data available (when used for
|
|
|
- * #MHD_process_watched_fds()). This status must not include "remote
|
|
|
- * peer shut down writing" status.
|
|
|
- * Note: #MHD_get_watched_fds() always set it as exceptions must be
|
|
|
- * always watched.
|
|
|
+ * Desired size of the stack for threads created by MHD.
|
|
|
+ * Use 0 for system default, which is also MHD default.
|
|
|
+ * Only useful if the selected threading mode
|
|
|
+ * is not #MHD_TM_EXTERNAL_EVENT_LOOP.
|
|
|
*/
|
|
|
- MHD_FD_STATE_EXCEPT = 1 << 2,
|
|
|
+ MHD_DAEMON_OPTION_SIZET_STACK_SIZE,
|
|
|
|
|
|
- /* The rest of the list is a bit-wise combination of three main
|
|
|
- * states. Application may use three main states directly as
|
|
|
- * a bit-mask instead of using of following values
|
|
|
- */
|
|
|
+};
|
|
|
+MHD_EXTERN_ void
|
|
|
+MHD_daemon_option_set_sizet (struct MHD_Daemon *daemon,
|
|
|
+ enum MHD_DaemonOptionSizet option,
|
|
|
+ size_t value)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
|
|
|
+/**
|
|
|
+ * 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 daemon is running.
|
|
|
+ *
|
|
|
+ * @param daemon daemon to configure
|
|
|
+ * @param buf_size number of bytes in @a buf
|
|
|
+ * @param buf entropy buffer
|
|
|
+ */
|
|
|
+MHD_EXTERN_ void
|
|
|
+MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
|
|
|
+ size_t buf_size,
|
|
|
+ const void *buf)
|
|
|
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Length of the internal array holding the map of the nonce and
|
|
|
+ * the nonce counter.
|
|
|
+ *
|
|
|
+ * @param daemon daemon to configure
|
|
|
+ * @param nc_length desired array length
|
|
|
+ */
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_set_digest_auth_nc_length (struct MHD_Daemon *daemon,
|
|
|
+ size_t nc_length)
|
|
|
+MHD_FN_PAR_NONNULL_ (1);
|
|
|
+
|
|
|
+// FIXME: end of transform everything to option
|
|
|
+
|
|
|
+union MHD_DaemonOptionValue
|
|
|
+{
|
|
|
+ enum MHD_Bool v_bool;
|
|
|
+ unsigned int v_uint;
|
|
|
+ size_t v_sizet;
|
|
|
+ struct MHD_DaemonOptionValueSA v_sa;
|
|
|
+ enum MHD_DaemonOptionAddrReuse v_addr_reuse;
|
|
|
+};
|
|
|
+
|
|
|
+struct MHD_DaemonOptionAndValue
|
|
|
+{
|
|
|
/**
|
|
|
- * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_SEND states.
|
|
|
- */
|
|
|
- MHD_FD_STATE_RECV_SEND = MHD_FD_STATE_RECV | MHD_FD_STATE_SEND,
|
|
|
- /**
|
|
|
- * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
|
|
|
- */
|
|
|
- MHD_FD_STATE_RECV_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT,
|
|
|
- /**
|
|
|
- * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
|
|
|
+ * The daemon configuration option
|
|
|
*/
|
|
|
- MHD_FD_STATE_SEND_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT,
|
|
|
+ enum MHD_DaemonOption opt;
|
|
|
/**
|
|
|
- * Combination of #MHD_FD_STATE_RECV, #MHD_FD_STATE_SEND and
|
|
|
- * #MHD_FD_STATE_EXCEPT states.
|
|
|
+ * The value for the @a opt option
|
|
|
*/
|
|
|
- MHD_FD_STATE_RECV_SEND_EXCEPT = \
|
|
|
- MHD_FD_STATE_RECV | MHD_FD_STATE_SEND | MHD_FD_STATE_EXCEPT
|
|
|
+ union MHD_DaemonOptionValue val;
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
- * Checks whether specific @a state is enabled in @a var
|
|
|
- */
|
|
|
-#define MHD_FD_STATE_IS_SET(var,state) \
|
|
|
- (MHD_FD_STATE_NONE != \
|
|
|
- (((enum MHD_FdState) (var)) & ((enum MHD_FdState) (state))))
|
|
|
+
|
|
|
+#if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)
|
|
|
+/* */ // TODO: no generic form
|
|
|
+# define MHD_D_OPTION_BOOL_SET_(option,bool_val) \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_DaemonOptionAndValue) \
|
|
|
+ { \
|
|
|
+ .opt = (option), \
|
|
|
+ .val.v_bool = (bool_val) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
|
|
|
/**
|
|
|
- * Checks whether RECV is enabled in @a var
|
|
|
- */
|
|
|
-#define MHD_FD_STATE_IS_SET_RECV(var) \
|
|
|
- MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_RECV)
|
|
|
-/**
|
|
|
- * Checks whether SEND is enabled in @a var
|
|
|
+ * Bind to the given socket address.
|
|
|
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
+ *
|
|
|
+ * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
|
|
|
+ * or even a UNIX domain socket (AF_UNIX)
|
|
|
+ * @param sa_len number of bytes in @a sa
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_IS_SET_SEND(var) \
|
|
|
- MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_SEND)
|
|
|
+# define MHD_D_OPTION_SOCK_ADDR(sa_len_val,sa_val) \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_DaemonOptionAndValue) \
|
|
|
+ { \
|
|
|
+ .opt = (MHD_D_O_SA), \
|
|
|
+ .val.v_sa.sa_len = (sa_len_val), \
|
|
|
+ .val.v_sa.sa = (sa_val) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
+
|
|
|
/**
|
|
|
- * Checks whether EXCEPT is enabled in @a var
|
|
|
+ * Terminate the list of the options
|
|
|
+ * @return the terminating object of struct MHD_DaemonOptionAndValue
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_IS_SET_EXCEPT(var) \
|
|
|
- MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_EXCEPT)
|
|
|
+# define MHD_D_OPTION_TERMINATE() \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ (const struct MHD_DaemonOptionAndValue) \
|
|
|
+ { \
|
|
|
+ .opt = (MHD_D_O_END) \
|
|
|
+ } \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
+
|
|
|
+#else /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
|
|
|
+MHD_NOWARN_UNUSED_FUNC_
|
|
|
+
|
|
|
+/* Do not use directly */
|
|
|
+static MHD_INLINE struct MHD_DaemonOptionAndValue
|
|
|
+MHD_D_OPTION_BOOL_SET_(enum MHD_DaemonOption option,
|
|
|
+ enum MHD_Bool bool_val)
|
|
|
+{
|
|
|
+ struct MHD_DaemonOptionAndValue opt_val;
|
|
|
+
|
|
|
+ opt_val.opt = option;
|
|
|
+ opt_val.val.v_bool = bool_val;
|
|
|
|
|
|
+ return opt_val;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * Enable specific @a state in @a var
|
|
|
+ * Bind to the given socket address.
|
|
|
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
|
|
|
+ *
|
|
|
+ * @param sa_len_val the number of bytes in @a sa
|
|
|
+ * @param sa_val the address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
|
|
|
+ * or even a UNIX domain socket (AF_UNIX)
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_SET(var,state) \
|
|
|
- (var) = (enum MHD_FdState) ((var) | (state))
|
|
|
+static MHD_INLINE struct MHD_DaemonOptionAndValue
|
|
|
+MHD_D_OPTION_SOCK_ADDR(size_t sa_len_val,
|
|
|
+ const struct sockaddr *sa_val)
|
|
|
+{
|
|
|
+ struct MHD_DaemonOptionAndValue opt_val;
|
|
|
+
|
|
|
+ opt_val.opt = MHD_D_O_SA;
|
|
|
+ opt_val.val.v_sa.sa_len = sa_len_val;
|
|
|
+ opt_val.val.v_sa.sa = sa_val;
|
|
|
+
|
|
|
+ return opt_val;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
- * Enable RECV state in @a var
|
|
|
+ * Terminate the list of the options
|
|
|
+ * @return the terminating object of struct MHD_DaemonOptionAndValue
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_SET_RECV(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_RECV)
|
|
|
+static MHD_INLINE struct MHD_DaemonOptionAndValue
|
|
|
+MHD_D_OPTION_TERMINATE(void)
|
|
|
+{
|
|
|
+ struct MHD_DaemonOptionAndValue opt_val;
|
|
|
+
|
|
|
+ opt_val.opt = MHD_D_O_END;
|
|
|
+
|
|
|
+ return opt_val;
|
|
|
+}
|
|
|
+
|
|
|
+MHD_RESTORE_WARN_UNUSED_FUNC_
|
|
|
+#endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
- * Enable SEND state in @a var
|
|
|
+ * Suppresses use of "Date:" header.
|
|
|
+ * According to RFC should be used only if the system has no RTC.
|
|
|
+ * @param bool_val the value of the parameter
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_SET_SEND(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_SEND)
|
|
|
+#define MHD_D_OPTION_SUPPRESS_DATE_HEADER(bool_val) \
|
|
|
+ MHD_D_OPTION_BOOL_SET_(MHD_D_O_BOOL_SUPPRESS_DATE_HEADER,(bool_val))
|
|
|
+
|
|
|
/**
|
|
|
- * Enable EXCEPT state in @a var
|
|
|
+ * Disable #MHD_action_suspend() functionality.
|
|
|
+ *
|
|
|
+ * You should only use this function if you are sure you do
|
|
|
+ * satisfy all of its requirements and need a generally minor
|
|
|
+ * boost in performance.
|
|
|
+ * @param bool_val the value of the parameter
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_SET_EXCEPT(var) \
|
|
|
- MHD_FD_STATE_SET ((var),MHD_FD_STATE_EXCEPT)
|
|
|
+#define MHD_D_OPTION_DISALLOW_SUSPEND_RESUME(bool_val) \
|
|
|
+ MHD_D_OPTION_BOOL_SET_(MHD_D_O_BOOL_DISALLOW_SUSPEND_RESUME,(bool_val))
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
- * Clear/disable specific @a state in @a var
|
|
|
+ * Set the requested options for the daemon.
|
|
|
+ *
|
|
|
+ * If any option fail other options may be or may be not applied.
|
|
|
+ * @param daemon the daemon to set the options
|
|
|
+ * @param[in] options the pointer to the array with the options;
|
|
|
+ * the array processing stops at the first ::MHD_D_O_END
|
|
|
+ * option, but not later than after processing
|
|
|
+ * @a options_max_num entries
|
|
|
+ * @param options_max_num the maximum number of entries in the @a options,
|
|
|
+ * use MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
|
|
|
+ * must stop only at zero-termination option
|
|
|
+ * @return ::MHD_SC_OK on success,
|
|
|
+ * error code otherwise
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_CLEAR(var,state) \
|
|
|
- (var) = (enum MHD_FdState) ((var) & (((enum MHD_FdState))(~state)))
|
|
|
+MHD_EXTERN_ enum MHD_StatusCode
|
|
|
+MHD_daemon_options_set(struct MHD_Daemon *daemon,
|
|
|
+ const struct MHD_DaemonOptionAndValue *options,
|
|
|
+ size_t options_max_num)
|
|
|
+MHD_FN_PAR_NONNULL_ALL_;
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
- * Clear/disable RECV state in @a var
|
|
|
+ * Set the requested single option for the daemon.
|
|
|
+ *
|
|
|
+ * @param daemon the daemon to set the option
|
|
|
+ * @param[in] options the pointer to the option
|
|
|
+ * @return ::MHD_SC_OK on success,
|
|
|
+ * error code otherwise
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_CLEAR_RECV(var) \
|
|
|
- MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_RECV)
|
|
|
+#define MHD_daemon_option_set(daemon, option_ptr) \
|
|
|
+ MHD_daemon_options_set(daemon, options_ptr, 1)
|
|
|
+
|
|
|
+
|
|
|
+#ifdef MHD_USE_VARARG_MACROS
|
|
|
+MHD_NOWARN_VARIADIC_MACROS_
|
|
|
+# if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_COMP_LIT_FUNC_PARAMS)
|
|
|
/**
|
|
|
- * Clear/disable SEND state in @a var
|
|
|
+ * Set the requested options for the daemon.
|
|
|
+ *
|
|
|
+ * If any option fail other options may be or may be not applied.
|
|
|
+ *
|
|
|
+ * It should be used with helpers that creates required options, for example:
|
|
|
+ *
|
|
|
+ * MHD_DAEMON_OPTIONS_SET(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
|
|
|
+ * MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
|
|
|
+ *
|
|
|
+ * @param daemon the daemon to set the options
|
|
|
+ * @param ... the list of the options, each option must be created
|
|
|
+ * by helpers MHD_DAEMON_OPTION_NameOfOption(option_value)
|
|
|
+ * @return ::MHD_SC_OK on success,
|
|
|
+ * error code otherwise
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_CLEAR_SEND(var) \
|
|
|
- MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_SEND)
|
|
|
+# define MHD_DAEMON_OPTIONS_SET(daemon,...) \
|
|
|
+ MHD_NOWARN_COMPOUND_LITERALS_ \
|
|
|
+ MHD_daemon_options_set(daemon, \
|
|
|
+ ((const struct MHD_DaemonOptionAndValue[]) \
|
|
|
+ {__VA_ARGS__, MHD_D_OPTION_TERMINATE()}), \
|
|
|
+ MHD_OPTIONS_ARRAY_MAX_SIZE) \
|
|
|
+ MHD_RESTORE_WARN_COMPOUND_LITERALS_
|
|
|
+# elif defined(MHD_USE_CPP_INIT_LIST)
|
|
|
+} /* extern "C" */
|
|
|
+# include <vector>
|
|
|
+extern "C"
|
|
|
+{
|
|
|
/**
|
|
|
- * Clear/disable EXCEPT state in @a var
|
|
|
+ * Set the requested options for the daemon.
|
|
|
+ *
|
|
|
+ * If any option fail other options may be or may be not applied.
|
|
|
+ *
|
|
|
+ * It should be used with helpers that creates required options, for example:
|
|
|
+ *
|
|
|
+ * MHD_DAEMON_OPTIONS_SET(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
|
|
|
+ * MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
|
|
|
+ *
|
|
|
+ * @param daemon the daemon to set the options
|
|
|
+ * @param ... the list of the options, each option must be created
|
|
|
+ * by helpers MHD_D_OPTION_NameOfOption(option_value)
|
|
|
+ * @return ::MHD_SC_OK on success,
|
|
|
+ * error code otherwise
|
|
|
*/
|
|
|
-#define MHD_FD_STATE_CLEAR_EXCEPT(var) \
|
|
|
- MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_EXCEPT)
|
|
|
-
|
|
|
+# define MHD_DAEMON_OPTIONS_SET(daemon,...) \
|
|
|
+ MHD_NOWARN_CPP_INIT_LIST_ \
|
|
|
+ MHD_daemon_options_set(daemon, \
|
|
|
+ (std::vector<struct MHD_DaemonOptionAndValue> \
|
|
|
+ {__VA_ARGS__,MHD_D_OPTION_TERMINATE()}).data(), \
|
|
|
+ MHD_OPTIONS_ARRAY_MAX_SIZE) \
|
|
|
+ MHD_RESTORE_WARN_CPP_INIT_LIST_
|
|
|
+# endif
|
|
|
+MHD_RESTORE_WARN_VARIADIC_MACROS_
|
|
|
+#endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
|
|
|
|
|
|
-/* Changes:
|
|
|
- * + status update callback replaced with function
|
|
|
- * + status update accepts array of updates
|
|
|
- */
|
|
|
|
|
|
/**
|
|
|
- * The context data to be used for updates of the socket state
|
|
|
+ * Create parameter for #MHD_daemon_options_set() for work mode with
|
|
|
+ * no internal threads.
|
|
|
+ * The application periodically calls #MHD_daemon_process_blocking(), where
|
|
|
+ * MHD internally checks all sockets automatically.
|
|
|
+ * This is the default mode.
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-struct MHD_EventUpdateContext;
|
|
|
+#define MHD_DAEMON_OPTION_WM_EXTERNAL_PERIODIC() \
|
|
|
+ MHD_DAEMON_OPTION_WORK_MODE(MHD_WM_OPTION_EXTERNAL_PERIODIC())
|
|
|
|
|
|
+/**
|
|
|
+* Create parameter for #MHD_daemon_options_set() for work mode with
|
|
|
+* an external event loop with level triggers.
|
|
|
+* Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
|
|
|
+* sockets polling (like select() or poll()) and #MHD_daemon_event_update().
|
|
|
+* @param cb_val the callback for sockets registration
|
|
|
+* @param cb_cls_val the closure for the @a cv_val callback
|
|
|
+* @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
+*/
|
|
|
+#define MHD_DAEMON_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL(cb_val,cb_cls_val) \
|
|
|
+ MHD_DAEMON_OPTION_WORK_MODE( \
|
|
|
+ MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL((cb_val),(cb_cls_val)))
|
|
|
|
|
|
-/* Define MHD_APP_SOCKET_CNTX_TYPE to the socket context type before
|
|
|
- * including this header.
|
|
|
- * This is optional, but improves the types safety.
|
|
|
- * For example:
|
|
|
- * #define MHD_APP_SOCKET_CNTX_TYPE struct my_structure
|
|
|
+/**
|
|
|
+ * Create parameter for #MHD_daemon_options_set() for work mode with
|
|
|
+ * an external event loop with edge triggers.
|
|
|
+ * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
|
|
|
+ * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
|
|
|
+ * @param cb_val the callback for sockets registration
|
|
|
+ * @param cb_cls_val the closure for the @a cv_val callback
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-#ifndef MHD_APP_SOCKET_CNTX_TYPE
|
|
|
-# define MHD_APP_SOCKET_CNTX_TYPE void
|
|
|
-#endif
|
|
|
+#define MHD_DAEMON_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE(cb_val,cb_cls_val) \
|
|
|
+ MHD_DAEMON_OPTION_WORK_MODE( \
|
|
|
+ MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE((cb_val),(cb_cls_val)))
|
|
|
|
|
|
/**
|
|
|
- * The callback for registration/de-registration of the sockets to watch.
|
|
|
- *
|
|
|
- * This callback must not call #MHD_daemon_destroy(), #MHD_daemon_quiesce(),
|
|
|
- * #MHD_daemon_add_connection().
|
|
|
- *
|
|
|
- * @param cls the closure
|
|
|
- * @param fd the socket to watch
|
|
|
- * @param watch_for the states of the @a fd to watch, if set to
|
|
|
- * #MHD_FD_STATE_NONE the socket must be de-registred
|
|
|
- * @param app_cntx_old the old application defined context for the socket,
|
|
|
- * NULL if @a fd socket was not registered before
|
|
|
- * @param ecb_cntx the context handle to be used
|
|
|
- * with #MHD_daemon_event_update()
|
|
|
- * @return NULL if error (to connection will be closed),
|
|
|
- * or the new socket context
|
|
|
- * @ingroup event
|
|
|
+ * Create parameter for #MHD_daemon_options_set() for work mode with
|
|
|
+ * no internal threads and aggregate watch FD.
|
|
|
+ * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
|
|
|
+ * that gets triggered by any MHD event.
|
|
|
+ * This FD can be watched as an aggregate indicator for all MHD events.
|
|
|
+ * This mode is available only on selected platforms (currently
|
|
|
+ * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
|
|
|
+ * When the FD is triggered, #MHD_daemon_process_nonblocking() should
|
|
|
+ * be called.
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-typedef MHD_APP_SOCKET_CNTX_TYPE *
|
|
|
-(MHD_FN_PAR_NONNULL_(5)
|
|
|
- *MHD_SocketRegistrationUpdateCallback)(
|
|
|
- void *cls,
|
|
|
- MHD_socket fd,
|
|
|
- enum MHD_FdState watch_for,
|
|
|
- MHD_APP_SOCKET_CNTX_TYPE *app_cntx_old,
|
|
|
- struct MHD_EventUpdateContext *ecb_cntx);
|
|
|
-
|
|
|
+#define MHD_DAEMON_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH() \
|
|
|
+ MHD_DAEMON_OPTION_WORK_MODE(MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH())
|
|
|
|
|
|
/**
|
|
|
- * Update the sockets state.
|
|
|
- * Must be called for every socket that got state updated.
|
|
|
- * For #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL mode should be called for each
|
|
|
- * socket.
|
|
|
- * Available only for daemons stated in #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
|
|
|
- * #MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
|
|
|
- * @param daemon the daemon handle
|
|
|
- * @param ecb_cntx the context handle provided
|
|
|
- * for #MHD_SocketRegistrationUpdateCallback
|
|
|
- * @param fd_current_state the current state of the socket
|
|
|
+ * Create parameter for #MHD_daemon_options_set() for work mode with
|
|
|
+ * one or more worker threads.
|
|
|
+ * If number of threads is one, then daemon starts with single worker thread
|
|
|
+ * that handles all connections.
|
|
|
+ * If number of threads is larger than one, then that number of worker threads,
|
|
|
+ * and handling of connection is distributed among the workers.
|
|
|
+ * @param num_workers the number of worker threads, zero is treated as one
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-MHD_EXTERN_ void
|
|
|
-MHD_daemon_event_update (
|
|
|
- struct MHD_Daemon *daemon,
|
|
|
- struct MHD_EventUpdateContext *ecb_cntx,
|
|
|
- enum MHD_FdState fd_current_state)
|
|
|
-MHD_FN_PAR_NONNULL_(1) MHD_FN_PAR_NONNULL_(2);
|
|
|
-
|
|
|
+#define MHD_DAEMON_OPTION_WORKER_THREADS(num_workers) \
|
|
|
+ MHD_DAEMON_OPTION_WORK_MODE(MHD_WM_OPTION_WORKER_THREADS(num_workers))
|
|
|
|
|
|
/**
|
|
|
- * Perform sockets registration, process registered network events.
|
|
|
- *
|
|
|
- * This function first processes all registered (by MHD_daemon_event_update())
|
|
|
- * network events (if any) and then calls #MHD_SocketRegistrationUpdateCallback
|
|
|
- * callback for every socket that needs to be added/updated/removed.
|
|
|
- *
|
|
|
- * Available only for daemons stated in #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
|
|
|
- * #MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
|
|
|
- *
|
|
|
- * @param daemon the daemon handle
|
|
|
- * @param[out] next_max_wait the optional pointer to receive the next maximum
|
|
|
- * wait time in microseconds to be used for sockets
|
|
|
- * polling function, can be NULL
|
|
|
- * @return MHD_SC_OK on success,
|
|
|
- * error code otherwise
|
|
|
+ * Create parameter for #MHD_daemon_options_set() for work mode with
|
|
|
+ * one internal thread for listening and additional threads per every
|
|
|
+ * connection. Use this if handling requests is CPU-intensive or blocking,
|
|
|
+ * your application is thread-safe and you have plenty of memory (per
|
|
|
+ * connection).
|
|
|
+ * @return the object of struct MHD_DaemonOptionAndValue with requested values
|
|
|
*/
|
|
|
-MHD_EXTERN_ enum MHD_StatusCode
|
|
|
-MHD_deamon_process_reg_events(struct MHD_Daemon *daemon,
|
|
|
- uint_fast64_t *next_max_wait)
|
|
|
-MHD_FN_PAR_NONNULL_(1);
|
|
|
+#define MHD_DAEMON_OPTION_THREAD_PER_CONNECTION() \
|
|
|
+ MHD_DAEMON_OPTION_WORK_MODE(MHD_WM_OPTION_THREAD_PER_CONNECTION())
|
|
|
+
|
|
|
+
|
|
|
+/* ******************* Event loop ************************ */
|
|
|
|
|
|
|
|
|
/**
|