commit 9914072c16b773a828709ecc61062c37c864e858
parent bca7a709f8129e856d9175ea1081abc0feec883c
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 15 Feb 2018 04:04:22 +0100
add explicit nonnull declarations to function arguments
Diffstat:
7 files changed, 525 insertions(+), 84 deletions(-)
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
@@ -267,6 +267,16 @@ typedef SOCKET MHD_socket;
#define _MHD_DEPR_FUNC(msg)
#endif /* !_MHD_DEPR_FUNC */
+
+/* Define MHD_NONNULL attribute */
+
+/**
+ * Macro to indicate that certain parameters must be
+ * non-null. Todo: port to non-gcc platforms.
+ */
+#define MHD_NONNULL(...) __THROW __nonnull((__VA_ARGS__))
+
+
/**
* Not all architectures and `printf()`'s support the `long long` type.
* This gives the ability to replace `long long` with just a `long`,
@@ -541,6 +551,17 @@ enum MHD_StatusCode
*/
MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED = 50035,
+ /**
+ * We failed to build the FD set because a socket was
+ * outside of the permitted range.
+ */
+ MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE = 50036,
+
+ /**
+ * This daemon was not configured with options that
+ * would allow us to build an FD set for select().
+ */
+ MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_FDSET = 50037,
};
@@ -1148,7 +1169,8 @@ typedef struct MHD_Action *
*/
_MHD_EXTERN struct MHD_Daemon *
MHD_daemon_create (MHD_RequestCallback cb,
- void *cb_cls);
+ void *cb_cls)
+ MHD_NONNULL(1);
/**
@@ -1160,7 +1182,8 @@ MHD_daemon_create (MHD_RequestCallback cb,
* @ingroup event
*/
_MHD_EXTERN enum MHD_StatusCode
-MHD_daemon_start (struct MHD_Daemon *daemon);
+MHD_daemon_start (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1184,7 +1207,8 @@ MHD_daemon_start (struct MHD_Daemon *daemon);
* @ingroup specialized
*/
_MHD_EXTERN MHD_socket
-MHD_daemon_quiesce (struct MHD_Daemon *daemon);
+MHD_daemon_quiesce (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1194,7 +1218,8 @@ MHD_daemon_quiesce (struct MHD_Daemon *daemon);
* @ingroup event
*/
_MHD_EXTERN void
-MHD_daemon_destroy (struct MHD_Daemon *daemon);
+MHD_daemon_destroy (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1226,7 +1251,8 @@ _MHD_EXTERN enum MHD_StatusCode
MHD_daemon_add_connection (struct MHD_Daemon *daemon,
MHD_socket client_socket,
const struct sockaddr *addr,
- socklen_t addrlen);
+ socklen_t addrlen)
+ MHD_NONNULL(1);
/**
@@ -1258,7 +1284,8 @@ MHD_daemon_get_fdset (struct MHD_Daemon *daemon,
fd_set *read_fd_set,
fd_set *write_fd_set,
fd_set *except_fd_set,
- MHD_socket *max_fd);
+ MHD_socket *max_fd)
+ MHD_NONNULL(1,2,3,4);
/**
@@ -1294,7 +1321,8 @@ MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
fd_set *write_fd_set,
fd_set *except_fd_set,
MHD_socket *max_fd,
- unsigned int fd_setsize);
+ unsigned int fd_setsize)
+ MHD_NONNULL(1,2,3,4);
/**
@@ -1344,7 +1372,8 @@ MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN enum MHD_StatusCode
MHD_daemon_get_timeout (struct MHD_Daemon *daemon,
- MHD_UNSIGNED_LONG_LONG *timeout);
+ MHD_UNSIGNED_LONG_LONG *timeout)
+ MHD_NONNULL(1,2);
/**
@@ -1366,7 +1395,8 @@ MHD_daemon_get_timeout (struct MHD_Daemon *daemon,
* @ingroup event
*/
_MHD_EXTERN enum MHD_StatusCode
-MHD_daemon_run (struct MHD_Daemon *daemon);
+MHD_daemon_run (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1395,9 +1425,8 @@ _MHD_EXTERN enum MHD_StatusCode
MHD_daemon_run_from_select (struct MHD_Daemon *daemon,
const fd_set *read_fd_set,
const fd_set *write_fd_set,
- const fd_set *except_fd_set);
-
-
+ const fd_set *except_fd_set)
+ MHD_NONNULL(1,2,3,4);
/* ********************* daemon options ************** */
@@ -1431,7 +1460,8 @@ typedef void
_MHD_EXTERN void
MHD_daemon_set_logger (struct MHD_Daemon *daemon,
MHD_LoggingCallback logger,
- void *logger_cls);
+ void *logger_cls)
+ MHD_NONNULL(1);
/**
@@ -1448,7 +1478,8 @@ MHD_daemon_set_logger (struct MHD_Daemon *daemon,
* @param daemon which instance to disable clock for.
*/
_MHD_EXTERN void
-MHD_daemon_suppress_date_no_clock (struct MHD_Daemon *daemon);
+MHD_daemon_suppress_date_no_clock (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1469,7 +1500,8 @@ MHD_daemon_suppress_date_no_clock (struct MHD_Daemon *daemon);
* @param daemon which instance to disable itc for
*/
_MHD_EXTERN void
-MHD_daemon_disable_itc (struct MHD_Daemon *daemon);
+MHD_daemon_disable_itc (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1481,7 +1513,8 @@ MHD_daemon_disable_itc (struct MHD_Daemon *daemon);
* @param daemon which instance to enable turbo for
*/
_MHD_EXTERN void
-MHD_daemon_enable_turbo (struct MHD_Daemon *daemon);
+MHD_daemon_enable_turbo (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1494,7 +1527,8 @@ MHD_daemon_enable_turbo (struct MHD_Daemon *daemon);
* @param daemon which instance to disable suspend for
*/
_MHD_EXTERN void
-MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon);
+MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1509,7 +1543,8 @@ MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon);
* @param daemon which instance to enable suspend/resume for
*/
_MHD_EXTERN void
-MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon);
+MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1555,7 +1590,8 @@ enum MHD_FastOpenMethod
_MHD_EXTERN enum MHD_Bool
MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
enum MHD_FastOpenMethod fom,
- unsigned int queue_length);
+ unsigned int queue_length)
+ MHD_NONNULL(1);
/**
@@ -1608,7 +1644,8 @@ enum MHD_AddressFamily
_MHD_EXTERN void
MHD_daemon_bind_port (struct MHD_Daemon *daemon,
enum MHD_AddressFamily af,
- uint16_t port);
+ uint16_t port)
+ MHD_NONNULL(1);
/**
@@ -1623,7 +1660,8 @@ MHD_daemon_bind_port (struct MHD_Daemon *daemon,
_MHD_EXTERN void
MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
const struct sockaddr *sa,
- size_t sa_len);
+ size_t sa_len)
+ MHD_NONNULL(1);
/**
@@ -1635,7 +1673,8 @@ MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN void
MHD_daemon_listen_backlog (struct MHD_Daemon *daemon,
- int listen_backlog);
+ int listen_backlog)
+ MHD_NONNULL(1);
/**
@@ -1649,7 +1688,8 @@ MHD_daemon_listen_backlog (struct MHD_Daemon *daemon,
* @param daemon daemon to configure address reuse for
*/
_MHD_EXTERN void
-MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon);
+MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1668,7 +1708,8 @@ MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon);
*/
_MHD_EXTERN void
MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
- MHD_socket listen_socket);
+ MHD_socket listen_socket)
+ MHD_NONNULL(1);
/**
@@ -1708,7 +1749,8 @@ enum MHD_EventLoopSyscall
*/
_MHD_EXTERN enum MHD_Bool
MHD_daemon_event_loop (struct MHD_Daemon *daemon,
- enum MHD_EventLoopSyscall els);
+ enum MHD_EventLoopSyscall els)
+ MHD_NONNULL(1);
/**
@@ -1752,7 +1794,8 @@ enum MHD_ProtocolStrictLevel
*/
_MHD_EXTERN void
MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
- enum MHD_ProtocolStrictLevel sl);
+ enum MHD_ProtocolStrictLevel sl)
+ MHD_NONNULL(1);
/**
@@ -1762,7 +1805,8 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
* @param daemon daemon to set SHOUTcast option for
*/
_MHD_EXTERN void
-MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon);
+MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon)
+ MHD_NONNULL(1);
/**
@@ -1783,7 +1827,8 @@ MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon);
_MHD_EXTERN enum MHD_StatusCode
MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
const char *tls_backend,
- const char *ciphers);
+ const char *ciphers)
+ MHD_NONNULL(1);
/**
@@ -1802,7 +1847,8 @@ _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);
+ const char *pass)
+ MHD_NONNULL(1,2,3);
/**
@@ -1815,7 +1861,8 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN enum MHD_StatusCode
MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
- const char *dh);
+ const char *dh)
+ MHD_NONNULL(1);
/**
@@ -1828,7 +1875,8 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN enum MHD_StatusCode
MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
- const char *mem_trust);
+ const char *mem_trust)
+ MHD_NONNULL(1);
/**
@@ -1840,7 +1888,8 @@ MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN enum MHD_StatusCode
MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
- int gnutls_credentials);
+ int gnutls_credentials)
+ MHD_NONNULL(1);
/**
@@ -1862,7 +1911,8 @@ MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN enum MHD_StatusCode
MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
- void *cb);
+ void *cb)
+ MHD_NONNULL(1);
/**
@@ -1920,7 +1970,8 @@ enum MHD_ThreadingModel
*/
_MHD_EXTERN void
MHD_daemon_threading_model (struct MHD_Daemon *daemon,
- enum MHD_ThreadingModel tm);
+ enum MHD_ThreadingModel tm)
+ MHD_NONNULL(1);
/**
@@ -1950,7 +2001,8 @@ typedef enum MHD_Bool
_MHD_EXTERN void
MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
MHD_AcceptPolicyCallback apc,
- void *apc_cls);
+ void *apc_cls)
+ MHD_NONNULL(1);
/**
@@ -1981,7 +2033,8 @@ typedef void *
_MHD_EXTERN void
MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
MHD_EarlyUriLogCallback cb,
- void *cb_cls);
+ void *cb_cls)
+ MHD_NONNULL(1);
/**
@@ -2043,7 +2096,8 @@ typedef void
_MHD_EXTERN void
MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
MHD_NotifyConnectionCallback ncc,
- void *ncc_cls);
+ void *ncc_cls)
+ MHD_NONNULL(1);
/**
@@ -2060,7 +2114,8 @@ MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
_MHD_EXTERN void
MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon,
size_t memory_limit_b,
- size_t memory_increment_b);
+ size_t memory_increment_b)
+ MHD_NONNULL(1);
/**
@@ -2073,7 +2128,8 @@ MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN void
MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon,
- size_t stack_limit_b);
+ size_t stack_limit_b)
+ MHD_NONNULL(1);
/**
@@ -2094,7 +2150,8 @@ MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon,
_MHD_EXTERN void
MHD_daemon_connection_limits (struct MHD_Daemon *daemon,
unsigned int global_connection_limit,
- unsigned int ip_connection_limit);
+ unsigned int ip_connection_limit)
+ MHD_NONNULL(1);
/**
@@ -2107,7 +2164,8 @@ MHD_daemon_connection_limits (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN void
MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon,
- unsigned int timeout_s);
+ unsigned int timeout_s)
+ MHD_NONNULL(1);
/**
@@ -2142,7 +2200,8 @@ typedef size_t
_MHD_EXTERN void
MHD_daemon_unescape_cb (struct MHD_Daemon *daemon,
MHD_UnescapeCallback unescape_cb,
- void *unescape_cb_cls);
+ void *unescape_cb_cls)
+ MHD_NONNULL(1);
/**
@@ -2157,7 +2216,8 @@ MHD_daemon_unescape_cb (struct MHD_Daemon *daemon,
_MHD_EXTERN void
MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
size_t buf_size,
- const void *buf);
+ const void *buf)
+ MHD_NONNULL(1,3);
/**
@@ -2169,7 +2229,8 @@ MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN enum MHD_StatusCode
MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
- size_t nc_length);
+ size_t nc_length)
+ MHD_NONNULL(1);
/* ********************* connection options ************** */
@@ -2185,7 +2246,8 @@ MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
*/
_MHD_EXTERN void
MHD_connection_set_timeout (struct MHD_Connection *connection,
- unsigned int timeout_s);
+ unsigned int timeout_s)
+ MHD_NONNULL(1);
/* **************** Request handling functions ***************** */
@@ -2268,7 +2330,8 @@ _MHD_EXTERN unsigned int
MHD_request_get_values (struct MHD_Request *request,
enum MHD_ValueKind kind,
MHD_KeyValueIterator iterator,
- void *iterator_cls);
+ void *iterator_cls)
+ MHD_NONNULL(1);
/**
@@ -2300,7 +2363,8 @@ _MHD_EXTERN enum MHD_Bool
MHD_request_set_value (struct MHD_Request *request,
enum MHD_ValueKind kind,
const char *key,
- const char *value);
+ const char *value)
+ MHD_NONNULL(1,3,4);
/**
@@ -2316,7 +2380,8 @@ MHD_request_set_value (struct MHD_Request *request,
_MHD_EXTERN const char *
MHD_request_lookup_value (struct MHD_Request *request,
enum MHD_ValueKind kind,
- const char *key);
+ const char *key)
+ MHD_NONNULL(1);
@@ -2487,7 +2552,8 @@ MHD_action_suspend (void);
* @param request the request to resume
*/
_MHD_EXTERN void
-MHD_request_resume (struct MHD_Request *request);
+MHD_request_resume (struct MHD_Request *request)
+ MHD_NONNULL(1);
/* **************** Response manipulation functions ***************** */
@@ -2520,7 +2586,8 @@ struct MHD_Response;
*/
_MHD_EXTERN struct MHD_Action *
MHD_action_from_response (struct MHD_Response *response,
- enum MHD_Bool destroy_after_use);
+ enum MHD_Bool destroy_after_use)
+ MHD_NONNULL(1);
/**
@@ -2531,7 +2598,8 @@ MHD_action_from_response (struct MHD_Response *response,
* @param request the request for which we force HTTP 1.0 to be used
*/
_MHD_EXTERN void
-MHD_response_option_v10_only (struct MHD_Response *response);
+MHD_response_option_v10_only (struct MHD_Response *response)
+ MHD_NONNULL(1);
/**
@@ -2620,7 +2688,8 @@ typedef void
_MHD_EXTERN void
MHD_response_option_termination_callback (struct MHD_Response *response,
MHD_RequestTerminationCallback termination_cb,
- void *termination_cb_cls);
+ void *termination_cb_cls)
+ MHD_NONNULL(1);
/**
@@ -2837,7 +2906,8 @@ struct MHD_UpgradeResponseHandle;
_MHD_EXTERN enum MHD_Bool
MHD_upgrade_operation (struct MHD_UpgradeResponseHandle *urh,
enum MHD_UpgradeOperation operation,
- ...);
+ ...)
+ MHD_NONNULL(1);
/**
@@ -2929,7 +2999,8 @@ typedef void
*/
_MHD_EXTERN struct MHD_Response *
MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
- void *upgrade_handler_cls);
+ void *upgrade_handler_cls)
+ MHD_NONNULL(1);
/**
@@ -2942,7 +3013,8 @@ MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
* @ingroup response
*/
_MHD_EXTERN void
-MHD_response_queue_for_destroy (struct MHD_Response *response);
+MHD_response_queue_for_destroy (struct MHD_Response *response)
+ MHD_NONNULL(1);
/**
@@ -2958,7 +3030,8 @@ MHD_response_queue_for_destroy (struct MHD_Response *response);
_MHD_EXTERN enum MHD_Bool
MHD_response_add_header (struct MHD_Response *response,
const char *header,
- const char *content);
+ const char *content)
+ MHD_NONNULL(1,2,3);
/**
@@ -2974,7 +3047,8 @@ MHD_response_add_header (struct MHD_Response *response,
_MHD_EXTERN enum MHD_Bool
MHD_response_add_trailer (struct MHD_Response *response,
const char *footer,
- const char *content);
+ const char *content)
+ MHD_NONNULL(1,2,3);
/**
@@ -2989,7 +3063,8 @@ MHD_response_add_trailer (struct MHD_Response *response,
_MHD_EXTERN enum MHD_Bool
MHD_response_del_header (struct MHD_Response *response,
const char *header,
- const char *content);
+ const char *content)
+ MHD_NONNULL(1,2,3);
/**
@@ -3005,7 +3080,8 @@ MHD_response_del_header (struct MHD_Response *response,
_MHD_EXTERN unsigned int
MHD_response_get_headers (struct MHD_Response *response,
MHD_KeyValueIterator iterator,
- void *iterator_cls);
+ void *iterator_cls)
+ MHD_NONNULL(1);
/**
@@ -3018,7 +3094,8 @@ MHD_response_get_headers (struct MHD_Response *response,
*/
_MHD_EXTERN const char *
MHD_response_get_header (struct MHD_Response *response,
- const char *key);
+ const char *key)
+ MHD_NONNULL(1,2);
/* ************Upload and PostProcessor functions ********************** */
@@ -3067,7 +3144,8 @@ typedef struct MHD_Action *
*/
_MHD_EXTERN struct MHD_Action *
MHD_action_process_upload (MHD_UploadCallback uc,
- void *uc_cls);
+ void *uc_cls)
+ MHD_NONNULL(1);
/**
@@ -3132,7 +3210,8 @@ typedef struct MHD_Action *
_MHD_EXTERN struct MHD_Action *
MHD_action_parse_post (size_t buffer_size,
MHD_PostDataIterator iter,
- void *iter_cls);
+ void *iter_cls)
+ MHD_NONNULL(2);
@@ -3303,7 +3382,8 @@ _MHD_EXTERN enum MHD_Bool
MHD_connection_get_information_sz (struct MHD_Connection *connection,
enum MHD_ConnectionInformationType info_type,
union MHD_ConnectionInformation *return_value,
- size_t return_value_size);
+ size_t return_value_size)
+ MHD_NONNULL(1,3);
/**
@@ -3415,7 +3495,8 @@ _MHD_EXTERN enum MHD_Bool
MHD_request_get_information_sz (struct MHD_Request *request,
enum MHD_RequestInformationType info_type,
union MHD_RequestInformation *return_value,
- size_t return_value_size);
+ size_t return_value_size)
+ MHD_NONNULL(1,3);
/**
@@ -3521,7 +3602,8 @@ _MHD_EXTERN enum MHD_Bool
MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
enum MHD_DaemonInformationType info_type,
union MHD_DaemonInformation *return_value,
- size_t return_value_size);
+ size_t return_value_size)
+ MHD_NONNULL(1,3);
/**
* Obtain information about the given daemon.
@@ -3588,7 +3670,8 @@ MHD_set_panic_func (MHD_PanicCallback cb,
* shorter afterwards due to elimination of escape sequences)
*/
_MHD_EXTERN size_t
-MHD_http_unescape (char *val);
+MHD_http_unescape (char *val)
+ MHD_NONNULL(1);
/**
diff --git a/src/lib/daemon_create.c b/src/lib/daemon_create.c
@@ -89,8 +89,6 @@ MHD_daemon_create (MHD_RequestCallback cb,
struct MHD_Daemon *daemon;
MHD_check_global_init_();
- if (NULL == cb)
- return NULL;
if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
return NULL;
memset (daemon,
diff --git a/src/lib/daemon_destroy.c b/src/lib/daemon_destroy.c
@@ -93,8 +93,6 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
{
MHD_socket fd;
- if (NULL == daemon)
- return;
daemon->shutdown = true;
if (daemon->was_quiesced)
fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
diff --git a/src/lib/daemon_get_fdset.c b/src/lib/daemon_get_fdset.c
@@ -62,7 +62,142 @@ MHD_daemon_get_fdset (struct MHD_Daemon *daemon,
fd_set *except_fd_set,
MHD_socket *max_fd)
{
- return -1;
+ return MHD_daemon_get_fdset2 (daemon,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ _MHD_SYS_DEFAULT_FD_SETSIZE);
+}
+
+
+/**
+ * Internal version of #MHD_daemon_get_fdset2().
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @param fd_setsize value of FD_SETSIZE
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+static enum MHD_StatusCode
+internal_get_fdset2 (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
+
+{
+ struct MHD_Connection *pos;
+ struct MHD_Connection *posn;
+ int result = MHD_YES;
+ MHD_socket ls;
+
+ if (daemon->shutdown)
+ return MHD_NO;
+
+ ls = daemon->listen_socket;
+ if ( (MHD_INVALID_SOCKET != ls) &&
+ (! daemon->was_quiesced) &&
+ (! MHD_add_to_fd_set_ (ls,
+ read_fd_set,
+ max_fd,
+ fd_setsize)) )
+ result = MHD_NO;
+
+ /* Add all sockets to 'except_fd_set' as well to watch for
+ * out-of-band data. However, ignore errors if INFO_READ
+ * or INFO_WRITE sockets will not fit 'except_fd_set'. */
+ /* Start from oldest connections. Make sense for W32 FDSETs. */
+ for (pos = daemon->connections_tail; NULL != pos; pos = posn)
+ {
+ posn = pos->prev;
+
+ switch (pos->request.event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ if (! MHD_add_to_fd_set_ (pos->socket_fd,
+ read_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
+#ifdef MHD_POSIX_SOCKETS
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+#endif /* MHD_POSIX_SOCKETS */
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ if (! MHD_add_to_fd_set_ (pos->socket_fd,
+ write_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
+#ifdef MHD_POSIX_SOCKETS
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+#endif /* MHD_POSIX_SOCKETS */
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ if ( (NULL == except_fd_set) ||
+ ! MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* this should never happen */
+ break;
+ }
+ }
+#ifdef MHD_WINSOCK_SOCKETS
+ /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
+ * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
+ * not be pushed out. */
+ for (pos = daemon->connections_tail; NULL != pos; pos = posn)
+ {
+ posn = pos->prev;
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+ }
+#endif /* MHD_WINSOCK_SOCKETS */
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ {
+ struct MHD_UpgradeResponseHandle *urh;
+
+ for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
+ {
+ if (MHD_NO ==
+ urh_to_fdset (urh,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
+ }
+ }
+#endif
+#if DEBUG_CONNECT
+#ifdef HAVE_MESSAGES
+ if (NULL != max_fd)
+ MHD_DLOG (daemon,
+ _("Maximum socket in select set: %d\n"),
+ *max_fd);
+#endif
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ return result;
}
@@ -101,7 +236,34 @@ MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
MHD_socket *max_fd,
unsigned int fd_setsize)
{
- return -1;
+ if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model) ||
+ (MHD_ELS_POLL == daemon->event_loop_syscall) )
+ return MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_FDSET;
+
+#ifdef EPOLL_SUPPORT
+ if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
+ {
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+
+ /* we're in epoll mode, use the epoll FD as a stand-in for
+ the entire event set */
+
+ return MHD_add_to_fd_set_ (daemon->epoll_fd,
+ read_fd_set,
+ max_fd,
+ fd_setsize)
+ ? MHD_SC_OK
+ : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+ }
+#endif
+
+ return internal_get_fdset2 (daemon,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
}
/* end of daemon_get_fdset.c */
diff --git a/src/lib/internal.h b/src/lib/internal.h
@@ -826,6 +826,202 @@ struct MHD_Connection
};
+#ifdef UPGRADE_SUPPORT
+/**
+ * Buffer we use for upgrade response handling in the unlikely
+ * case where the memory pool was so small it had no buffer
+ * capacity left. Note that we don't expect to _ever_ use this
+ * buffer, so it's mostly wasted memory (except that it allows
+ * us to handle a tricky error condition nicely). So no need to
+ * make this one big. Applications that want to perform well
+ * should just pick an adequate size for the memory pools.
+ */
+#define RESERVE_EBUF_SIZE 8
+
+/**
+ * Context we pass to epoll() for each of the two sockets
+ * of a `struct MHD_UpgradeResponseHandle`. We need to do
+ * this so we can distinguish the two sockets when epoll()
+ * gives us event notifications.
+ */
+struct UpgradeEpollHandle
+{
+ /**
+ * Reference to the overall response handle this struct is
+ * included within.
+ */
+ struct MHD_UpgradeResponseHandle *urh;
+
+ /**
+ * The socket this event is kind-of about. Note that this is NOT
+ * necessarily the socket we are polling on, as for when we read
+ * from TLS, we epoll() on the connection's socket
+ * (`urh->connection->socket_fd`), while this then the application's
+ * socket (where the application will read from). Nevertheless, for
+ * the application to read, we need to first read from TLS, hence
+ * the two are related.
+ *
+ * Similarly, for writing to TLS, this epoll() will be on the
+ * connection's `socket_fd`, and this will merely be the FD which
+ * the applicatio would write to. Hence this struct must always be
+ * interpreted based on which field in `struct
+ * MHD_UpgradeResponseHandle` it is (`app` or `mhd`).
+ */
+ MHD_socket socket;
+
+ /**
+ * IO-state of the @e socket (or the connection's `socket_fd`).
+ */
+ enum MHD_EpollState celi;
+
+};
+
+
+/**
+ * Handle given to the application to manage special
+ * actions relating to MHD responses that "upgrade"
+ * the HTTP protocol (i.e. to WebSockets).
+ */
+struct MHD_UpgradeResponseHandle
+{
+ /**
+ * The connection for which this is an upgrade handle. Note that
+ * because a response may be shared over many connections, this may
+ * not be the only upgrade handle for the response of this connection.
+ */
+ struct MHD_Connection *connection;
+
+#ifdef HTTPS_SUPPORT
+ /**
+ * Kept in a DLL per daemon.
+ */
+ struct MHD_UpgradeResponseHandle *next;
+
+ /**
+ * Kept in a DLL per daemon.
+ */
+ struct MHD_UpgradeResponseHandle *prev;
+
+#ifdef EPOLL_SUPPORT
+ /**
+ * Next pointer for the EDLL listing urhs that are epoll-ready.
+ */
+ struct MHD_UpgradeResponseHandle *nextE;
+
+ /**
+ * Previous pointer for the EDLL listing urhs that are epoll-ready.
+ */
+ struct MHD_UpgradeResponseHandle *prevE;
+
+ /**
+ * Specifies whether urh already in EDLL list of ready connections.
+ */
+ bool in_eready_list;
+#endif
+
+ /**
+ * The buffer for receiving data from TLS to
+ * be passed to the application. Contains @e in_buffer_size
+ * bytes (unless @e in_buffer_size is zero). Do not free!
+ */
+ char *in_buffer;
+
+ /**
+ * The buffer for receiving data from the application to
+ * be passed to TLS. Contains @e out_buffer_size
+ * bytes (unless @e out_buffer_size is zero). Do not free!
+ */
+ char *out_buffer;
+
+ /**
+ * Size of the @e in_buffer.
+ * Set to 0 if the TLS connection went down for reading or socketpair
+ * went down for writing.
+ */
+ size_t in_buffer_size;
+
+ /**
+ * Size of the @e out_buffer.
+ * Set to 0 if the TLS connection went down for writing or socketpair
+ * went down for reading.
+ */
+ size_t out_buffer_size;
+
+ /**
+ * Number of bytes actually in use in the @e in_buffer. Can be larger
+ * than @e in_buffer_size if and only if @a in_buffer_size is zero and
+ * we still have bytes that can be forwarded.
+ * Reset to zero if all data was forwarded to socketpair or
+ * if socketpair went down for writing.
+ */
+ size_t in_buffer_used;
+
+ /**
+ * Number of bytes actually in use in the @e out_buffer. Can be larger
+ * than @e out_buffer_size if and only if @a out_buffer_size is zero and
+ * we still have bytes that can be forwarded.
+ * Reset to zero if all data was forwarded to TLS connection or
+ * if TLS connection went down for writing.
+ */
+ size_t out_buffer_used;
+
+ /**
+ * The socket we gave to the application (r/w).
+ */
+ struct UpgradeEpollHandle app;
+
+ /**
+ * If @a app_sock was a socketpair, our end of it, otherwise
+ * #MHD_INVALID_SOCKET; (r/w).
+ */
+ struct UpgradeEpollHandle mhd;
+
+ /**
+ * Emergency IO buffer we use in case the memory pool has literally
+ * nothing left.
+ */
+ char e_buf[RESERVE_EBUF_SIZE];
+
+#endif /* HTTPS_SUPPORT */
+
+ /**
+ * Set to true after the application finished with the socket
+ * by #MHD_UPGRADE_ACTION_CLOSE.
+ *
+ * When BOTH @e was_closed (changed by command from application)
+ * AND @e clean_ready (changed internally by MHD) are set to
+ * #MHD_YES, function #MHD_resume_connection() will move this
+ * connection to cleanup list.
+ * @remark This flag could be changed from any thread.
+ */
+ volatile bool was_closed;
+
+ /**
+ * Set to true if connection is ready for cleanup.
+ *
+ * In TLS mode functions #MHD_connection_finish_forward_() must
+ * be called before setting this flag to true.
+ *
+ * In thread-per-connection mode, true in this flag means
+ * that connection's thread exited or about to exit and will
+ * not use MHD_Connection::urh data anymore.
+ *
+ * In any mode true in this flag also means that
+ * MHD_Connection::urh data will not be used for socketpair
+ * forwarding and forwarding itself is finished.
+ *
+ * When BOTH @e was_closed (changed by command from application)
+ * AND @e clean_ready (changed internally by MHD) are set to
+ * true, function #MHD_resume_connection() will move this
+ * connection to cleanup list.
+ * @remark This flag could be changed from thread that process
+ * connection's recv(), send() and response.
+ */
+ bool clean_ready;
+};
+#endif /* UPGRADE_SUPPORT */
+
+
/**
* State kept for each MHD daemon. All connections are kept in two
* doubly-linked lists. The first one reflects the state of the
@@ -910,6 +1106,22 @@ struct MHD_Daemon
#if HTTPS_SUPPORT
+#ifdef UPGRADE_SUPPORT
+ /**
+ * Head of DLL of upgrade response handles we are processing.
+ * Used for upgraded TLS connections when thread-per-connection
+ * is not used.
+ */
+ struct MHD_UpgradeResponseHandle *urh_head;
+
+ /**
+ * Tail of DLL of upgrade response handles we are processing.
+ * Used for upgraded TLS connections when thread-per-connection
+ * is not used.
+ */
+ struct MHD_UpgradeResponseHandle *urh_tail;
+#endif /* UPGRADE_SUPPORT */
+
/**
* Which TLS backend should be used. NULL for no TLS.
* This is merely the handle to the dlsym() object, not
@@ -1012,13 +1224,10 @@ struct MHD_Daemon
*/
struct MHD_Connection *eready_tail;
-#ifdef EPOLL_SUPPORT
/**
* Pointer to marker used to indicate ITC slot in epoll sets.
*/
const char *epoll_itc_marker;
-#endif
-
#ifdef UPGRADE_SUPPORT
/**
* Head of EDLL of upgraded connections ready for processing (in epoll mode).
diff --git a/src/lib/request.c b/src/lib/request.c
@@ -47,8 +47,6 @@ MHD_request_get_values (struct MHD_Request *request,
int ret;
struct MHD_HTTP_Header *pos;
- if (NULL == request)
- return -1;
ret = 0;
for (pos = request->headers_received;
NULL != pos;
@@ -143,8 +141,6 @@ MHD_request_lookup_value (struct MHD_Request *request,
{
struct MHD_HTTP_Header *pos;
- if (NULL == request)
- return NULL;
for (pos = request->headers_received;
NULL != pos;
pos = pos->next)
diff --git a/src/lib/response.c b/src/lib/response.c
@@ -172,9 +172,6 @@ MHD_response_del_header (struct MHD_Response *response,
struct MHD_HTTP_Header *pos;
struct MHD_HTTP_Header *prev;
- if ( (NULL == header) ||
- (NULL == content) )
- return MHD_NO;
prev = NULL;
pos = response->first_header;
while (NULL != pos)
@@ -248,8 +245,6 @@ MHD_response_get_header (struct MHD_Response *response,
{
struct MHD_HTTP_Header *pos;
- if (NULL == key)
- return NULL;
for (pos = response->first_header;
NULL != pos;
pos = pos->next)