libmicrohttpd

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

commit f710701c8241822b0869ba5feb95f33e61527efa
parent 2dedef2d861073db618bf67360877701c88d683e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 13 Jun 2010 08:47:17 +0000

clean up example code

Diffstat:
Msrc/daemon/daemon.c | 8++++++++
Msrc/examples/fileserver_example.c | 27++++++++++++++++++++-------
Msrc/examples/fileserver_example_dirs.c | 65++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/examples/fileserver_example_external_select.c | 17++++++++++++++---
Msrc/examples/https_fileserver_example.c | 6+++---
Msrc/examples/minimal_example.c | 6+++---
Msrc/examples/minimal_example_comet.c | 6+++---
Msrc/examples/querystring_example.c | 11++++++++---
Msrc/examples/refuse_post_example.c | 6+++---
Msrc/include/microhttpd.h | 6+++++-
10 files changed, 121 insertions(+), 37 deletions(-)

diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c @@ -1254,6 +1254,14 @@ parse_options_va (struct MHD_Daemon *daemon, break; case MHD_OPTION_THREAD_POOL_SIZE: daemon->worker_pool_size = va_arg (ap, unsigned int); + if (daemon->worker_pool_size >= SIZE_MAX / sizeof (struct MHD_Daemon)) + { +#if HAVE_MESSAGES + FPRINTF (stderr, + "Specified thread pool size too big\n"); +#endif + return MHD_NO; + } break; #if HTTPS_SUPPORT case MHD_OPTION_PROTOCOL_VERSION: diff --git a/src/examples/fileserver_example.c b/src/examples/fileserver_example.c @@ -38,6 +38,13 @@ file_reader (void *cls, uint64_t pos, char *buf, int max) return fread (buf, 1, max, file); } +static void +free_callback (void *cls) +{ + FILE *file = cls; + fclose (file); +} + static int ahc_echo (void *cls, struct MHD_Connection *connection, @@ -62,7 +69,10 @@ ahc_echo (void *cls, return MHD_YES; } *ptr = NULL; /* reset when done */ - file = fopen (&url[1], "rb"); + if (0 == stat (&url[1], &buf)) + file = fopen (&url[1], "rb"); + else + file = NULL; if (file == NULL) { response = MHD_create_response_from_data (strlen (PAGE), @@ -73,12 +83,15 @@ ahc_echo (void *cls, } else { - stat (&url[1], &buf); response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */ &file_reader, file, - (MHD_ContentReaderFreeCallback) - & fclose); + &free_callback); + if (response == NULL) + { + fclose (file); + return MHD_NO; + } ret = MHD_queue_response (connection, MHD_HTTP_OK, response); MHD_destroy_response (response); } @@ -90,9 +103,9 @@ main (int argc, char *const *argv) { struct MHD_Daemon *d; - if (argc != 3) + if (argc != 2) { - printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); + printf ("%s PORT\n", argv[0]); return 1; } d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, @@ -100,7 +113,7 @@ main (int argc, char *const *argv) NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); if (d == NULL) return 1; - sleep (atoi (argv[2])); + getc (stdin); MHD_stop_daemon (d); return 0; } diff --git a/src/examples/fileserver_example_dirs.c b/src/examples/fileserver_example_dirs.c @@ -39,16 +39,32 @@ file_reader (void *cls, uint64_t pos, char *buf, int max) return fread (buf, 1, max, file); } +static void +file_free_callback (void *cls) +{ + FILE *file = cls; + fclose (file); +} + +static void +dir_free_callback (void *cls) +{ + DIR *dir = cls; + if (dir != NULL) + closedir (dir); +} static int dir_reader (void *cls, uint64_t pos, char *buf, int max) { + DIR *dir = cls; struct dirent *e; + if (max < 512) return 0; do { - e = readdir (cls); + e = readdir (dir); if (e == NULL) return -1; } while (e->d_name[0] == '.'); @@ -72,7 +88,9 @@ ahc_echo (void *cls, struct MHD_Response *response; int ret; FILE *file; + DIR *dir; struct stat buf; + char emsg[1024]; if (0 != strcmp (method, MHD_HTTP_METHOD_GET)) return MHD_NO; /* unexpected method */ @@ -86,13 +104,39 @@ ahc_echo (void *cls, file = fopen (&url[1], "rb"); if (file == NULL) { - response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, - 32 * 1024, - &dir_reader, - opendir ("."), - (MHD_ContentReaderFreeCallback) &closedir); - ret = MHD_queue_response (connection, MHD_HTTP_OK, response); - MHD_destroy_response (response); + dir = opendir ("."); + if (dir == NULL) + { + /* most likely cause: more concurrent requests than + available file descriptors / 2 */ + snprintf (emsg, + sizeof (emsg), + "Failed to open directory `.': %s\n", + strerror (errno)); + response = MHD_create_response_from_data (strlen (emsg), + emsg, + MHD_NO, + MHD_YES); + if (response == NULL) + return MHD_NO; + ret = MHD_queue_response (connection, MHD_HTTP_SERVICE_UNAVAILABLE, response); + MHD_destroy_response (response); + } + else + { + response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, + 32 * 1024, + &dir_reader, + dir, + &dir_free_callback); + if (response == NULL) + { + closedir (dir); + return MHD_NO; + } + ret = MHD_queue_response (connection, MHD_HTTP_OK, response); + MHD_destroy_response (response); + } } else { @@ -100,8 +144,7 @@ ahc_echo (void *cls, response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */ &file_reader, file, - (MHD_ContentReaderFreeCallback) - & fclose); + &file_free_callback); ret = MHD_queue_response (connection, MHD_HTTP_OK, response); MHD_destroy_response (response); } @@ -123,7 +166,7 @@ main (int argc, char *const *argv) NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); if (d == NULL) return 1; - while (1) sleep (1); + getc (stdin); MHD_stop_daemon (d); return 0; } diff --git a/src/examples/fileserver_example_external_select.c b/src/examples/fileserver_example_external_select.c @@ -34,10 +34,17 @@ file_reader (void *cls, uint64_t pos, char *buf, int max) { FILE *file = cls; - fseek (file, pos, SEEK_SET); + (void) fseek (file, pos, SEEK_SET); return fread (buf, 1, max, file); } +static void +free_callback (void *cls) +{ + FILE *file = cls; + fclose (file); +} + static int ahc_echo (void *cls, struct MHD_Connection *connection, @@ -77,8 +84,12 @@ ahc_echo (void *cls, response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */ &file_reader, file, - (MHD_ContentReaderFreeCallback) - & fclose); + &free_callback); + if (response == NULL) + { + fclose (file); + return MHD_NO; + } ret = MHD_queue_response (connection, MHD_HTTP_OK, response); MHD_destroy_response (response); } diff --git a/src/examples/https_fileserver_example.c b/src/examples/https_fileserver_example.c @@ -158,7 +158,7 @@ main (int argc, char *const *argv) { struct MHD_Daemon *TLS_daemon; - if (argc == 3) + if (argc == 2) { /* TODO check if this is truly necessary - disallow usage of the blocking /dev/random */ /* gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); */ @@ -172,7 +172,7 @@ main (int argc, char *const *argv) } else { - printf ("Usage: %s HTTP-PORT SECONDS-TO-RUN\n", argv[0]); + printf ("Usage: %s HTTP-PORT\n", argv[0]); return 1; } @@ -186,7 +186,7 @@ main (int argc, char *const *argv) printf ("MHD daemon listening on port %d\n", atoi (argv[1])); } - sleep (atoi (argv[2])); + getc (stdin); MHD_stop_daemon (TLS_daemon); diff --git a/src/examples/minimal_example.c b/src/examples/minimal_example.c @@ -61,9 +61,9 @@ main (int argc, char *const *argv) { struct MHD_Daemon *d; - if (argc != 3) + if (argc != 2) { - printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); + printf ("%s PORT\n", argv[0]); return 1; } d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, @@ -71,7 +71,7 @@ main (int argc, char *const *argv) NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); if (d == NULL) return 1; - sleep (atoi (argv[2])); + getc (stdin); MHD_stop_daemon (d); return 0; } diff --git a/src/examples/minimal_example_comet.c b/src/examples/minimal_example_comet.c @@ -69,9 +69,9 @@ main (int argc, char *const *argv) { struct MHD_Daemon *d; - if (argc != 3) + if (argc != 2) { - printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); + printf ("%s PORT\n", argv[0]); return 1; } d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, @@ -79,7 +79,7 @@ main (int argc, char *const *argv) NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); if (d == NULL) return 1; - sleep (atoi (argv[2])); + getc (stdin); MHD_stop_daemon (d); return 0; } diff --git a/src/examples/querystring_example.c b/src/examples/querystring_example.c @@ -58,6 +58,11 @@ ahc_echo (void *cls, return MHD_NO; sprintf (me, fmt, "q", val); response = MHD_create_response_from_data (strlen (me), me, MHD_YES, MHD_NO); + if (response == NULL) + { + free (me); + return MHD_NO; + } ret = MHD_queue_response (connection, MHD_HTTP_OK, response); MHD_destroy_response (response); return ret; @@ -68,9 +73,9 @@ main (int argc, char *const *argv) { struct MHD_Daemon *d; - if (argc != 3) + if (argc != 2) { - printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); + printf ("%s PORT\n", argv[0]); return 1; } d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, @@ -78,7 +83,7 @@ main (int argc, char *const *argv) NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); if (d == NULL) return 1; - sleep (atoi (argv[2])); + getc (stdin); MHD_stop_daemon (d); return 0; } diff --git a/src/examples/refuse_post_example.c b/src/examples/refuse_post_example.c @@ -80,9 +80,9 @@ main (int argc, char *const *argv) { struct MHD_Daemon *d; - if (argc != 3) + if (argc != 2) { - printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); + printf ("%s PORT\n", argv[0]); return 1; } d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, @@ -91,7 +91,7 @@ main (int argc, char *const *argv) MHD_OPTION_END); if (d == NULL) return 1; - sleep (atoi (argv[2])); + getc (stdin); MHD_stop_daemon (d); return 0; } diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -1,6 +1,6 @@ /* This file is part of libmicrohttpd - (C) 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2006, 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -97,7 +97,11 @@ extern "C" * Constant used to indicate unknown size (use when * creating a response). */ +#ifdef UINT64_MAX +#define MHD_SIZE_UNKNOWN UINT64_MAX +#else #define MHD_SIZE_UNKNOWN ((uint64_t) -1LL) +#endif /** * HTTP response codes.