diff options
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r-- | src/microhttpd/connection.c | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 02fc0e71..84bfc662 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -4181,6 +4181,56 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
4181 | 4181 | ||
4182 | 4182 | ||
4183 | /** | 4183 | /** |
4184 | * Check whether connection has timed out. | ||
4185 | * @param c the connection to check | ||
4186 | * @return true if connection has timeout and needs to be closed, | ||
4187 | * false otherwise. | ||
4188 | */ | ||
4189 | static bool | ||
4190 | connection_check_timedout (struct MHD_Connection *c) | ||
4191 | { | ||
4192 | const uint64_t timeout = c->connection_timeout_ms; | ||
4193 | uint64_t now; | ||
4194 | uint64_t since_actv; | ||
4195 | |||
4196 | if (c->suspended) | ||
4197 | return false; | ||
4198 | if (0 == timeout) | ||
4199 | return false; | ||
4200 | now = MHD_monotonic_msec_counter (); | ||
4201 | since_actv = now - c->last_activity; | ||
4202 | /* Keep the next lines in sync with #connection_get_wait() to avoid | ||
4203 | * undesired side-effects like busy-waiting. */ | ||
4204 | if (timeout < since_actv) | ||
4205 | { | ||
4206 | if (UINT64_MAX / 2 < since_actv) | ||
4207 | { | ||
4208 | const uint64_t jump_back = c->last_activity - now; | ||
4209 | /* Very unlikely that it is more than quarter-million years pause. | ||
4210 | * More likely that system clock jumps back. */ | ||
4211 | if (5000 >= jump_back) | ||
4212 | { | ||
4213 | #ifdef HAVE_MESSAGES | ||
4214 | MHD_DLOG (c->daemon, | ||
4215 | _ ("Detected system clock %u milliseconds jump back.\n"), | ||
4216 | (unsigned int) jump_back); | ||
4217 | #endif | ||
4218 | return false; | ||
4219 | } | ||
4220 | #ifdef HAVE_MESSAGES | ||
4221 | MHD_DLOG (c->daemon, | ||
4222 | _ ("Detected too large system clock %" PRIu64 " milliseconds " | ||
4223 | "jump back.\n"), | ||
4224 | jump_back); | ||
4225 | #endif | ||
4226 | } | ||
4227 | return true; | ||
4228 | } | ||
4229 | return false; | ||
4230 | } | ||
4231 | |||
4232 | |||
4233 | /** | ||
4184 | * Clean up the state of the given connection and move it into the | 4234 | * Clean up the state of the given connection and move it into the |
4185 | * clean up queue for final disposal. | 4235 | * clean up queue for final disposal. |
4186 | * @remark To be called only from thread that process connection's | 4236 | * @remark To be called only from thread that process connection's |
@@ -4799,21 +4849,12 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
4799 | } | 4849 | } |
4800 | break; | 4850 | break; |
4801 | } | 4851 | } |
4802 | if (! connection->suspended) | 4852 | if (connection_check_timedout (connection)) |
4803 | { | 4853 | { |
4804 | uint64_t timeout; | 4854 | MHD_connection_close_ (connection, |
4805 | timeout = connection->connection_timeout_ms; | 4855 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); |
4806 | /* Keep the next lines in sync with #MHD_get_timeout() to avoid | 4856 | connection->in_idle = false; |
4807 | * undesired side-effects like busy-waiting. */ | 4857 | return MHD_YES; |
4808 | if ( (0 != timeout) && | ||
4809 | (timeout < (MHD_monotonic_msec_counter () | ||
4810 | - connection->last_activity)) ) | ||
4811 | { | ||
4812 | MHD_connection_close_ (connection, | ||
4813 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); | ||
4814 | connection->in_idle = false; | ||
4815 | return MHD_YES; | ||
4816 | } | ||
4817 | } | 4858 | } |
4818 | MHD_connection_update_event_loop_info (connection); | 4859 | MHD_connection_update_event_loop_info (connection); |
4819 | ret = MHD_YES; | 4860 | ret = MHD_YES; |