libmicrohttpd

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

commit fe43cf59f6679a0b73b0ab980a9b120f9a6e2e08
parent 1ea6af115589702923a795c4776135c3b1b37d06
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 13 Apr 2008 03:36:12 +0000

improved MHD handling of client programmer bugs in handling of upload data

Diffstat:
MChangeLog | 9+++++++--
Msrc/daemon/connection.c | 38++++++++++++++++++++++++++++++++++++--
Msrc/examples/Makefile.am | 7++++++-
Msrc/testcurl/daemontest_large_put.c | 13+++++++------
Msrc/testcurl/daemontest_postform.c | 7++-----
Msrc/testcurl/daemontest_put.c | 7++-----
Msrc/testcurl/daemontest_put_chunked.c | 7++-----
7 files changed, 62 insertions(+), 26 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,8 @@ +Sat Apr 12 21:34:26 MDT 2008 + Generate an internal server error if the programmer fails + to handle upload data correctly. Tweaked testcases to + avoid running into the problem in the testcases. -CG + Sat Apr 12 15:14:05 MDT 2008 Restructured the code (curl-testcases and zzuf testcases are now in different directories; code examples are in @@ -9,8 +14,8 @@ Sat Apr 12 15:14:05 MDT 2008 errors (such as request too large and malformed requests). Without that flag, the webpages returned will still be empty. - Added zzuf-based fuzzing-testcases (these require the - zzuf and socat binaries to be installed). + Started to add zzuf-based fuzzing-testcases (these require + the zzuf and socat binaries to be installed). -CG Fri Apr 11 20:20:34 MDT 2008 I hereby dub libmicrohttpd a GNU package. -Richard Stallman diff --git a/src/daemon/connection.c b/src/daemon/connection.c @@ -1,6 +1,6 @@ /* This file is part of libmicrohttpd - (C) 2007 Daniel Pittman and Christian Grothoff + (C) 2007, 2008 Daniel Pittman and Christian Grothoff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -82,6 +82,18 @@ #define REQUEST_MALFORMED "" #endif +/** + * Response text used when there is an internal server error. + * + * Intentionally empty here to keep our memory footprint + * minimal. + */ +#if HAVE_MESSAGES +#define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Some programmer needs to study the manual more carefully.</body></html>" +#else +#define INTERNAL_ERROR "" +#endif + #define EXTRA_CHECKS MHD_YES #if EXTRA_CHECKS @@ -676,7 +688,29 @@ MHD_connection_get_fdset (struct MHD_Connection *connection, break; case MHD_CONNECTION_CONTINUE_SENT: if (connection->read_buffer_offset == connection->read_buffer_size) - try_grow_read_buffer (connection); + { + if ((MHD_YES != try_grow_read_buffer (connection)) && + (0 != (connection->daemon->options & + (MHD_USE_SELECT_INTERNALLY | + MHD_USE_THREAD_PER_CONNECTION)))) + { + /* failed to grow the read buffer, and the + client which is supposed to handle the + received data in a *blocking* fashion + (in this mode) did not handle the data as + it was supposed to! + => we would either have to do busy-waiting + (on the client, which would likely fail), + or if we do nothing, we would just timeout + on the connection (if a timeout is even + set!). + Solution: we kill the connection with an error */ + transmit_error_response (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + INTERNAL_ERROR); + continue; + } + } if ((connection->read_buffer_offset < connection->read_buffer_size) && (MHD_NO == connection->read_closed)) do_fd_set (fd, read_fd_set, max_fd); diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am @@ -4,13 +4,18 @@ INCLUDES = -I$(top_srcdir)/src/include # example programs -noinst_PROGRAMS = minimal_example fileserver_example +noinst_PROGRAMS = minimal_example querystring_example fileserver_example minimal_example_SOURCES = \ minimal_example.c minimal_example_LDADD = \ $(top_builddir)/src/daemon/libmicrohttpd.la +querystring_example_SOURCES = \ + querystring_example.c +querystring_example_LDADD = \ + $(top_builddir)/src/daemon/libmicrohttpd.la + fileserver_example_SOURCES = \ fileserver_example.c fileserver_example_LDADD = \ diff --git a/src/testcurl/daemontest_large_put.c b/src/testcurl/daemontest_large_put.c @@ -41,8 +41,12 @@ static int oneone; * Do not make this much larger since we will hit the * MHD default buffer limit and the test code is not * written for incremental upload processing... + * (larger values will likely cause MHD to generate + * an internal server error -- which would be avoided + * by writing the putBuffer method in a more general + * fashion). */ -#define PUT_SIZE (512 * 1024) +#define PUT_SIZE (256 * 1024) static char *put_buffer; @@ -390,11 +394,8 @@ main (int argc, char *const *argv) return 2; put_buffer = malloc (PUT_SIZE); memset (put_buffer, 1, PUT_SIZE); - if (0) - { - errorCount += testInternalPut (); - errorCount += testMultithreadedPut (); - } + errorCount += testInternalPut (); + errorCount += testMultithreadedPut (); errorCount += testExternalPut (); free (put_buffer); if (errorCount != 0) diff --git a/src/testcurl/daemontest_postform.c b/src/testcurl/daemontest_postform.c @@ -392,11 +392,8 @@ main (int argc, char *const *argv) if (0 != curl_global_init (CURL_GLOBAL_WIN32)) return 2; errorCount += testInternalPost (); - if (0) - { - errorCount += testMultithreadedPost (); - errorCount += testExternalPost (); - } + errorCount += testMultithreadedPost (); + errorCount += testExternalPost (); if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", errorCount); curl_global_cleanup (); diff --git a/src/testcurl/daemontest_put.c b/src/testcurl/daemontest_put.c @@ -363,11 +363,8 @@ main (int argc, char *const *argv) if (0 != curl_global_init (CURL_GLOBAL_WIN32)) return 2; errorCount += testInternalPut (); - if (0) - { - errorCount += testMultithreadedPut (); - errorCount += testExternalPut (); - } + errorCount += testMultithreadedPut (); + errorCount += testExternalPut (); if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", errorCount); curl_global_cleanup (); diff --git a/src/testcurl/daemontest_put_chunked.c b/src/testcurl/daemontest_put_chunked.c @@ -371,11 +371,8 @@ main (int argc, char *const *argv) if (0 != curl_global_init (CURL_GLOBAL_WIN32)) return 2; errorCount += testInternalPut (); - if (0) - { - errorCount += testMultithreadedPut (); - errorCount += testExternalPut (); - } + errorCount += testMultithreadedPut (); + errorCount += testExternalPut (); if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", errorCount); curl_global_cleanup ();