libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit d1d5bf7cb9e99860fb0e9657b36436ac48690dbb
parent 54f9e798f2123d22c284f5ce55524018c8dea098
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 28 Sep 2012 11:39:38 +0000

-introduce MHD_UNSIGNED_LONG_LONG, deprecate MHD_LONG_LONG, check for invalid options on start, document

Diffstat:
Mdoc/examples/sessions.c | 2+-
Mdoc/libmicrohttpd.texi | 43+++++++++++++++++++++++++++++++------------
Msrc/daemon/connection.c | 12++++++------
Msrc/daemon/daemon.c | 97++++++++++++++++++++++++++++++++++---------------------------------------------
Msrc/daemon/postprocessor.c | 9++++++---
Msrc/examples/fileserver_example_external_select.c | 2+-
Msrc/examples/post_example.c | 2+-
Msrc/include/microhttpd.h | 23+++++++++++++++++++++--
Msrc/testcurl/perf_get_concurrent.c | 2+-
9 files changed, 110 insertions(+), 82 deletions(-)

diff --git a/doc/examples/sessions.c b/doc/examples/sessions.c @@ -683,7 +683,7 @@ main (int argc, char *const *argv) fd_set ws; fd_set es; int max; - unsigned MHD_LONG_LONG mhd_timeout; + MHD_UNSIGNED_LONG_LONG mhd_timeout; if (argc != 2) { diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi @@ -262,20 +262,32 @@ ignore_sigpipe () } @end verbatim -@section MHD_LONG_LONG +@section MHD_UNSIGNED_LONG_LONG @cindex long long +@cindex MHD_LONG_LONG @cindex IAR @cindex ARM @cindex cortex m3 @cindex embedded systems -Some platforms do not support @code{long long}. Hence MHD defines -a macro @code{MHD_LONG_LONG} which will default to @code{long long}. -If your platform does not support @code{long long}, you should -change "platform.h" to define @code{MHD_LONG_LONG} to an appropriate -alternative type and also define @code{MHD_LONG_LONG_PRINTF} to the -corresponding format string for printing such a data type (without -the percent sign). +Some platforms do not support @code{long long}. Hence MHD defines a +macro @code{MHD_UNSIGNED LONG_LONG} which will default to +@code{unsigned long long}. For standard desktop operating systems, +this is all you need to know. + +However, if your platform does not support @code{unsigned long long}, +you should change "platform.h" to define @code{MHD_LONG_LONG} and +@code{MHD_UNSIGNED_LONG_LONG} to an appropriate alternative type and +also define @code{MHD_LONG_LONG_PRINTF} and +@code{MHD_UNSIGNED_LONG_LONG_PRINTF} to the corresponding format +string for printing such a data type. Note that the ``signed'' +versions are deprecated. Also, for historical reasons, +@code{MHD_LONG_LONG_PRINTF} is without the percent sign, whereas +@code{MHD_UNSIGNED_LONG_LONG_PRINTF} is with the percent sign. Newly +written code should only use the unsigned versions. However, you need +to define both in "platform.h" if you need to change the definition +for the specific platform. + @c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -311,7 +323,11 @@ compiled with messages enabled. This is done by default except you ran configure with the @code{--disable-messages} flag set. @item MHD_USE_SSL -Run in https mode (this option may not work with all threading modes yet). +@cindex TLS +@cindex SSL +Run in HTTPS-mode. If you specify @code{MHD_USE_SSL} and MHD was +compiled without SSL support, @code{MHD_start_daemon} will return +NULL. @item MHD_USE_THREAD_PER_CONNECTION Run using one thread per connection. @@ -322,7 +338,8 @@ Run using an internal thread doing @code{SELECT}. @item MHD_USE_IPv6 @cindex IPv6 Run using the IPv6 protocol (otherwise, MHD will just support IPv4). - +If you specify @code{MHD_USE_IPV6} and the local platform does not +support it, @code{MHD_start_daemon} will return NULL. @item MHD_USE_PEDANTIC_CHECKS Be pedantic about the protocol (as opposed to as tolerant as possible). @@ -339,7 +356,9 @@ production. @cindex select Use poll instead of select. This allows sockets with descriptors @code{>= FD_SETSIZE}. This option only works in conjunction with -@code{MHD_USE_THREAD_PER_CONNECTION} (at this point). +@code{MHD_USE_THREAD_PER_CONNECTION} (at this point). If you +specify @code{MHD_USE_POLL} and the local platform does not support +it, @code{MHD_start_daemon} will return NULL. @item MHD_SUPPRESS_DATE_NO_CLOCK @cindex date @@ -581,7 +600,7 @@ Number (unsigned int) of threads in thread pool. Enable thread pooling by setting this value to to something greater than 1. Currently, thread model must be MHD_USE_SELECT_INTERNALLY if thread pooling is enabled -(MHD_start_daemon returns @code{NULL} for an unsupported thread +(@code{MHD_start_daemon} returns @code{NULL} for an unsupported thread model). @item MHD_OPTION_ARRAY diff --git a/src/daemon/connection.c b/src/daemon/connection.c @@ -561,8 +561,8 @@ add_extra_headers (struct MHD_Connection *connection) MHD_HTTP_HEADER_CONTENT_LENGTH)) { SPRINTF (buf, - "%" MHD_LONG_LONG_PRINTF "u", - (unsigned MHD_LONG_LONG) connection->response->total_size); + MHD_UNSIGNED_LONG_LONG_PRINTF, + (MHD_UNSIGNED_LONG_LONG) connection->response->total_size); MHD_add_response_header (connection->response, MHD_HTTP_HEADER_CONTENT_LENGTH, buf); } @@ -1517,11 +1517,11 @@ process_request_body (struct MHD_Connection *connection) return; } if (processed > used) - mhd_panic (mhd_panic_cls, __FILE__, __LINE__, + mhd_panic (mhd_panic_cls, __FILE__, __LINE__ #if HAVE_MESSAGES - "API violation" + , "API violation" #else - NULL + , NULL #endif ); if (processed != 0) @@ -1771,7 +1771,7 @@ static void parse_connection_headers (struct MHD_Connection *connection) { const char *clen; - unsigned MHD_LONG_LONG cval; + MHD_UNSIGNED_LONG_LONG cval; struct MHD_Response *response; const char *enc; char *end; diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c @@ -1147,27 +1147,32 @@ MHD_accept_connection (struct MHD_Daemon *daemon) if (MHD_YES == need_fcntl) { /* make socket non-inheritable */ -#if !WINDOWS - flags = fcntl (s, F_GETFD); - if ( ( (-1 == flags) || - ( (flags != (flags | FD_CLOEXEC)) && - (0 != fcntl (s, F_SETFD, flags | FD_CLOEXEC)) ) ) ) -#else +#if WINDOWS DWORD dwFlags; if (!GetHandleInformation ((HANDLE) s, &dwFlags) || ((dwFlags != dwFlags & ~HANDLE_FLAG_INHERIT) && !SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0))) -#endif { #if HAVE_MESSAGES -#if WINDOWS SetErrnoFromWinError (GetLastError ()); + MHD_DLOG (daemon, + "Failed to make socket non-inheritable: %s\n", + STRERROR (errno)); #endif + } +#else + flags = fcntl (s, F_GETFD); + if ( ( (-1 == flags) || + ( (flags != (flags | FD_CLOEXEC)) && + (0 != fcntl (s, F_SETFD, flags | FD_CLOEXEC)) ) ) ) + { +#if HAVE_MESSAGES MHD_DLOG (daemon, "Failed to make socket non-inheritable: %s\n", STRERROR (errno)); #endif } +#endif } #if HAVE_MESSAGES #if DEBUG_CONNECT @@ -1249,7 +1254,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) */ int MHD_get_timeout (struct MHD_Daemon *daemon, - unsigned MHD_LONG_LONG *timeout) + MHD_UNSIGNED_LONG_LONG *timeout) { time_t earliest_deadline; time_t now; @@ -1266,17 +1271,18 @@ MHD_get_timeout (struct MHD_Daemon *daemon, have_timeout = MHD_NO; for (pos = daemon->connections_head; NULL != pos; pos = pos->next) { - if (0 != pos->connection_timeout) { - if (!have_timeout || - earliest_deadline > pos->last_activity + pos->connection_timeout) - earliest_deadline = pos->last_activity + pos->connection_timeout; + if (0 != pos->connection_timeout) + { + if (!have_timeout || + earliest_deadline > pos->last_activity + pos->connection_timeout) + earliest_deadline = pos->last_activity + pos->connection_timeout; #if HTTPS_SUPPORT - if ( (0 != (daemon->options & MHD_USE_SSL)) && - (0 != gnutls_record_check_pending (pos->tls_session)) ) - earliest_deadline = 0; + if ( (0 != (daemon->options & MHD_USE_SSL)) && + (0 != gnutls_record_check_pending (pos->tls_session)) ) + earliest_deadline = 0; #endif - have_timeout = MHD_YES; - } + have_timeout = MHD_YES; + } } if (MHD_NO == have_timeout) return MHD_NO; @@ -1309,7 +1315,7 @@ MHD_select (struct MHD_Daemon *daemon, int max; struct timeval timeout; struct timeval *tv; - unsigned MHD_LONG_LONG ltimeout; + MHD_UNSIGNED_LONG_LONG ltimeout; int ds; timeout.tv_sec = 0; @@ -1428,7 +1434,7 @@ MHD_poll_all (struct MHD_Daemon *daemon, { struct pollfd p[2 + num_connections]; struct MHD_Pollfd mp; - unsigned MHD_LONG_LONG ltimeout; + MHD_UNSIGNED_LONG_LONG ltimeout; unsigned int i; int timeout; unsigned int poll_server; @@ -2073,11 +2079,24 @@ MHD_start_daemon_va (unsigned int options, int res_thread_create; int use_pipe; +#ifndef HAVE_INET6 + if (0 != (options & MHD_USE_IPv6)) + return NULL; +#endif +#ifndef HAVE_POLL_H + if (0 != (options & MHD_USE_POLL)) + return NULL; +#endif +#if ! HTTPS_SUPPORT + if (0 != (options & MHD_USE_SSL)) + return NULL; +#endif if (NULL == dh) return NULL; if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) return NULL; memset (daemon, 0, sizeof (struct MHD_Daemon)); + /* try to open listen socket */ #if HTTPS_SUPPORT if (0 != (options & MHD_USE_SSL)) { @@ -2085,27 +2104,6 @@ MHD_start_daemon_va (unsigned int options, "NORMAL", NULL); } -#else - if (0 != (options & MHD_USE_SSL)) - { -#if HAVE_MESSAGES - MHD_DLOG (daemon, - "HTTPS not supported\n"); -#endif - free (daemon); - return NULL; - } -#endif -#ifndef HAVE_POLL_H - if (0 != (options & MHD_USE_POLL)) - { -#if HAVE_MESSAGES - MHD_DLOG (daemon, - "poll not supported\n"); -#endif - free (daemon); - return NULL; - } #endif daemon->socket_fd = -1; daemon->options = (enum MHD_OPTION) options; @@ -2121,8 +2119,7 @@ MHD_start_daemon_va (unsigned int options, daemon->wpipe[0] = -1; daemon->wpipe[1] = -1; #if HAVE_MESSAGES - daemon->custom_error_log = - (void (*)(void *, const char *, va_list)) &vfprintf; + daemon->custom_error_log = (MHD_LogCallback) &vfprintf; daemon->custom_error_log_cls = stderr; #endif #ifdef HAVE_LISTEN_SHUTDOWN @@ -2178,7 +2175,6 @@ MHD_start_daemon_va (unsigned int options, free (daemon); return NULL; } - #ifdef DAUTH_SUPPORT if (daemon->nonce_nc_size > 0) { @@ -2255,17 +2251,7 @@ MHD_start_daemon_va (unsigned int options, { /* try to open listen socket */ if ((options & MHD_USE_IPv6) != 0) -#if HAVE_INET6 socket_fd = create_socket (PF_INET6, SOCK_STREAM, 0); -#else - { -#if HAVE_MESSAGES - MHD_DLOG (daemon, - "AF_INET6 not supported\n"); -#endif - goto free_and_fail; - } -#endif else socket_fd = create_socket (PF_INET, SOCK_STREAM, 0); if (-1 == socket_fd) @@ -2479,10 +2465,11 @@ MHD_start_daemon_va (unsigned int options, #if HAVE_PLIBC_FD if (SOCKET_ERROR == ioctlsocket (plibc_fd_get_handle (socket_fd), FIONBIO, &sk_flags)) + goto thread_failed; #else if (ioctlsocket (socket_fd, FIONBIO, &sk_flags) == SOCKET_ERROR) -#endif // PLIBC_FD goto thread_failed; +#endif // PLIBC_FD #endif // MINGW /* Allocate memory for pooled objects */ diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c @@ -58,10 +58,11 @@ enum PP_State PP_Nested_PerformMarking, PP_Nested_ProcessEntryHeaders, PP_Nested_ProcessValueToBoundary, - PP_Nested_PerformCleanup, + PP_Nested_PerformCleanup }; + enum RN_State { /** @@ -90,9 +91,10 @@ enum RN_State /** * Got a single dash, expect second dash. */ - RN_Dash2 = 4, + RN_Dash2 = 4 }; + /** * Bits for the globally known fields that * should not be deleted when we exit the @@ -104,9 +106,10 @@ enum NE_State NE_content_name = 1, NE_content_type = 2, NE_content_filename = 4, - NE_content_transfer_encoding = 8, + NE_content_transfer_encoding = 8 }; + /** * Internal state of the post-processor. Note that the fields * are sorted by type to enable optimal packing by the compiler. diff --git a/src/examples/fileserver_example_external_select.c b/src/examples/fileserver_example_external_select.c @@ -110,7 +110,7 @@ main (int argc, char *const *argv) fd_set ws; fd_set es; int max; - unsigned MHD_LONG_LONG mhd_timeout; + MHD_UNSIGNED_LONG_LONG mhd_timeout; if (argc != 3) { diff --git a/src/examples/post_example.c b/src/examples/post_example.c @@ -695,7 +695,7 @@ main (int argc, char *const *argv) fd_set ws; fd_set es; int max; - unsigned MHD_LONG_LONG mhd_timeout; + MHD_UNSIGNED_LONG_LONG mhd_timeout; if (argc != 2) { diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -147,14 +147,22 @@ extern "C" * standard int or a short. */ #ifndef MHD_LONG_LONG +/** + * @deprecated use MHD_UNSIGNED_LONG_LONG instead! + */ #define MHD_LONG_LONG long long +#define MHD_UNSIGNED_LONG_LONG unsigned long long #endif -#ifndef MHD_LONG_LONG_PRINTF /** * Format string for printing a variable of type 'MHD_LONG_LONG'. * You should only redefine this if you also define MHD_LONG_LONG. */ +#ifndef MHD_LONG_LONG_PRINTF +/** + * @deprecated use MHD_UNSIGNED_LONG_LONG_PRINTF instead! + */ #define MHD_LONG_LONG_PRINTF "ll" +#define MHD_UNSIGNED_LONG_LONG_PRINTF "%llu" #endif @@ -390,6 +398,16 @@ enum MHD_FLAG /** + * Type of a callback function used for logging by MHD. + * + * @param cls closure + * @param fm format string (printf-style) + * @param ap arguments to 'fm' + */ +typedef void (*MHD_LogCallback)(void *cls, const char *fm, va_list ap); + + +/** * MHD options. Passed in the varargs portion of MHD_start_daemon. */ enum MHD_OPTION @@ -518,6 +536,7 @@ enum MHD_OPTION * This option must be followed by two arguments; the * first must be a pointer to a function * of type "void fun(void * arg, const char * fmt, va_list ap)" + * (also known as MHD_LogCallback) * and the second a pointer "void*" which will * be passed as the "arg" argument to "fun". * <p> @@ -1151,7 +1170,7 @@ MHD_get_fdset (struct MHD_Daemon *daemon, * necessiate the use of a timeout right now). */ int MHD_get_timeout (struct MHD_Daemon *daemon, - unsigned MHD_LONG_LONG *timeout); + MHD_UNSIGNED_LONG_LONG *timeout); /** diff --git a/src/testcurl/perf_get_concurrent.c b/src/testcurl/perf_get_concurrent.c @@ -282,7 +282,7 @@ testExternalGet (int port) fd_set es; int max; struct timeval tv; - unsigned MHD_LONG_LONG tt; + MHD_UNSIGNED_LONG_LONG tt; int tret; d = MHD_start_daemon (MHD_USE_DEBUG,