commit 7cb018fd3364d37b36970b99f630e374d94b15b2
parent f78f507c193b87f1a0d1f019a00b5ba1152ff567
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 2 Mar 2012 23:00:11 +0000
changing order in which headers are returned to match the order in which we received them from the network
Diffstat:
6 files changed, 56 insertions(+), 31 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Mar 2 23:44:56 CET 2012
+ Making sure that MHD_get_connection_values iterates over the
+ headers in the order in which they were received. -CG
+
Wed Feb 1 09:39:12 CET 2012
Fixed compilation problem on MinGW. -BS
diff --git a/doc/microhttpd.texi b/doc/microhttpd.texi
@@ -1205,7 +1205,12 @@ right now).
Get all the headers matching @var{kind} from the request.
The @var{iterator} callback is invoked once for each header, with
-@var{iterator_cls} as first argument. Return the number of entries
+@var{iterator_cls} as first argument. After version 0.9.19, the
+headers are iterated in the same order as they were received from
+the network; previous versions iterated over the headers in reverse
+order.
+
+@code{MHD_get_connection_values} returns the number of entries
iterated over; this can be less than the number of headers if, while
iterating, @var{iterator} returns @code{MHD_NO}.
@@ -1224,8 +1229,8 @@ would contain the string ``key''.
@deftypefun int MHD_set_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char * key, const char * value)
-This function can be used to add an entry to
-the HTTP headers of a connection (so that the
+This function can be used to append an entry to
+the list of HTTP headers of a connection (so that the
@code{MHD_get_connection_values function} will return
them -- and the MHD PostProcessor will also
see them). This maybe required in certain
diff --git a/src/daemon/connection.c b/src/daemon/connection.c
@@ -144,8 +144,8 @@ MHD_get_connection_values (struct MHD_Connection *connection,
/**
- * This function can be used to add an entry to
- * the HTTP headers of a connection (so that the
+ * This function can be used to append an entry to
+ * the list of HTTP headers of a connection (so that the
* MHD_get_connection_values function will return
* them -- and the MHD PostProcessor will also
* see them). This maybe required in certain
@@ -186,8 +186,18 @@ MHD_set_connection_value (struct MHD_Connection *connection,
pos->header = (char *) key;
pos->value = (char *) value;
pos->kind = kind;
- pos->next = connection->headers_received;
- connection->headers_received = pos;
+ pos->next = NULL;
+ /* append 'pos' to the linked list of headers */
+ if (NULL == connection->headers_received_tail)
+ {
+ connection->headers_received = pos;
+ connection->headers_received_tail = pos;
+ }
+ else
+ {
+ connection->headers_received_tail->next = pos;
+ connection->headers_received_tail = pos;
+ }
return MHD_YES;
}
@@ -207,15 +217,11 @@ MHD_lookup_connection_value (struct MHD_Connection *connection,
{
struct MHD_HTTP_Header *pos;
- if (connection == NULL)
+ if (NULL == connection)
return NULL;
- pos = connection->headers_received;
- while (pos != NULL)
- {
- if ((0 != (pos->kind & kind)) && (0 == strcasecmp (key, pos->header)))
- return pos->value;
- pos = pos->next;
- }
+ for (pos = connection->headers_received; NULL != pos; pos = pos->next)
+ if ((0 != (pos->kind & kind)) && (0 == strcasecmp (key, pos->header)))
+ return pos->value;
return NULL;
}
@@ -1036,18 +1042,25 @@ get_next_header_line (struct MHD_Connection *connection)
return rbuf;
}
+
/**
+ * Add an entry to the HTTP headers of a connection. If this fails,
+ * transmit an error response (request too big).
+ *
+ * @param connection the connection for which a
+ * value should be set
+ * @param kind kind of the value
+ * @param key key for the value
+ * @param value the value itself
* @return MHD_NO on failure (out of memory), MHD_YES for success
*/
static int
connection_add_header (struct MHD_Connection *connection,
char *key, char *value, enum MHD_ValueKind kind)
{
- struct MHD_HTTP_Header *hdr;
-
- hdr = MHD_pool_allocate (connection->pool,
- sizeof (struct MHD_HTTP_Header), MHD_YES);
- if (hdr == NULL)
+ if (MHD_NO == MHD_set_connection_value (connection,
+ kind,
+ key, value))
{
#if HAVE_MESSAGES
MHD_DLOG (connection->daemon,
@@ -1057,14 +1070,10 @@ connection_add_header (struct MHD_Connection *connection,
REQUEST_TOO_BIG);
return MHD_NO;
}
- hdr->next = connection->headers_received;
- hdr->header = key;
- hdr->value = value;
- hdr->kind = kind;
- connection->headers_received = hdr;
return MHD_YES;
}
+
/**
* Parse and unescape the arguments given by the client as part
* of the HTTP request URI.
@@ -2289,6 +2298,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
connection->continue_message_write_offset = 0;
connection->responseCode = 0;
connection->headers_received = NULL;
+ connection->headers_received_tail = NULL;
connection->response_write_position = 0;
connection->have_chunked_upload = MHD_NO;
connection->method = NULL;
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
@@ -464,6 +464,11 @@ struct MHD_Connection
struct MHD_HTTP_Header *headers_received;
/**
+ * Tail of linked list of parsed headers.
+ */
+ struct MHD_HTTP_Header *headers_received_tail;
+
+ /**
* Response to transmit (initially NULL).
*/
struct MHD_Response *response;
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -106,7 +106,7 @@ extern "C"
/**
* Current version of the library.
*/
-#define MHD_VERSION 0x00091300
+#define MHD_VERSION 0x00091301
/**
* MHD-internal return code for "YES".
diff --git a/src/testcurl/daemontest_post_loop.c b/src/testcurl/daemontest_post_loop.c
@@ -432,7 +432,8 @@ testExternalPost ()
}
curl_multi_cleanup (multi);
MHD_stop_daemon (d);
- fprintf (stderr, "\n");
+ if (LOOPCOUNT >= 99)
+ fprintf (stderr, "\n");
return 0;
}
@@ -470,7 +471,7 @@ main (int argc, char *const *argv)
start_time = now();
errorCount += testInternalPost ();
fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s" : "%s: Sequential POSTs (http/1.0) %f/s",
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
"internal select",
(double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
GAUGER ("internal select",
@@ -480,7 +481,7 @@ main (int argc, char *const *argv)
start_time = now();
errorCount += testMultithreadedPost ();
fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s" : "%s: Sequential POSTs (http/1.0) %f/s",
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
"multithreaded post",
(double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
GAUGER ("Multithreaded select",
@@ -490,7 +491,7 @@ main (int argc, char *const *argv)
start_time = now();
errorCount += testMultithreadedPoolPost ();
fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s" : "%s: Sequential POSTs (http/1.0) %f/s",
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
"thread with pool",
(double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
GAUGER ("thread with pool",
@@ -500,7 +501,7 @@ main (int argc, char *const *argv)
start_time = now();
errorCount += testExternalPost ();
fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s" : "%s: Sequential POSTs (http/1.0) %f/s",
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
"external select",
(double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
GAUGER ("external select",