commit 808dd87371d54376d43ed5de317186a79628c56a
parent b8a83b2737ee54a22934b15e3001a759d8ed3aae
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Fri, 26 Dec 2025 15:39:08 +0100
Added automatic closing of ALL expired connections
Diffstat:
3 files changed, 64 insertions(+), 7 deletions(-)
diff --git a/src/mhd2/events_process.c b/src/mhd2/events_process.c
@@ -1702,6 +1702,67 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict d)
#endif /* MHD_SUPPORT_EPOLL */
+/**
+ * Close timed-out connections (if any)
+ * @param d the daemon to use
+ */
+static MHD_FN_PAR_NONNULL_ALL_ void
+daemon_close_timedout_conns (struct MHD_Daemon *restrict d)
+{
+ struct MHD_Connection *c;
+ struct MHD_Connection *next_c;
+
+#if defined(MHD_SUPPORT_THREADS)
+ mhd_assert (! mhd_D_HAS_WORKERS (d));
+ mhd_assert (! mhd_D_HAS_THR_PER_CONN (d));
+#endif /* MHD_SUPPORT_THREADS */
+
+ /* Check "normal" timeouts list */
+ c = mhd_DLINKEDL_GET_FIRST_D (&(d->conns.def_timeout));
+
+ while (NULL != c)
+ {
+ mhd_assert (! c->timeout.in_cstm_tmout_list);
+ mhd_assert (0u != d->conns.cfg.timeout_milsec);
+
+ if (mhd_conn_is_timeout_expired (c))
+ {
+ next_c = mhd_DLINKEDL_GET_NEXT (&(c->timeout),
+ tmout_list);
+ mhd_conn_start_closing_timedout (c);
+ mhd_conn_pre_clean (c);
+ mhd_conn_remove_from_daemon (c);
+ mhd_conn_close_final (c);
+
+ c = next_c;
+ }
+ else
+ break; /* DL-list is sorted, no need to check the rest of the list */
+ }
+
+ /* Check "custom" timeouts list */
+ c = mhd_DLINKEDL_GET_FIRST_D (&(d->conns.cust_timeout));
+
+ while (NULL != c)
+ {
+ mhd_assert (c->timeout.in_cstm_tmout_list);
+
+ next_c = mhd_DLINKEDL_GET_NEXT (&(c->timeout),
+ tmout_list);
+
+ if (mhd_conn_is_timeout_expired (c))
+ {
+ mhd_conn_start_closing_timedout (c);
+ mhd_conn_pre_clean (c);
+ mhd_conn_remove_from_daemon (c);
+ mhd_conn_close_final (c);
+ }
+
+ /* "Custom" timeouts list is not sorted, check all members */
+ c = next_c;
+ }
+}
+
/**
* Prepare daemon's data for the new round of connections processing
@@ -1780,6 +1841,7 @@ process_all_events_and_data (struct MHD_Daemon *restrict d)
d->events.accept_pending = ! daemon_accept_new_conns (d);
daemon_process_all_active_conns (d);
+ daemon_close_timedout_conns (d);
daemon_cleanup_upgraded_conns (d);
return ! mhd_D_HAS_STOP_REQ (d);
}
diff --git a/src/mhd2/stream_funcs.c b/src/mhd2/stream_funcs.c
@@ -733,7 +733,8 @@ mhd_conn_start_closing (struct MHD_Connection *restrict c,
#ifdef MHD_SUPPORT_HTTP2
if (mhd_C_IS_HTTP2 (c))
{
- mhd_assert ((mhd_CONN_CLOSE_DAEMON_SHUTDOWN == reason) ||
+ mhd_assert ((mhd_CONN_CLOSE_TIMEDOUT == reason) ||
+ (mhd_CONN_CLOSE_DAEMON_SHUTDOWN == reason) ||
(mhd_CONN_CLOSE_H2_CLOSE_SOFT == reason) ||
(mhd_CONN_CLOSE_H2_CLOSE_HARD == reason));
mhd_assert (NULL == log_msg);
diff --git a/src/mhd2/stream_process_states.c b/src/mhd2/stream_process_states.c
@@ -662,12 +662,6 @@ mhd_conn_process_data (struct MHD_Connection *restrict c)
return false;
}
- if (mhd_conn_is_timeout_expired (c)) // TODO: centralise timeout checks
- {
- mhd_conn_start_closing_timedout (c);
- return false;
- }
-
if (! update_active_state (c))
return false;