diff options
Diffstat (limited to 'src/microhttpd')
-rw-r--r-- | src/microhttpd/connection.c | 50 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 152 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 25 |
3 files changed, 143 insertions, 84 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index bcb3f934..de81f08a 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -3487,17 +3487,17 @@ MHD_update_last_activity_ (struct MHD_Connection *connection) | |||
3487 | { | 3487 | { |
3488 | struct MHD_Daemon *daemon = connection->daemon; | 3488 | struct MHD_Daemon *daemon = connection->daemon; |
3489 | 3489 | ||
3490 | if (0 == connection->connection_timeout) | 3490 | if (0 == connection->connection_timeout_ms) |
3491 | return; /* Skip update of activity for connections | 3491 | return; /* Skip update of activity for connections |
3492 | without timeout timer. */ | 3492 | without timeout timer. */ |
3493 | if (connection->suspended) | 3493 | if (connection->suspended) |
3494 | return; /* no activity on suspended connections */ | 3494 | return; /* no activity on suspended connections */ |
3495 | 3495 | ||
3496 | connection->last_activity = MHD_monotonic_sec_counter (); | 3496 | connection->last_activity = MHD_monotonic_msec_counter (); |
3497 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3497 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3498 | return; /* each connection has personal timeout */ | 3498 | return; /* each connection has personal timeout */ |
3499 | 3499 | ||
3500 | if (connection->connection_timeout != daemon->connection_timeout) | 3500 | if (connection->connection_timeout_ms != daemon->connection_timeout_ms) |
3501 | return; /* custom timeout, no need to move it in "normal" DLL */ | 3501 | return; /* custom timeout, no need to move it in "normal" DLL */ |
3502 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3502 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3503 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3503 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
@@ -4011,7 +4011,7 @@ cleanup_connection (struct MHD_Connection *connection) | |||
4011 | { | 4011 | { |
4012 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 4012 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
4013 | { | 4013 | { |
4014 | if (connection->connection_timeout == daemon->connection_timeout) | 4014 | if (connection->connection_timeout_ms == daemon->connection_timeout_ms) |
4015 | XDLL_remove (daemon->normal_timeout_head, | 4015 | XDLL_remove (daemon->normal_timeout_head, |
4016 | daemon->normal_timeout_tail, | 4016 | daemon->normal_timeout_tail, |
4017 | connection); | 4017 | connection); |
@@ -4584,11 +4584,13 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
4584 | } | 4584 | } |
4585 | if (! connection->suspended) | 4585 | if (! connection->suspended) |
4586 | { | 4586 | { |
4587 | time_t timeout; | 4587 | uint64_t timeout; |
4588 | timeout = connection->connection_timeout; | 4588 | timeout = connection->connection_timeout_ms; |
4589 | /* Keep the next lines in sync with #MHD_get_timeout() to avoid | ||
4590 | * undesired side-effects like busy-waiting. */ | ||
4589 | if ( (0 != timeout) && | 4591 | if ( (0 != timeout) && |
4590 | (timeout <= (MHD_monotonic_sec_counter () | 4592 | (timeout < (MHD_monotonic_msec_counter () |
4591 | - connection->last_activity)) ) | 4593 | - connection->last_activity)) ) |
4592 | { | 4594 | { |
4593 | MHD_connection_close_ (connection, | 4595 | MHD_connection_close_ (connection, |
4594 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); | 4596 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); |
@@ -4719,8 +4721,8 @@ MHD_get_connection_info (struct MHD_Connection *connection, | |||
4719 | connection->suspended_dummy = connection->suspended ? MHD_YES : MHD_NO; | 4721 | connection->suspended_dummy = connection->suspended ? MHD_YES : MHD_NO; |
4720 | return (const union MHD_ConnectionInfo *) &connection->suspended_dummy; | 4722 | return (const union MHD_ConnectionInfo *) &connection->suspended_dummy; |
4721 | case MHD_CONNECTION_INFO_CONNECTION_TIMEOUT: | 4723 | case MHD_CONNECTION_INFO_CONNECTION_TIMEOUT: |
4722 | connection->connection_timeout_dummy = (unsigned | 4724 | connection->connection_timeout_dummy = |
4723 | int) connection->connection_timeout; | 4725 | (unsigned int) connection->connection_timeout_ms * 1000; |
4724 | return (const union MHD_ConnectionInfo *) &connection-> | 4726 | return (const union MHD_ConnectionInfo *) &connection-> |
4725 | connection_timeout_dummy; | 4727 | connection_timeout_dummy; |
4726 | case MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE: | 4728 | case MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE: |
@@ -4759,15 +4761,15 @@ MHD_set_connection_option (struct MHD_Connection *connection, | |||
4759 | switch (option) | 4761 | switch (option) |
4760 | { | 4762 | { |
4761 | case MHD_CONNECTION_OPTION_TIMEOUT: | 4763 | case MHD_CONNECTION_OPTION_TIMEOUT: |
4762 | if (0 == connection->connection_timeout) | 4764 | if (0 == connection->connection_timeout_ms) |
4763 | connection->last_activity = MHD_monotonic_sec_counter (); | 4765 | connection->last_activity = MHD_monotonic_msec_counter (); |
4764 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 4766 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
4765 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 4767 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
4766 | #endif | 4768 | #endif |
4767 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 4769 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
4768 | (! connection->suspended) ) | 4770 | (! connection->suspended) ) |
4769 | { | 4771 | { |
4770 | if (connection->connection_timeout == daemon->connection_timeout) | 4772 | if (connection->connection_timeout_ms == daemon->connection_timeout_ms) |
4771 | XDLL_remove (daemon->normal_timeout_head, | 4773 | XDLL_remove (daemon->normal_timeout_head, |
4772 | daemon->normal_timeout_tail, | 4774 | daemon->normal_timeout_tail, |
4773 | connection); | 4775 | connection); |
@@ -4777,13 +4779,29 @@ MHD_set_connection_option (struct MHD_Connection *connection, | |||
4777 | connection); | 4779 | connection); |
4778 | } | 4780 | } |
4779 | va_start (ap, option); | 4781 | va_start (ap, option); |
4780 | connection->connection_timeout = va_arg (ap, | 4782 | connection->connection_timeout_ms = va_arg (ap, |
4781 | unsigned int); | 4783 | unsigned int); |
4782 | va_end (ap); | 4784 | va_end (ap); |
4785 | #if (0 == (UINT64_MAX + 0)) || ((UINT_MAX + 0) >= (UINT64_MAX + 0)) | ||
4786 | if ((UINT64_MAX / 2000 - 1) < connection->connection_timeout_ms) | ||
4787 | { | ||
4788 | #ifdef HAVE_MESSAGES | ||
4789 | MHD_DLOG (connection->daemon, | ||
4790 | _ ("The specified connection timeout (" PRIu64 ") is too " \ | ||
4791 | "large. Maximum allowed value (" PRIu64 ") will be used " \ | ||
4792 | "instead.\n"), | ||
4793 | connection->connection_timeout_ms, | ||
4794 | (UINT64_MAX / 2000 - 1)); | ||
4795 | #endif | ||
4796 | connection->connection_timeout_ms = UINT64_MAX / 2000 - 1; | ||
4797 | } | ||
4798 | else | ||
4799 | #endif /* UINTMAX_MAX >= UINT64_MAX */ | ||
4800 | connection->connection_timeout_ms *= 1000; | ||
4783 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 4801 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
4784 | (! connection->suspended) ) | 4802 | (! connection->suspended) ) |
4785 | { | 4803 | { |
4786 | if (connection->connection_timeout == daemon->connection_timeout) | 4804 | if (connection->connection_timeout_ms == daemon->connection_timeout_ms) |
4787 | XDLL_insert (daemon->normal_timeout_head, | 4805 | XDLL_insert (daemon->normal_timeout_head, |
4788 | daemon->normal_timeout_tail, | 4806 | daemon->normal_timeout_tail, |
4789 | connection); | 4807 | connection); |
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index d4fd0d6a..090d39d4 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -1869,7 +1869,6 @@ thread_main_handle_connection (void *data) | |||
1869 | MHD_socket maxsock; | 1869 | MHD_socket maxsock; |
1870 | struct timeval tv; | 1870 | struct timeval tv; |
1871 | struct timeval *tvp; | 1871 | struct timeval *tvp; |
1872 | time_t now; | ||
1873 | #if WINDOWS | 1872 | #if WINDOWS |
1874 | #ifdef HAVE_POLL | 1873 | #ifdef HAVE_POLL |
1875 | int extra_slot; | 1874 | int extra_slot; |
@@ -1893,7 +1892,7 @@ thread_main_handle_connection (void *data) | |||
1893 | while ( (! daemon->shutdown) && | 1892 | while ( (! daemon->shutdown) && |
1894 | (MHD_CONNECTION_CLOSED != con->state) ) | 1893 | (MHD_CONNECTION_CLOSED != con->state) ) |
1895 | { | 1894 | { |
1896 | const time_t timeout = con->connection_timeout; | 1895 | uint64_t timeout = con->connection_timeout_ms; |
1897 | #ifdef UPGRADE_SUPPORT | 1896 | #ifdef UPGRADE_SUPPORT |
1898 | struct MHD_UpgradeResponseHandle *const urh = con->urh; | 1897 | struct MHD_UpgradeResponseHandle *const urh = con->urh; |
1899 | #else /* ! UPGRADE_SUPPORT */ | 1898 | #else /* ! UPGRADE_SUPPORT */ |
@@ -1989,22 +1988,34 @@ thread_main_handle_connection (void *data) | |||
1989 | if ( (NULL == tvp) && | 1988 | if ( (NULL == tvp) && |
1990 | (timeout > 0) ) | 1989 | (timeout > 0) ) |
1991 | { | 1990 | { |
1992 | now = MHD_monotonic_sec_counter (); | 1991 | const uint64_t since_actv = MHD_monotonic_msec_counter () |
1993 | if (now - con->last_activity > timeout) | 1992 | - con->last_activity; |
1993 | if (since_actv > timeout) | ||
1994 | { | ||
1994 | tv.tv_sec = 0; | 1995 | tv.tv_sec = 0; |
1996 | tv.tv_usec = 0; | ||
1997 | } | ||
1998 | else if (since_actv == timeout) | ||
1999 | { | ||
2000 | /* Exact match for timeout and time from last activity. | ||
2001 | * Maybe this is just a precise match or this happens because the timer | ||
2002 | * resolution is too low. | ||
2003 | * Set wait time to 0.1 seconds to avoid busy-waiting with low | ||
2004 | * timer resolution as connection is not yet timed-out */ | ||
2005 | tv.tv_sec = 0; | ||
2006 | tv.tv_usec = 100 * 1000; | ||
2007 | } | ||
1995 | else | 2008 | else |
1996 | { | 2009 | { |
1997 | const time_t seconds_left = timeout - (now - con->last_activity); | 2010 | const uint64_t mseconds_left = timeout - since_actv; |
1998 | #if ! defined(_WIN32) || defined(__CYGWIN__) | 2011 | #if UINT64_MAX != TIMEVAL_TV_SEC_MAX |
1999 | tv.tv_sec = seconds_left; | 2012 | if (mseconds_left / 1000 > TIMEVAL_TV_SEC_MAX) |
2000 | #else /* _WIN32 && !__CYGWIN__ */ | ||
2001 | if (seconds_left > TIMEVAL_TV_SEC_MAX) | ||
2002 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; | 2013 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; |
2003 | else | 2014 | else |
2004 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; | 2015 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) mseconds_left / 1000; |
2005 | #endif /* _WIN32 && ! __CYGWIN__ */ | 2016 | #endif /* UINT64_MAX != TIMEVAL_TV_SEC_MAX */ |
2017 | tv.tv_usec = (mseconds_left % 1000) * 1000; | ||
2006 | } | 2018 | } |
2007 | tv.tv_usec = 0; | ||
2008 | tvp = &tv; | 2019 | tvp = &tv; |
2009 | } | 2020 | } |
2010 | if (! use_poll) | 2021 | if (! use_poll) |
@@ -2474,7 +2485,6 @@ new_connection_prepare_ (struct MHD_Daemon *daemon, | |||
2474 | connection->sk_nodelay = _MHD_UNKNOWN; | 2485 | connection->sk_nodelay = _MHD_UNKNOWN; |
2475 | } | 2486 | } |
2476 | 2487 | ||
2477 | connection->connection_timeout = daemon->connection_timeout; | ||
2478 | if (NULL == (connection->addr = malloc (addrlen))) | 2488 | if (NULL == (connection->addr = malloc (addrlen))) |
2479 | { | 2489 | { |
2480 | eno = errno; | 2490 | eno = errno; |
@@ -2500,7 +2510,9 @@ new_connection_prepare_ (struct MHD_Daemon *daemon, | |||
2500 | connection->is_nonip = sk_is_nonip; | 2510 | connection->is_nonip = sk_is_nonip; |
2501 | connection->sk_spipe_suppress = sk_spipe_supprs; | 2511 | connection->sk_spipe_suppress = sk_spipe_supprs; |
2502 | connection->daemon = daemon; | 2512 | connection->daemon = daemon; |
2503 | connection->last_activity = MHD_monotonic_sec_counter (); | 2513 | connection->connection_timeout_ms = daemon->connection_timeout_ms; |
2514 | if (0 != connection->connection_timeout_ms) | ||
2515 | connection->last_activity = MHD_monotonic_msec_counter (); | ||
2504 | 2516 | ||
2505 | if (0 == (daemon->options & MHD_USE_TLS)) | 2517 | if (0 == (daemon->options & MHD_USE_TLS)) |
2506 | { | 2518 | { |
@@ -3061,7 +3073,7 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
3061 | } | 3073 | } |
3062 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3074 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3063 | { | 3075 | { |
3064 | if (connection->connection_timeout == daemon->connection_timeout) | 3076 | if (connection->connection_timeout_ms == daemon->connection_timeout_ms) |
3065 | XDLL_remove (daemon->normal_timeout_head, | 3077 | XDLL_remove (daemon->normal_timeout_head, |
3066 | daemon->normal_timeout_tail, | 3078 | daemon->normal_timeout_tail, |
3067 | connection); | 3079 | connection); |
@@ -3270,10 +3282,10 @@ resume_suspended_connections (struct MHD_Daemon *daemon) | |||
3270 | if (! used_thr_p_c) | 3282 | if (! used_thr_p_c) |
3271 | { | 3283 | { |
3272 | /* Reset timeout timer on resume. */ | 3284 | /* Reset timeout timer on resume. */ |
3273 | if (0 != pos->connection_timeout) | 3285 | if (0 != pos->connection_timeout_ms) |
3274 | pos->last_activity = MHD_monotonic_sec_counter (); | 3286 | pos->last_activity = MHD_monotonic_msec_counter (); |
3275 | 3287 | ||
3276 | if (pos->connection_timeout == daemon->connection_timeout) | 3288 | if (pos->connection_timeout_ms == daemon->connection_timeout_ms) |
3277 | XDLL_insert (daemon->normal_timeout_head, | 3289 | XDLL_insert (daemon->normal_timeout_head, |
3278 | daemon->normal_timeout_tail, | 3290 | daemon->normal_timeout_tail, |
3279 | pos); | 3291 | pos); |
@@ -3824,10 +3836,9 @@ enum MHD_Result | |||
3824 | MHD_get_timeout (struct MHD_Daemon *daemon, | 3836 | MHD_get_timeout (struct MHD_Daemon *daemon, |
3825 | MHD_UNSIGNED_LONG_LONG *timeout) | 3837 | MHD_UNSIGNED_LONG_LONG *timeout) |
3826 | { | 3838 | { |
3827 | time_t earliest_deadline; | 3839 | uint64_t earliest_deadline; |
3828 | time_t now; | ||
3829 | struct MHD_Connection *pos; | 3840 | struct MHD_Connection *pos; |
3830 | bool have_timeout; | 3841 | struct MHD_Connection *earliest_tmot_conn; /**< the connection with earliest timeout */ |
3831 | 3842 | ||
3832 | #ifdef MHD_USE_THREADS | 3843 | #ifdef MHD_USE_THREADS |
3833 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 3844 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
@@ -3862,44 +3873,63 @@ MHD_get_timeout (struct MHD_Daemon *daemon, | |||
3862 | } | 3873 | } |
3863 | #endif /* EPOLL_SUPPORT */ | 3874 | #endif /* EPOLL_SUPPORT */ |
3864 | 3875 | ||
3865 | have_timeout = false; | 3876 | earliest_tmot_conn = NULL; |
3866 | earliest_deadline = 0; /* avoid compiler warnings */ | 3877 | earliest_deadline = 0; /* mute compiler warning */ |
3867 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) | ||
3868 | { | ||
3869 | if (0 != pos->connection_timeout) | ||
3870 | { | ||
3871 | if ( (! have_timeout) || | ||
3872 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) | ||
3873 | earliest_deadline = pos->last_activity + pos->connection_timeout; | ||
3874 | have_timeout = true; | ||
3875 | } | ||
3876 | } | ||
3877 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ | 3878 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ |
3878 | pos = daemon->normal_timeout_tail; | 3879 | pos = daemon->normal_timeout_tail; |
3879 | if ( (NULL != pos) && | 3880 | if ( (NULL != pos) && |
3880 | (0 != pos->connection_timeout) ) | 3881 | (0 != pos->connection_timeout_ms) ) |
3881 | { | 3882 | { |
3882 | if ( (! have_timeout) || | 3883 | earliest_tmot_conn = pos; |
3883 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) | 3884 | earliest_deadline = pos->last_activity + pos->connection_timeout_ms; |
3884 | earliest_deadline = pos->last_activity + pos->connection_timeout; | ||
3885 | have_timeout = true; | ||
3886 | } | 3885 | } |
3887 | 3886 | ||
3888 | if (! have_timeout) | 3887 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) |
3889 | return MHD_NO; | ||
3890 | now = MHD_monotonic_sec_counter (); | ||
3891 | if (earliest_deadline < now) | ||
3892 | *timeout = 0; | ||
3893 | else | ||
3894 | { | 3888 | { |
3895 | const time_t second_left = earliest_deadline - now; | 3889 | if (0 != pos->connection_timeout_ms) |
3890 | { | ||
3891 | if ( (NULL == earliest_tmot_conn) || | ||
3892 | (earliest_deadline - pos->last_activity > | ||
3893 | pos->connection_timeout_ms) ) | ||
3894 | { | ||
3895 | earliest_tmot_conn = pos; | ||
3896 | earliest_deadline = pos->last_activity + pos->connection_timeout_ms; | ||
3897 | } | ||
3898 | } | ||
3899 | } | ||
3896 | 3900 | ||
3897 | if (((unsigned long long) second_left) > ULLONG_MAX / 1000) | 3901 | if (NULL != earliest_tmot_conn) |
3898 | *timeout = ULLONG_MAX; | 3902 | { |
3903 | const uint64_t since_actv = MHD_monotonic_msec_counter () | ||
3904 | - earliest_tmot_conn->last_activity; | ||
3905 | /* Keep the next lines in sync with #MHD_connection_handle_idle() and | ||
3906 | * with #thread_main_handle_connection(). */ | ||
3907 | if (since_actv > earliest_tmot_conn->connection_timeout_ms) | ||
3908 | *timeout = 0; | ||
3909 | else if (since_actv == earliest_tmot_conn->connection_timeout_ms) | ||
3910 | { | ||
3911 | /* Exact match for timeout and time from last activity. | ||
3912 | * Maybe this is just a precise match or this happens because the timer | ||
3913 | * resolution is too low. | ||
3914 | * Set wait time to 0.1 seconds to avoid busy-waiting with low | ||
3915 | * timer resolution as connection is not yet timed-out */ | ||
3916 | *timeout = 100; | ||
3917 | } | ||
3899 | else | 3918 | else |
3900 | *timeout = 1000LLU * (unsigned long long) second_left; | 3919 | { |
3920 | const uint64_t mssecond_left = earliest_tmot_conn->connection_timeout_ms | ||
3921 | - since_actv; | ||
3922 | |||
3923 | #if UINT64_MAX != ULLONG_MAX | ||
3924 | if (mssecond_left > ULLONG_MAX) | ||
3925 | *timeout = ULLONG_MAX; | ||
3926 | else | ||
3927 | #endif /* UINT64 != ULLONG_MAX */ | ||
3928 | *timeout = (unsigned long long) mssecond_left; | ||
3929 | } | ||
3930 | return MHD_YES; | ||
3901 | } | 3931 | } |
3902 | return MHD_YES; | 3932 | return MHD_NO; |
3903 | } | 3933 | } |
3904 | 3934 | ||
3905 | 3935 | ||
@@ -5247,7 +5277,7 @@ close_connection (struct MHD_Connection *pos) | |||
5247 | #endif | 5277 | #endif |
5248 | mhd_assert (! pos->suspended); | 5278 | mhd_assert (! pos->suspended); |
5249 | mhd_assert (! pos->resuming); | 5279 | mhd_assert (! pos->resuming); |
5250 | if (pos->connection_timeout == daemon->connection_timeout) | 5280 | if (pos->connection_timeout_ms == daemon->connection_timeout_ms) |
5251 | XDLL_remove (daemon->normal_timeout_head, | 5281 | XDLL_remove (daemon->normal_timeout_head, |
5252 | daemon->normal_timeout_tail, | 5282 | daemon->normal_timeout_tail, |
5253 | pos); | 5283 | pos); |
@@ -5593,20 +5623,22 @@ parse_options_va (struct MHD_Daemon *daemon, | |||
5593 | case MHD_OPTION_CONNECTION_TIMEOUT: | 5623 | case MHD_OPTION_CONNECTION_TIMEOUT: |
5594 | uv = va_arg (ap, | 5624 | uv = va_arg (ap, |
5595 | unsigned int); | 5625 | unsigned int); |
5596 | daemon->connection_timeout = (time_t) uv; | 5626 | #if (0 == (UINT64_MAX + 0)) || ((UINT_MAX + 0) >= (UINT64_MAX + 0)) |
5597 | /* Next comparison could be always false on some platforms and whole branch will | 5627 | if ((UINT64_MAX / 2000 - 1) < uv) |
5598 | * be optimized out on those platforms. On others it will be compiled into real | ||
5599 | * check. */ | ||
5600 | if ( ( (MHD_TYPE_IS_SIGNED_ (time_t)) && | ||
5601 | (daemon->connection_timeout < 0) ) || /* Compiler may warn on some platforms, ignore warning. */ | ||
5602 | (uv != (unsigned int) daemon->connection_timeout) ) | ||
5603 | { | 5628 | { |
5604 | #ifdef HAVE_MESSAGES | 5629 | #ifdef HAVE_MESSAGES |
5605 | MHD_DLOG (daemon, | 5630 | MHD_DLOG (daemon, |
5606 | _ ("Warning: Too large timeout value, ignored.\n")); | 5631 | _ ("The specified connection timeout (%u) is too large. " \ |
5632 | "Maximum allowed value (" PRIu64 ") will be used " \ | ||
5633 | "instead.\n"), | ||
5634 | uv, | ||
5635 | (UINT64_MAX / 2000 - 1)); | ||
5607 | #endif | 5636 | #endif |
5608 | daemon->connection_timeout = 0; | 5637 | daemon->connection_timeout_ms = UINT64_MAX / 2000 - 1; |
5609 | } | 5638 | } |
5639 | else | ||
5640 | #endif /* UINTMAX_MAX >= UINT64_MAX */ | ||
5641 | daemon->connection_timeout_ms = uv * 1000; | ||
5610 | break; | 5642 | break; |
5611 | case MHD_OPTION_NOTIFY_COMPLETED: | 5643 | case MHD_OPTION_NOTIFY_COMPLETED: |
5612 | daemon->notify_completed = va_arg (ap, | 5644 | daemon->notify_completed = va_arg (ap, |
@@ -6444,7 +6476,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
6444 | daemon->pool_size = MHD_POOL_SIZE_DEFAULT; | 6476 | daemon->pool_size = MHD_POOL_SIZE_DEFAULT; |
6445 | daemon->pool_increment = MHD_BUF_INC_SIZE; | 6477 | daemon->pool_increment = MHD_BUF_INC_SIZE; |
6446 | daemon->unescape_callback = &unescape_wrapper; | 6478 | daemon->unescape_callback = &unescape_wrapper; |
6447 | daemon->connection_timeout = 0; /* no timeout */ | 6479 | daemon->connection_timeout_ms = 0; /* no timeout */ |
6448 | MHD_itc_set_invalid_ (daemon->itc); | 6480 | MHD_itc_set_invalid_ (daemon->itc); |
6449 | #ifdef SOMAXCONN | 6481 | #ifdef SOMAXCONN |
6450 | daemon->listen_backlog_size = SOMAXCONN; | 6482 | daemon->listen_backlog_size = SOMAXCONN; |
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index 9db32af1..a9f5e141 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h | |||
@@ -43,6 +43,13 @@ | |||
43 | #include <stdbool.h> | 43 | #include <stdbool.h> |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #ifdef HAVE_INTTYPES_H | ||
47 | #include <inttypes.h> | ||
48 | #endif /* HAVE_INTTYPES_H */ | ||
49 | |||
50 | #ifndef PRIu64 | ||
51 | #define PRIu64 "llu" | ||
52 | #endif /* ! PRIu64 */ | ||
46 | 53 | ||
47 | #ifdef MHD_PANIC | 54 | #ifdef MHD_PANIC |
48 | /* Override any defined MHD_PANIC macro with proper one */ | 55 | /* Override any defined MHD_PANIC macro with proper one */ |
@@ -1143,13 +1150,14 @@ struct MHD_Connection | |||
1143 | * Last time this connection had any activity | 1150 | * Last time this connection had any activity |
1144 | * (reading or writing). | 1151 | * (reading or writing). |
1145 | */ | 1152 | */ |
1146 | time_t last_activity; | 1153 | uint64_t last_activity; |
1147 | 1154 | ||
1148 | /** | 1155 | /** |
1149 | * After how many seconds of inactivity should | 1156 | * After how many milliseconds of inactivity should |
1150 | * this connection time out? Zero for no timeout. | 1157 | * this connection time out? |
1158 | * Zero for no timeout. | ||
1151 | */ | 1159 | */ |
1152 | time_t connection_timeout; | 1160 | uint64_t connection_timeout_ms; |
1153 | 1161 | ||
1154 | /** | 1162 | /** |
1155 | * Special member to be returned by #MHD_get_connection_info() | 1163 | * Special member to be returned by #MHD_get_connection_info() |
@@ -1707,7 +1715,7 @@ struct MHD_Daemon | |||
1707 | * moved back to the tail of the list. | 1715 | * moved back to the tail of the list. |
1708 | * | 1716 | * |
1709 | * All connections by default start in this list; if a custom | 1717 | * All connections by default start in this list; if a custom |
1710 | * timeout that does not match @e connection_timeout is set, they | 1718 | * timeout that does not match @e connection_timeout_ms is set, they |
1711 | * are moved to the @e manual_timeout_head-XDLL. | 1719 | * are moved to the @e manual_timeout_head-XDLL. |
1712 | * Not used in MHD_USE_THREAD_PER_CONNECTION mode as each thread | 1720 | * Not used in MHD_USE_THREAD_PER_CONNECTION mode as each thread |
1713 | * needs only one connection-specific timeout. | 1721 | * needs only one connection-specific timeout. |
@@ -1968,10 +1976,11 @@ struct MHD_Daemon | |||
1968 | unsigned int connection_limit; | 1976 | unsigned int connection_limit; |
1969 | 1977 | ||
1970 | /** | 1978 | /** |
1971 | * After how many seconds of inactivity should | 1979 | * After how many milliseconds of inactivity should |
1972 | * connections time out? Zero for no timeout. | 1980 | * this connection time out? |
1981 | * Zero for no timeout. | ||
1973 | */ | 1982 | */ |
1974 | time_t connection_timeout; | 1983 | uint64_t connection_timeout_ms; |
1975 | 1984 | ||
1976 | /** | 1985 | /** |
1977 | * Maximum number of connections per IP, or 0 for | 1986 | * Maximum number of connections per IP, or 0 for |