libmicrohttpd

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

commit f6f79e051afad06016d7854045937ff163853cd8
parent 17cfe877069e727a0cb820a7de0036ea9c4fcb82
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 11 Oct 2009 09:31:57 +0000

Dear Christian Grothoff

Thanks for libmicrohttpd! It's really useful for writing unit tests
for http clients and code interacting with http servers.

I mostly write code for Symbian, so I ported the library to Symbian
OS. You can see the patch at http://codereview.appspot.com/130056/show
. I'm not sure if you agree with how the changes have been structured,
but hopefully we can work towards a version that can be integrated.
Note that Symbian doesn't have autoconf and only a partial C library.

Best regards,

   Mika Raento


Diffstat:
MChangeLog | 3+++
Mdoc/microhttpd.texi | 7+++++--
Msrc/daemon/daemon.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/daemon/reason_phrase.c | 2+-
Msrc/include/platform.h | 2+-
Msrc/include/plibc.h | 18++++++++++++++++++
Msrc/testcurl/daemon_options_test.c | 8++++++++
Asymbian/MHD_config.h | 261+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asymbian/README.txt | 9+++++++++
Asymbian/SConstruct | 39+++++++++++++++++++++++++++++++++++++++
10 files changed, 398 insertions(+), 26 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,6 @@ +Sun Oct 11 11:24:27 CEST 2009 + Adding support for Symbian. -MR + Fri Oct 9 15:21:29 CEST 2009 Check for error codes from pthread operations (to help with error diagnostics) and abort if something went wrong. -CG diff --git a/doc/microhttpd.texi b/doc/microhttpd.texi @@ -204,7 +204,10 @@ the process and will call the appropriate microhttpd callbacks. Starting the daemon may also fail if a particular option is not implemented or not supported on the target platform (i.e. no support for -@acronym{SSL}, threads or IPv6). +@acronym{SSL}, threads or IPv6). SSL support generally depends on +options given during @mhd{} compilation. Threaded operations +(including @code{MHD_USE_SELECT_INTERNALLY}) are not supported on +Symbian. @table @code @item MHD_NO_FLAG @@ -252,7 +255,7 @@ list. @item MHD_OPTION_CONNECTION_MEMORY_LIMIT Maximum memory size per connection (followed by a @code{size_t}). The -default is 1 MB (1024*1024 bytes) as defined by the internal constant +default is 32 kB (32*1024 bytes) as defined by the internal constant @code{MHD_POOL_SIZE_DEFAULT}. @item MHD_OPTION_CONNECTION_LIMIT diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c @@ -44,7 +44,7 @@ /** * Default memory allowed per connection. */ -#define MHD_POOL_SIZE_DEFAULT (1024 * 1024) +#define MHD_POOL_SIZE_DEFAULT (32 * 1024) /** * Print extra messages with reasons for closing @@ -62,7 +62,18 @@ #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 #endif +#endif + +#ifdef __SYMBIAN32__ +static void pthread_kill (int, int) { + // Symbian doesn't have signals. The user of the library is required to + // run it in an external select loop. + abort(); +} +#endif // __SYMBIAN32__ /** * Trace up to and return master daemon. If the supplied daemon @@ -202,7 +213,7 @@ MHD_ip_limit_add(struct MHD_Daemon *daemon, MHD_ip_count_lock (daemon); /* Search for the IP address */ - node = TSEARCH (key, &daemon->per_ip_connection_count, MHD_ip_addr_compare); + node = (void*)TSEARCH (key, &daemon->per_ip_connection_count, MHD_ip_addr_compare); if (!node) { #if HAVE_MESSAGES @@ -254,7 +265,7 @@ MHD_ip_limit_del(struct MHD_Daemon *daemon, MHD_ip_count_lock (daemon); /* Search for the IP address */ - node = TFIND (&search_key, &daemon->per_ip_connection_count, MHD_ip_addr_compare); + node = (void*)TFIND (&search_key, &daemon->per_ip_connection_count, MHD_ip_addr_compare); /* Something's wrong if we couldn't find an IP address * that was previously added */ @@ -471,11 +482,11 @@ MHD_handle_connection (void *data) tv.tv_sec = 0; if ((con->state == MHD_CONNECTION_NORMAL_BODY_UNREADY) || (con->state == MHD_CONNECTION_CHUNKED_BODY_UNREADY)) - { + { /* do not block (we're waiting for our callback to succeed) */ - timeout = 1; - tv.tv_sec = 0; - } + timeout = 1; + tv.tv_sec = 0; + } num_ready = SELECT (max + 1, &rs, &ws, &es, (timeout != 0) ? &tv : NULL); if (num_ready < 0) @@ -1017,6 +1028,8 @@ MHD_start_daemon (unsigned int options, } +typedef void (*VfprintfFunctionPointerType)(void *, const char *, va_list); + /** * Start a webserver on the given port. * @@ -1053,7 +1066,7 @@ MHD_start_daemon_va (unsigned int options, if (retVal == NULL) return NULL; memset (retVal, 0, sizeof (struct MHD_Daemon)); - retVal->options = options; + retVal->options = (enum MHD_OPTION)options; retVal->port = port; retVal->apc = apc; retVal->apc_cls = apc_cls; @@ -1143,13 +1156,13 @@ MHD_start_daemon_va (unsigned int options, case MHD_OPTION_EXTERNAL_LOGGER: #if HAVE_MESSAGES retVal->custom_error_log = - va_arg (ap, void (*)(void *cls, const char *, va_list)); + va_arg (ap, VfprintfFunctionPointerType); retVal->custom_error_log_cls = va_arg (ap, void *); #else - va_arg (ap, void (*)(void *cls, const char *, ...)); + va_arg (ap, VfprintfFunctionPointerType); va_arg (ap, void *); #endif - break; + break; default: #if HAVE_MESSAGES if ((opt >= MHD_OPTION_HTTPS_MEM_KEY) && @@ -1182,6 +1195,17 @@ MHD_start_daemon_va (unsigned int options, return NULL; } +#ifdef __SYMBIAN32__ + if (0 != (OPTIONS & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) + { +#if HAVE_MESSAGES + fprintf (stderr, + "Threaded operations are not supported on Symbian.\n"); +#endif + free (retVal); + return NULL; + } +#endif if ((options & MHD_USE_IPv6) != 0) #if HAVE_INET6 socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0); @@ -1209,9 +1233,9 @@ MHD_start_daemon_va (unsigned int options, #if HAVE_MESSAGES if ((options & MHD_USE_DEBUG) != 0) FPRINTF (stderr, - "Socket descriptor larger than FD_SETSIZE: %d > %d\n", - socket_fd, - FD_SETSIZE); + "Socket descriptor larger than FD_SETSIZE: %d > %d\n", + socket_fd, + FD_SETSIZE); #endif CLOSE (socket_fd); return NULL; @@ -1265,7 +1289,6 @@ MHD_start_daemon_va (unsigned int options, return NULL; } - if (LISTEN (socket_fd, 20) < 0) { #if HAVE_MESSAGES @@ -1359,7 +1382,7 @@ MHD_start_daemon_va (unsigned int options, retVal->worker_pool = malloc (sizeof (struct MHD_Daemon) * retVal->worker_pool_size); if (NULL == retVal->worker_pool) - goto thread_failed; + goto thread_failed; /* Start the workers in the pool */ for (i = 0; i < retVal->worker_pool_size; ++i) @@ -1369,8 +1392,8 @@ MHD_start_daemon_va (unsigned int options, memcpy (d, retVal, sizeof (struct MHD_Daemon)); /* Adjust pooling params for worker daemons; note that memcpy() - has already copied MHD_USE_SELECT_INTERNALLY thread model into - the worker threads. */ + has already copied MHD_USE_SELECT_INTERNALLY thread model into + the worker threads. */ d->master = retVal; d->worker_pool_size = 0; d->worker_pool = NULL; @@ -1393,7 +1416,7 @@ MHD_start_daemon_va (unsigned int options, * all previously-created workers. */ goto thread_failed; } - } + } } return retVal; @@ -1407,7 +1430,7 @@ thread_failed: CLOSE (socket_fd); pthread_mutex_destroy (&retVal->per_ip_connection_mutex); if (NULL != retVal->worker_pool) - free (retVal->worker_pool); + free (retVal->worker_pool); free (retVal); return NULL; } @@ -1597,11 +1620,19 @@ sigalrmHandler (int sig) } #endif +#ifdef __GNUC__ +#define ATTRIBUTE_CONSTRUCTOR __attribute__ ((constructor)) +#define ATTRIBUTE_DESTRUCTOR __attribute__ ((destructor)) +#else // !__GNUC__ +#define ATTRIBUTE_CONSTRUCTOR +#define ATTRIBUTE_DESTRUCTOR +#endif // __GNUC__ + /** * Initialize the signal handler for SIGALRM * and do other setup work. */ -void __attribute__ ((constructor)) MHD_init () +void ATTRIBUTE_CONSTRUCTOR MHD_init () { #ifndef WINDOWS /* make sure SIGALRM does not kill us */ @@ -1619,7 +1650,7 @@ void __attribute__ ((constructor)) MHD_init () #endif } -void __attribute__ ((destructor)) MHD_fini () +void ATTRIBUTE_DESTRUCTOR MHD_fini () { #if HTTPS_SUPPORT if (0 != pthread_mutex_destroy(&MHD_gnutls_init_mutex)) diff --git a/src/daemon/reason_phrase.c b/src/daemon/reason_phrase.c @@ -27,7 +27,7 @@ #include "reason_phrase.h" -static const char *invalid_hundred[] = { }; +static const char *invalid_hundred[] = { NULL }; static const char *one_hundred[] = { "Continue", diff --git a/src/include/platform.h b/src/include/platform.h @@ -53,7 +53,7 @@ #include <errno.h> #include <fcntl.h> #include <signal.h> -#ifndef MINGW +#if !defined(MINGW) && !defined(__SYMBIAN32__) #include <search.h> #endif #include <stddef.h> diff --git a/src/include/plibc.h b/src/include/plibc.h @@ -532,6 +532,8 @@ extern "C" #define GETTIMEOFDAY(t, n) gettimeofday(t, n) #define INSQUE(e, p) insque(e, p) #define REMQUE(e) remque(e) + +#ifndef __SYMBIAN32__ #define HSEARCH(i, a) hsearch(i, a) #define HCREATE(n) hcreate(n) #define HDESTROY() hdestroy() @@ -545,6 +547,22 @@ extern "C" #define TDESTROY(r, f) tdestroy(r, f) #define LFIND(k, b, n, s, c) lfind(k, b, n, s, c) #define LSEARCH(k, b, n, s, c) lsearch(k, b, n, s, c) +#else // __SYMBIAN32__ +#define HSEARCH(i, a) _win_hsearch(i, a) +#define HCREATE(n) _win_hcreate(n) +#define HDESTROY() _win_hdestroy() +#define HSEARCH_R(i, a, r, h) _win_hsearch_r(i, a, r, h) +#define HCREATE_R(n, h) _win_hcreate_r(n, h) +#define HDESTROY_R(h) _win_hdestroy_r(h) +#define TSEARCH(k, r, c) _win_tsearch(k, r, c) +#define TFIND(k, r, c) _win_tfind(k, r, c) +#define TDELETE(k, r, c) _win_tdelete(k, r, c) +#define TWALK(r, a) _win_twalk(r, a) +#define TDESTROY(r, f) _win_tdestroy(r, f) +#define LFIND(k, b, n, s, c) _win_lfind(k, b, n, s, c) +#define LSEARCH(k, b, n, s, c) _win_lsearch(k, b, n, s, c) +#endif // !__SYMBIAN32__ + #else #define DIR_SEPARATOR '\\' #define DIR_SEPARATOR_STR "\\" diff --git a/src/testcurl/daemon_options_test.c b/src/testcurl/daemon_options_test.c @@ -73,18 +73,24 @@ test_ip_addr_option () { struct MHD_Daemon *d; struct sockaddr_in daemon_ip_addr; +#if HAVE_INET6 struct sockaddr_in6 daemon_ip_addr6; +#endif memset (&daemon_ip_addr, 0, sizeof (struct sockaddr_in)); daemon_ip_addr.sin_family = AF_INET; daemon_ip_addr.sin_port = htons (42433); +#if HAVE_INET6 memset (&daemon_ip_addr6, 0, sizeof (struct sockaddr_in6)); daemon_ip_addr6.sin6_family = AF_INET6; daemon_ip_addr6.sin6_port = htons (42433); +#endif inet_pton (AF_INET, "127.0.0.1", &daemon_ip_addr.sin_addr); +#if HAVE_INET6 inet_pton (AF_INET6, "::ffff:127.0.0.1", &daemon_ip_addr6.sin6_addr); +#endif d = MHD_start_daemon (MHD_USE_DEBUG, 42433, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR, @@ -95,6 +101,7 @@ test_ip_addr_option () MHD_stop_daemon (d); +#if HAVE_INET6 d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_IPv6, 42433, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR, &daemon_ip_addr6, MHD_OPTION_END); @@ -103,6 +110,7 @@ test_ip_addr_option () return -1; MHD_stop_daemon (d); +#endif return 0; } diff --git a/symbian/MHD_config.h b/symbian/MHD_config.h @@ -0,0 +1,261 @@ +/* MHD_config.h. Generated from MHD_config.h.in by configure. */ +/* MHD_config.h.in. Generated from configure.ac by autoheader. */ + +#define _GNU_SOURCE 1 + +/* This is a Cygwin system */ +#define CYGWIN 1 + +/* This is a FreeBSD system */ +/* #undef FREEBSD */ + +/* GNULIB_GC_RANDOM */ +#define GNULIB_GC_RANDOM 1 + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the declaration of `TCP_CORK', and to 0 if you + don't. */ +#define HAVE_DECL_TCP_CORK 0 + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <errno.h> header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#define HAVE_FSEEKO 1 + +/* Provides IPv6 headers */ +#undef HAVE_INET6 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have a functional curl library. */ +#define HAVE_LIBCURL 1 + +/* Define to 1 if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the <locale.h> header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the <math.h> header file. */ +#define HAVE_MATH_H 1 + +/* Define to 1 if you have the `memmem' function. */ +#define HAVE_MEMMEM 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Include error messages */ +#define HAVE_MESSAGES 1 + +/* Define to 1 if you have the <netdb.h> header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the <netinet/tcp.h> header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the <pthread.h> header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdio.h> header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/mman.h> header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define to 1 if you have the <sys/msg.h> header file. */ +#define HAVE_SYS_MSG_H 1 + +/* Define to 1 if you have the <sys/select.h> header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <time.h> header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* disable HTTPS support */ +#define HTTPS_SUPPORT 0 + +/* Defined if libcurl supports AsynchDNS */ +/* #undef LIBCURL_FEATURE_ASYNCHDNS */ + +/* Defined if libcurl supports IDN */ +/* #undef LIBCURL_FEATURE_IDN */ + +/* Defined if libcurl supports IPv6 */ +/* #undef LIBCURL_FEATURE_IPV6 */ + +/* Defined if libcurl supports KRB4 */ +/* #undef LIBCURL_FEATURE_KRB4 */ + +/* Defined if libcurl supports libz */ +#define LIBCURL_FEATURE_LIBZ 1 + +/* Defined if libcurl supports NTLM */ +#define LIBCURL_FEATURE_NTLM 1 + +/* Defined if libcurl supports SSL */ +#define LIBCURL_FEATURE_SSL 1 + +/* Defined if libcurl supports SSPI */ +/* #undef LIBCURL_FEATURE_SSPI */ + +/* Defined if libcurl supports DICT */ +#define LIBCURL_PROTOCOL_DICT 1 + +/* Defined if libcurl supports FILE */ +#define LIBCURL_PROTOCOL_FILE 1 + +/* Defined if libcurl supports FTP */ +#define LIBCURL_PROTOCOL_FTP 1 + +/* Defined if libcurl supports FTPS */ +#define LIBCURL_PROTOCOL_FTPS 1 + +/* Defined if libcurl supports HTTP */ +#define LIBCURL_PROTOCOL_HTTP 1 + +/* Defined if libcurl supports HTTPS */ +#define LIBCURL_PROTOCOL_HTTPS 1 + +/* Defined if libcurl supports LDAP */ +#define LIBCURL_PROTOCOL_LDAP 1 + +/* Defined if libcurl supports TELNET */ +#define LIBCURL_PROTOCOL_TELNET 1 + +/* Defined if libcurl supports TFTP */ +#define LIBCURL_PROTOCOL_TFTP 1 + +/* This is a Linux system */ +/* #undef LINUX */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Compile client side code. This will enable running some test cases. */ +#define MHD_DEBUG_TLS 0 + +/* gcrypt lib version */ +#define MHD_GCRYPT_VERSION "1:1.2.4" + +/* gnuTLS lib version - used in conjunction with cURL */ +#define MHD_REQ_CURL_GNUTLS_VERSION "2.2.3" + +/* required cURL SSL version to run tests */ +#define MHD_REQ_CURL_OPENSSL_VERSION "0.9.8" + +/* required cURL version to run tests */ +#define MHD_REQ_CURL_VERSION "7.16.4" + +/* This is a MinGW system */ +/* #undef MINGW */ + +/* This is a NetBSD system */ +/* #undef NETBSD */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* This is an OpenBSD system */ +/* #undef OPENBSD */ + +/* This is a OS/390 system */ +/* #undef OS390 */ + +/* This is an OS X system */ +/* #undef OSX */ + +/* Some strange OS */ +/* #undef OTHEROS */ + +/* Name of package */ +#define PACKAGE "libmicrohttpd" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libmicrohttpd@gnu.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libmicrohttpd" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libmicrohttpd 0.4.2" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libmicrohttpd" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.4.2" + +/* This is a Solaris system */ +/* #undef SOLARIS */ + +/* This is a BSD system */ +/* #undef SOMEBSD */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.4.2" + +/* This is a Windows system */ +/* #undef WINDOWS */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* #undef _LARGEFILE_SOURCE */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Need with solaris or errno doesnt work */ +/* #undef _REENTRANT */ + +/* Define curl_free() as free() if our version of curl lacks curl_free. */ +/* #undef curl_free */ diff --git a/symbian/README.txt b/symbian/README.txt @@ -0,0 +1,9 @@ +This directory contains a MHD_config.h that allows compilation on Symbian OS 9 +with OpenC 1.6 (possibly earlier and later versions too) and plibc. It also +contains a Scons-for-Symbian (http://code.google.com/p/scons-for-symbian/) +SConstruct file that compiler the code into a static library, as an example +of how to use this. It assumes that plibc is checked out into <libmicrohttpd +directory>/../plibc. + +Since Symbian lacks POSIX signals you need to run this in 'external select +loop' mode. diff --git a/symbian/SConstruct b/symbian/SConstruct @@ -0,0 +1,39 @@ +from scons_symbian import * + +def MicroHttpd(): + target = "microhttpd" + targettype = "lib" + libraries = [ "euser", "libc", "libstdcpp" ] + + uid3 = 0 + + sources = Glob("../src/daemon/*c", strings = True) + sources += Glob("../../plibc/src/*search.c", strings = True) + sources = [ s for s in sources if s.find("test") < 0 ] + sources = [ s for s in sources if s.find("https") < 0 ] + + includes = ['.', + '../src/include', + '../../libc/src/include', + ] + sysincludes = [ EPOC32_INCLUDE, + join(EPOC32_INCLUDE, 'stdapis'), + join(EPOC32_INCLUDE, 'stdapis', 'stlport'), + join(EPOC32_INCLUDE, 'libc'), + ] + defines = [ + "_STLP_NO_WCHAR_T", + ] + + return SymbianProgram( target, targettype, + sources = sources, + includes = includes, + sysincludes = sysincludes, + libraries = libraries, + defines = defines, + epocstacksize = 8192, + epocheapsize = (0x1000,0x100000), + uid3 = uid3, + ) + +microhttpd = MicroHttpd()