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:
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 ();