summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2008-03-25 19:47:23 +0000
committerChristian Grothoff <christian@grothoff.org>2008-03-25 19:47:23 +0000
commit4a9bb6522a5dcb991e69ad8b975df6e616a5238f (patch)
tree549039f036ecf2ad7b1f9d31b7020dee9832828a
parentafc6633ee8d1c5338b956f04a4c0b4d715b6278e (diff)
Alex's patches
-rw-r--r--ChangeLog18
-rw-r--r--configure.ac4
-rw-r--r--src/daemon/Makefile.am2
-rw-r--r--src/daemon/connection.c18
-rw-r--r--src/daemon/daemon.c77
-rw-r--r--src/daemon/minimal_example.c5
-rw-r--r--src/daemon/postprocessor.c745
-rw-r--r--src/daemon/postprocessor_test.c159
-rw-r--r--src/daemon/response.c8
9 files changed, 517 insertions, 519 deletions
diff --git a/ChangeLog b/ChangeLog
index d9887909..66b047f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Tue Mar 25 13:40:53 MDT 2008
+ Prevent multi-part post-processor from going to error
+ state when the input buffer is full and current token
+ just changes processor state without consuming any data.
+ Also, the original implementation would not consume any
+ input in process_value_to_boundary if there is no new
+ line character in sight. -AS
+
+ Remove checks for request method after it finished writing
+ response footers as it's only _pipelined_ requests that
+ should not be allowed after POST or PUT requests. Reusing
+ the existing connection is perfectly ok though. And there
+ is no reliable way to detect pipelining on server side
+ anyway so it is the client's responsibility to not send new
+ data before it gets a response after a POST operation. -AS
+
+ Clarified license in man page. -CG
+
Sat Mar 22 01:12:38 MDT 2008
Releasing libmicrohttpd 0.2.2. -CG
diff --git a/configure.ac b/configure.ac
index 4413681e..975bb519 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,8 +21,8 @@
#
#
AC_PREREQ(2.57)
-AC_INIT([libmicrohttpd], [0.2.2],[libmicrohttpd@gnunet.org])
-AM_INIT_AUTOMAKE([libmicrohttpd], [0.2.2])
+AC_INIT([libmicrohttpd], [0.2.3],[libmicrohttpd@gnunet.org])
+AM_INIT_AUTOMAKE([libmicrohttpd], [0.2.3])
AM_CONFIG_HEADER([config.h])
AH_TOP([#define _GNU_SOURCE 1])
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index 254dab8c..b2f58c94 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -12,7 +12,7 @@ lib_LTLIBRARIES = \
libmicrohttpd.la
libmicrohttpd_la_LDFLAGS = \
- -export-dynamic -version-info 3:1:0 $(retaincommand)
+ -export-dynamic -version-info 3:2:0 $(retaincommand)
libmicrohttpd_la_SOURCES = \
connection.c connection.h \
reason_phrase.c reason_phrase.h \
diff --git a/src/daemon/connection.c b/src/daemon/connection.c
index 08b503d7..60cbfe43 100644
--- a/src/daemon/connection.c
+++ b/src/daemon/connection.c
@@ -654,9 +654,9 @@ MHD_connection_get_fdset (struct MHD_Connection *connection,
case MHD_CONNECTION_CONTINUE_SENT:
if (connection->read_buffer_offset == connection->read_buffer_size)
try_grow_read_buffer (connection);
- if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
- (MHD_NO == connection->read_closed) )
- do_fd_set (fd, read_fd_set, max_fd);
+ if ((connection->read_buffer_offset < connection->read_buffer_size)
+ && (MHD_NO == connection->read_closed))
+ do_fd_set (fd, read_fd_set, max_fd);
break;
case MHD_CONNECTION_BODY_RECEIVED:
case MHD_CONNECTION_FOOTER_PART_RECEIVED:
@@ -1797,13 +1797,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
if (((MHD_YES == connection->read_closed) &&
(0 == connection->read_buffer_offset)) ||
(connection->version == NULL) ||
- (connection->method == NULL) ||
- ( (0 != strcasecmp (MHD_HTTP_METHOD_HEAD, connection->method)) &&
- (0 != strcasecmp (MHD_HTTP_METHOD_GET, connection->method)) ) ||
- (0 != strcasecmp (MHD_HTTP_VERSION_1_1, connection->version)))
+ (0 != strcasecmp (MHD_HTTP_VERSION_1_1, connection->version)))
{
- /* http 1.0, version-less or non-HEAD/GET requests cannot be
- pipelined */
+ /* http 1.0, version-less requests cannot be pipelined */
connection->state = MHD_CONNECTION_CLOSED;
MHD_pool_destroy (connection->pool);
connection->pool = NULL;
@@ -1832,8 +1828,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
break;
}
timeout = connection->daemon->connection_timeout;
- if ( (connection->socket_fd != -1) &&
- (timeout != 0) && (time (NULL) - timeout > connection->last_activity))
+ if ((connection->socket_fd != -1) &&
+ (timeout != 0) && (time (NULL) - timeout > connection->last_activity))
{
connection_close_error (connection);
return MHD_NO;
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index e971c9b2..971196f8 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -172,7 +172,7 @@ MHD_handle_connection (void *data)
static int
MHD_accept_connection (struct MHD_Daemon *daemon)
{
- struct MHD_Connection *pos;
+ struct MHD_Connection *pos;
struct MHD_Connection *connection;
struct sockaddr_in6 addr6;
struct sockaddr *addr = (struct sockaddr *) &addr6;
@@ -204,42 +204,44 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
#if DEBUG_CONNECT
MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
#endif
- have = 0;
- if ( (daemon->per_ip_connection_limit != 0) &&
- (daemon->max_connections > 0) )
+ have = 0;
+ if ((daemon->per_ip_connection_limit != 0) && (daemon->max_connections > 0))
{
pos = daemon->connections;
- while (pos != NULL)
- {
- if ( (pos->addr != NULL) &&
- (pos->addr_len == addrlen) )
- {
- if (addrlen == sizeof(struct sockaddr_in))
- {
- const struct sockaddr_in * a1 = (const struct sockaddr_in *) &addr;
- const struct sockaddr_in * a2 = (const struct sockaddr_in *) pos->addr;
- if (0 == memcmp(&a1->sin_addr,
- &a2->sin_addr,
- sizeof(struct in_addr)))
- have++;
- }
- if (addrlen == sizeof(struct sockaddr_in6))
- {
- const struct sockaddr_in6 * a1 = (const struct sockaddr_in6 *) &addr;
- const struct sockaddr_in6 * a2 = (const struct sockaddr_in6 *) pos->addr;
- if (0 == memcmp(&a1->sin6_addr,
- &a2->sin6_addr,
- sizeof(struct in6_addr)))
- have++;
- }
- }
- pos = pos->next;
- }
+ while (pos != NULL)
+ {
+ if ((pos->addr != NULL) && (pos->addr_len == addrlen))
+ {
+ if (addrlen == sizeof (struct sockaddr_in))
+ {
+ const struct sockaddr_in *a1 =
+ (const struct sockaddr_in *) &addr;
+ const struct sockaddr_in *a2 =
+ (const struct sockaddr_in *) pos->addr;
+ if (0 ==
+ memcmp (&a1->sin_addr, &a2->sin_addr,
+ sizeof (struct in_addr)))
+ have++;
+ }
+ if (addrlen == sizeof (struct sockaddr_in6))
+ {
+ const struct sockaddr_in6 *a1 =
+ (const struct sockaddr_in6 *) &addr;
+ const struct sockaddr_in6 *a2 =
+ (const struct sockaddr_in6 *) pos->addr;
+ if (0 ==
+ memcmp (&a1->sin6_addr, &a2->sin6_addr,
+ sizeof (struct in6_addr)))
+ have++;
+ }
+ }
+ pos = pos->next;
+ }
}
- if ( (daemon->max_connections == 0) ||
- ( (daemon->per_ip_connection_limit != 0) &&
- (daemon->per_ip_connection_limit <= have) ) )
+ if ((daemon->max_connections == 0) ||
+ ((daemon->per_ip_connection_limit != 0) &&
+ (daemon->per_ip_connection_limit <= have)))
{
/* above connection limit - reject */
#if HAVE_MESSAGES
@@ -635,7 +637,7 @@ MHD_start_daemon (unsigned int options,
retVal = malloc (sizeof (struct MHD_Daemon));
if (retVal == NULL)
{
- CLOSE(socket_fd);
+ CLOSE (socket_fd);
return NULL;
}
memset (retVal, 0, sizeof (struct MHD_Daemon));
@@ -668,10 +670,9 @@ MHD_start_daemon (unsigned int options,
va_arg (ap, MHD_RequestCompletedCallback);
retVal->notify_completed_cls = va_arg (ap, void *);
break;
- case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
- retVal->per_ip_connection_limit
- = va_arg (ap, unsigned int);
- break;
+ case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
+ retVal->per_ip_connection_limit = va_arg (ap, unsigned int);
+ break;
default:
#if HAVE_MESSAGES
fprintf (stderr,
diff --git a/src/daemon/minimal_example.c b/src/daemon/minimal_example.c
index 0cbf3a14..647a4776 100644
--- a/src/daemon/minimal_example.c
+++ b/src/daemon/minimal_example.c
@@ -40,9 +40,8 @@ ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
- const char *version,
- const char *upload_data,
- unsigned int *upload_data_size, void **ptr)
+ const char *version,
+ const char *upload_data, unsigned int *upload_data_size, void **ptr)
{
static int aptr;
const char *me = cls;
diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c
index 5b8f01a2..8be3ee89 100644
--- a/src/daemon/postprocessor.c
+++ b/src/daemon/postprocessor.c
@@ -40,13 +40,13 @@ enum PP_State
PP_Done,
PP_Init,
- /* url encoding-states*/
- PP_ProcessValue,
- PP_ExpectNewLine,
+ /* url encoding-states */
+ PP_ProcessValue,
+ PP_ExpectNewLine,
/* post encoding-states */
PP_ProcessEntryHeaders,
- PP_PerformCheckMultipart,
+ PP_PerformCheckMultipart,
PP_ProcessValueToBoundary,
PP_PerformCleanup,
@@ -56,7 +56,7 @@ enum PP_State
PP_Nested_ProcessEntryHeaders,
PP_Nested_ProcessValueToBoundary,
PP_Nested_PerformCleanup,
-
+
};
enum RN_State
@@ -76,11 +76,11 @@ enum RN_State
* Expect '\r\n' (and only '\r\n'). As always, we also
* expect only '\r' or only '\n'.
*/
- RN_Full = 2,
+ RN_Full = 2,
/**
* Expect either '\r\n' or '--\r\n'. If '--\r\n', transition into dash-state
- * for the main state machine
+ * for the main state machine
*/
RN_Dash = 3,
@@ -94,8 +94,8 @@ enum RN_State
* Bits for the globally known fields that
* should not be deleted when we exit the
* nested state.
- */
-enum NE_State
+ */
+enum NE_State
{
NE_none = 0,
NE_content_name = 1,
@@ -136,12 +136,12 @@ struct MHD_PostProcessor
/**
* Primary boundary (points into encoding string)
*/
- const char * boundary;
+ const char *boundary;
/**
- * Nested boundary (if we have multipart/mixed encoding).
+ * Nested boundary (if we have multipart/mixed encoding).
*/
- char * nested_boundary;
+ char *nested_boundary;
/**
* Pointer to the name given in disposition.
@@ -263,23 +263,22 @@ MHD_create_post_processor (struct MHD_Connection *connection,
if (encoding == NULL)
return NULL;
boundary = NULL;
- if (0 != strcasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
- encoding))
+ if (0 != strcasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, encoding))
{
- if (0 != strncasecmp (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, encoding,
- strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
- return NULL;
+ if (0 !=
+ strncasecmp (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, encoding,
+ strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
+ return NULL;
boundary =
- &encoding[strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
+ &encoding[strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
/* Q: should this be "strcasestr"? */
if (NULL != strstr (boundary, "boundary="))
- boundary = strstr (boundary, "boundary=") + strlen ("boundary=");
+ boundary = strstr (boundary, "boundary=") + strlen ("boundary=");
else
- return NULL; /* failed to determine boundary */
+ return NULL; /* failed to determine boundary */
blen = strlen (boundary);
- if ( (blen == 0) ||
- (blen * 2 + 2 > buffer_size) )
- return NULL; /* (will be) out of memory or invalid boundary */
+ if ((blen == 0) || (blen * 2 + 2 > buffer_size))
+ return NULL; /* (will be) out of memory or invalid boundary */
}
else
blen = 0;
@@ -322,10 +321,10 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
{
case PP_Error:
return MHD_NO;
- case PP_Done:
- /* did not expect to receive more data */
- pp->state = PP_Error;
- return MHD_NO;
+ case PP_Done:
+ /* did not expect to receive more data */
+ pp->state = PP_Error;
+ return MHD_NO;
case PP_Init:
equals = 0;
while ((equals + poff < post_data_len) &&
@@ -444,39 +443,37 @@ try_match_header (const char *prefix, char *line, char **suffix)
{
if (NULL != *suffix)
return MHD_NO;
- while(*line != 0)
+ while (*line != 0)
{
- if (0 == strncasecmp (prefix, line, strlen (prefix)))
- {
- *suffix = strdup (&line[strlen (prefix)]);
- return MHD_YES;
- }
- ++line;
+ if (0 == strncasecmp (prefix, line, strlen (prefix)))
+ {
+ *suffix = strdup (&line[strlen (prefix)]);
+ return MHD_YES;
+ }
+ ++line;
}
return MHD_NO;
}
static int
-find_boundary(struct MHD_PostProcessor * pp,
- const char * boundary,
- size_t blen,
- unsigned int * ioffptr,
- enum PP_State next_state,
- enum PP_State next_dash_state)
+find_boundary (struct MHD_PostProcessor *pp,
+ const char *boundary,
+ size_t blen,
+ unsigned int *ioffptr,
+ enum PP_State next_state, enum PP_State next_dash_state)
{
- char * buf = (char*) &pp[1];
+ char *buf = (char *) &pp[1];
if (pp->buffer_pos < 2 + blen)
{
if (pp->buffer_pos == pp->buffer_size)
- pp->state = PP_Error; /* out of memory */
- return MHD_NO; /* not enough data */
- }
- if ( (0 != memcmp ("--", buf, 2)) ||
- (0 != memcmp (&buf[2], boundary, blen)))
+ pp->state = PP_Error; /* out of memory */
+ return MHD_NO; /* not enough data */
+ }
+ if ((0 != memcmp ("--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen)))
{
pp->state = PP_Error;
- return MHD_NO; /* expected boundary */
+ return MHD_NO; /* expected boundary */
}
/* remove boundary from buffer */
(*ioffptr) += 2 + blen;
@@ -491,49 +488,43 @@ find_boundary(struct MHD_PostProcessor * pp,
* In buf, there maybe an expression
* '$key="$value"'. If that is the case,
* copy a copy of $value to destination.
- *
+ *
* If destination is already non-NULL,
* do nothing.
*/
static void
-try_get_value(const char * buf,
- const char * key,
- char ** destination)
+try_get_value (const char *buf, const char *key, char **destination)
{
- const char * spos;
- const char * bpos;
- const char * endv;
+ const char *spos;
+ const char *bpos;
+ const char *endv;
size_t klen;
size_t vlen;
if (NULL != *destination)
return;
bpos = buf;
- klen = strlen(key);
- while (NULL != (spos = strstr(bpos, key)))
+ klen = strlen (key);
+ while (NULL != (spos = strstr (bpos, key)))
{
- if ( (spos[klen] != '=') ||
- ( (spos != buf) &&
- (spos[-1] != ' ') ) )
- {
- /* no match */
- bpos = spos + 1;
- continue;
- }
+ if ((spos[klen] != '=') || ((spos != buf) && (spos[-1] != ' ')))
+ {
+ /* no match */
+ bpos = spos + 1;
+ continue;
+ }
if (spos[klen + 1] != '"')
- return; /* not quoted */
- if (NULL == (endv = strstr(&spos[klen+2], "\"")))
- return; /* no end-quote */
+ return; /* not quoted */
+ if (NULL == (endv = strstr (&spos[klen + 2], "\"")))
+ return; /* no end-quote */
vlen = endv - spos - klen - 1;
- *destination = malloc(vlen);
+ *destination = malloc (vlen);
if (NULL == *destination)
- return; /* out of memory */
+ return; /* out of memory */
(*destination)[vlen - 1] = '\0';
- memcpy(*destination,
- &spos[klen + 2],
- vlen - 1);
- return; /* success */
- }
+ memcpy (*destination, &spos[klen + 2], vlen - 1);
+ return; /* success */
+ }
}
/**
@@ -541,37 +532,35 @@ try_get_value(const char * buf,
* the fields in "pp" according to what we find.
* If we are at the end of the headers (as indicated
* by an empty line), transition into next_state.
- *
+ *
* @param ioffptr set to how many bytes have been
* processed
* @return MHD_YES if we can continue processing,
* MHD_NO on error or if we do not have
* enough data yet
- */
+ */
static int
-process_multipart_headers(struct MHD_PostProcessor * pp,
- unsigned int * ioffptr,
- enum PP_State next_state)
+process_multipart_headers (struct MHD_PostProcessor *pp,
+ unsigned int *ioffptr, enum PP_State next_state)
{
- char * buf = (char*) &pp[1];
+ char *buf = (char *) &pp[1];
unsigned int newline;
newline = 0;
while ((newline < pp->buffer_pos) &&
- (buf[newline] != '\r') &&
- (buf[newline] != '\n'))
+ (buf[newline] != '\r') && (buf[newline] != '\n'))
newline++;
if (newline == pp->buffer_size)
{
pp->state = PP_Error;
- return MHD_NO; /* out of memory */
+ return MHD_NO; /* out of memory */
}
if (newline == pp->buffer_pos)
- return MHD_NO; /* will need more data */
+ return MHD_NO; /* will need more data */
if (newline == 0)
{
/* empty line - end of headers */
- pp->skip_rn = RN_Full;
+ pp->skip_rn = RN_Full;
pp->state = next_state;
return MHD_YES;
}
@@ -579,24 +568,21 @@ process_multipart_headers(struct MHD_PostProcessor * pp,
if (buf[newline] == '\r')
pp->skip_rn = RN_OptN;
buf[newline] = '\0';
- if (0 == strncasecmp("Content-disposition: ",
- buf,
- strlen("Content-disposition: ")))
- {
- try_get_value(&buf[strlen("Content-disposition: ")],
- "name",
- &pp->content_name);
- try_get_value(&buf[strlen("Content-disposition: ")],
- "filename",
- &pp->content_filename);
+ if (0 == strncasecmp ("Content-disposition: ",
+ buf, strlen ("Content-disposition: ")))
+ {
+ try_get_value (&buf[strlen ("Content-disposition: ")],
+ "name", &pp->content_name);
+ try_get_value (&buf[strlen ("Content-disposition: ")],
+ "filename", &pp->content_filename);
}
- else
+ else
{
try_match_header ("Content-type: ", buf, &pp->content_type);
try_match_header ("Content-Transfer-Encoding: ",
- buf, &pp->content_transfer_encoding);
-}
- (*ioffptr) += newline + 1;
+ buf, &pp->content_transfer_encoding);
+ }
+ (*ioffptr) += newline + 1;
return MHD_YES;
}
@@ -615,14 +601,14 @@ process_multipart_headers(struct MHD_PostProcessor * pp,
* enough data yet
*/
static int
-process_value_to_boundary(struct MHD_PostProcessor * pp,
- unsigned int * ioffptr,
- const char * boundary,
- size_t blen,
- enum PP_State next_state,
- enum PP_State next_dash_state)
+process_value_to_boundary (struct MHD_PostProcessor *pp,
+ unsigned int *ioffptr,
+ const char *boundary,
+ size_t blen,
+ enum PP_State next_state,
+ enum PP_State next_dash_state)
{
- char * buf = (char*) &pp[1];
+ char *buf = (char *) &pp[1];
unsigned int newline;
/* all data in buf until the boundary
@@ -631,53 +617,51 @@ process_value_to_boundary(struct MHD_PostProcessor * pp,
while (1)
{
while ((newline + 4 < pp->buffer_pos) &&
- (0 != memcmp ("\r\n--", &buf[newline], 4)))
- newline++;
- if (newline + pp->blen + 4 <= pp->buffer_pos)
- {
- /* can check boundary */
- if (0 != memcmp (&buf[newline + 4], boundary, pp->blen))
- {
- /* no boundary, "\r\n--" is part of content, skip */
- newline += 4;
- continue;
- }
- else
- {
- /* boundary found, process until newline then
- skip boundary and go back to init */
- pp->skip_rn = RN_Dash;
- pp->state = next_state;
- pp->dash_state = next_dash_state;
- (*ioffptr) += pp->blen + 4; /* skip boundary as well */
- break;
- }
- }
+ (0 != memcmp ("\r\n--", &buf[newline], 4)))
+ newline++;
+ if (newline + pp->blen + 4 <= pp->buffer_pos)
+ {
+ /* can check boundary */
+ if (0 != memcmp (&buf[newline + 4], boundary, pp->blen))
+ {
+ /* no boundary, "\r\n--" is part of content, skip */
+ newline += 4;
+ continue;
+ }
+ else
+ {
+ /* boundary found, process until newline then
+ skip boundary and go back to init */
+ pp->skip_rn = RN_Dash;
+ pp->state = next_state;
+ pp->dash_state = next_dash_state;
+ (*ioffptr) += pp->blen + 4; /* skip boundary as well */
+ break;
+ }
+ }
else
- {
- /* cannot check for boundary, process content that
- we have and check again later; except, if we have
- no content, abort (out of memory) */
- if ( (newline == 0) &&
- (pp->buffer_pos == pp->buffer_size) )
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- return MHD_NO;
- }
+ {
+ /* cannot check for boundary, process content that
+ we have and check again later; except, if we have
+ no content, abort (out of memory) */
+ if ((newline == 0) && (pp->buffer_pos == pp->buffer_size))
+ {
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ break;
+ }
}
/* newline is either at beginning of boundary or
at least at the last character that we are sure
is not part of the boundary */
if (MHD_NO == pp->ikvi (pp->cls,
- MHD_POSTDATA_KIND,
- pp->content_name,
- pp->content_filename,
- pp->content_type,
- pp->content_transfer_encoding,
- buf,
- pp->value_offset, newline))
+ MHD_POSTDATA_KIND,
+ pp->content_name,
+ pp->content_filename,
+ pp->content_type,
+ pp->content_transfer_encoding,
+ buf, pp->value_offset, newline))
{
pp->state = PP_Error;
return MHD_NO;
@@ -688,30 +672,28 @@ process_value_to_boundary(struct MHD_PostProcessor * pp,
}
static void
-free_unmarked(struct MHD_PostProcessor * pp)
+free_unmarked (struct MHD_PostProcessor *pp)
{
- if ( (pp->content_name != NULL) &&
- (0 == (pp->have & NE_content_name)) )
+ if ((pp->content_name != NULL) && (0 == (pp->have & NE_content_name)))
{
- free(pp->content_name);
+ free (pp->content_name);
pp->content_name = NULL;
}
- if ( (pp->content_type != NULL) &&
- (0 == (pp->have & NE_content_type)) )
+ if ((pp->content_type != NULL) && (0 == (pp->have & NE_content_type)))
{
- free(pp->content_type);
+ free (pp->content_type);
pp->content_type = NULL;
}
- if ( (pp->content_filename != NULL) &&
- (0 == (pp->have & NE_content_filename)) )
+ if ((pp->content_filename != NULL) &&
+ (0 == (pp->have & NE_content_filename)))
{
- free(pp->content_filename);
+ free (pp->content_filename);
pp->content_filename = NULL;
}
- if ( (pp->content_transfer_encoding != NULL) &&
- (0 == (pp->have & NE_content_transfer_encoding)) )
+ if ((pp->content_transfer_encoding != NULL) &&
+ (0 == (pp->have & NE_content_transfer_encoding)))
{
- free(pp->content_transfer_encoding);
+ free (pp->content_transfer_encoding);
pp->content_transfer_encoding = NULL;
}
}
@@ -727,251 +709,252 @@ post_process_multipart (struct MHD_PostProcessor *pp,
unsigned int max;
unsigned int ioff;
unsigned int poff;
+ int state_changed;
buf = (char *) &pp[1];
ioff = 0;
poff = 0;
- max = 1;
- while ( (poff < post_data_len) ||
- ( (pp->buffer_pos > 0) &&
- (max != 0) ) )
+ state_changed = 1;
+ while ((poff < post_data_len) ||
+ ((pp->buffer_pos > 0) && (state_changed != 0)))
{
- /* first, move as much input data
- as possible to our internal buffer */
+ /* first, move as much input data
+ as possible to our internal buffer */
max = pp->buffer_size - pp->buffer_pos;
if (max > post_data_len - poff)
max = post_data_len - poff;
memcpy (&buf[pp->buffer_pos], &post_data[poff], max);
poff += max;
pp->buffer_pos += max;
- if ( (max == 0) &&
- (poff < post_data_len) )
- {
- pp->state = PP_Error;
- return MHD_NO; /* out of memory */
- }
+ if ((max == 0) && (state_changed == 0) && (poff < post_data_len))
+ {
+ pp->state = PP_Error;
+ return MHD_NO; /* out of memory */
+ }
+ state_changed = 0;
/* first state machine for '\r'-'\n' and '--' handling */
switch (pp->skip_rn)
- {
- case RN_Inactive:
- break;
- case RN_OptN:
- if (buf[0] == '\n')
- {
- ioff++;
- pp->skip_rn = RN_Inactive;
- goto AGAIN;
- }
- case RN_Dash:
- if (buf[0] == '-')
- {
- ioff++;
- pp->skip_rn = RN_Dash2;
- goto AGAIN;
- }
- pp->skip_rn = RN_Full;
- /* fall-through! */
- case RN_Full:
- if (buf[0] == '\r')
- {
- if ( (pp->buffer_pos > 1) &&
- (buf[1] == '\n') )
- {
- pp->skip_rn = RN_Inactive;
- ioff += 2;
- }
- else
- {
- pp->skip_rn = RN_OptN;
- ioff++;
- }
- goto AGAIN;
- }
- if (buf[0] == '\n')
- {
- ioff++;
- pp->skip_rn = RN_Inactive;
- goto AGAIN;
- }
- pp->skip_rn = RN_Inactive;
- pp->state = PP_Error;
- return MHD_NO; /* no '\r\n' */
- case RN_Dash2:
- if (buf[0] == '-')
- {
- ioff++;
- pp->skip_rn = RN_Full;
- pp->state = pp->dash_state;
- goto AGAIN;
- }
- pp->state = PP_Error;
- break;
- }
+ {
+ case RN_Inactive:
+ break;
+ case RN_OptN:
+ if (buf[0] == '\n')
+ {
+ ioff++;
+ pp->skip_rn = RN_Inactive;
+ goto AGAIN;
+ }
+ case RN_Dash:
+ if (buf[0] == '-')
+ {
+ ioff++;
+ pp->skip_rn = RN_Dash2;
+ goto AGAIN;
+ }
+ pp->skip_rn = RN_Full;
+ /* fall-through! */
+ case RN_Full:
+ if (buf[0] == '\r')
+ {
+ if ((pp->buffer_pos > 1) && (buf[1] == '\n'))
+ {
+ pp->skip_rn = RN_Inactive;
+ ioff += 2;
+ }
+ else
+ {
+ pp->skip_rn = RN_OptN;
+ ioff++;
+ }
+ goto AGAIN;
+ }
+ if (buf[0] == '\n')
+ {
+ ioff++;
+ pp->skip_rn = RN_Inactive;
+ goto AGAIN;
+ }
+ pp->skip_rn = RN_Inactive;
+ pp->state = PP_Error;
+ return MHD_NO; /* no '\r\n' */
+ case RN_Dash2:
+ if (buf[0] == '-')
+ {
+ ioff++;
+ pp->skip_rn = RN_Full;
+ pp->state = pp->dash_state;
+ goto AGAIN;
+ }
+ pp->state = PP_Error;
+ break;
+ }
/* main state engine */
switch (pp->state)
- {
+ {
case PP_Error:
- return MHD_NO;
- case PP_Done:
- /* did not expect to receive more data */
- pp->state = PP_Error;
- return MHD_NO;
- case PP_Init:
- if (MHD_NO == find_boundary(pp,
- pp->boundary,
- pp->blen,
- &ioff,
- PP_ProcessEntryHeaders,
- PP_Done))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- goto END;
- }
- break;
- case PP_ProcessEntryHeaders:
- if (MHD_NO == process_multipart_headers(pp, &ioff, PP_PerformCheckMultipart))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- else
- goto END;
- }
- max = 1;
+ return MHD_NO;
+ case PP_Done:
+ /* did not expect to receive more data */
+ pp->state = PP_Error;
+ return MHD_NO;
+ case PP_Init:
+ if (MHD_NO == find_boundary (pp,
+ pp->boundary,
+ pp->blen,
+ &ioff,
+ PP_ProcessEntryHeaders, PP_Done))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ goto END;
+ }
+ break;
+ case PP_ProcessEntryHeaders:
+ if (MHD_NO ==
+ process_multipart_headers (pp, &ioff, PP_PerformCheckMultipart))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ else
+ goto END;
+ }
+ state_changed = 1;
break;
case PP_PerformCheckMultipart:
- if ( (pp->content_type != NULL) &&
- (0 == strncasecmp(pp->content_type,
- "multipart/mixed",
- strlen("multipart/mixed")) ) )
- {
- pp->nested_boundary = strstr(pp->content_type,
- "boundary=");
- if (pp->nested_boundary == NULL)
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- pp->nested_boundary = strdup(&pp->nested_boundary[strlen("boundary=")]);
- if (pp->nested_boundary == NULL)
- {
- /* out of memory */
- pp->state = PP_Error;
- return MHD_NO;
- }
- /* free old content type, we will need that field
- for the content type of the nested elements */
- free(pp->content_type);
- pp->content_type = NULL;
- pp->nlen = strlen(pp->nested_boundary);
- pp->state = PP_Nested_Init;
- max = 1;
- break;
- }
- pp->state = PP_ProcessValueToBoundary;
- pp->value_offset = 0;
- max = 1;
- break;
+ if ((pp->content_type != NULL) &&
+ (0 == strncasecmp (pp->content_type,
+ "multipart/mixed",
+ strlen ("multipart/mixed"))))
+ {
+ pp->nested_boundary = strstr (pp->content_type, "boundary=");
+ if (pp->nested_boundary == NULL)
+ {
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ pp->nested_boundary =
+ strdup (&pp->nested_boundary[strlen ("boundary=")]);
+ if (pp->nested_boundary == NULL)
+ {
+ /* out of memory */
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ /* free old content type, we will need that field
+ for the content type of the nested elements */
+ free (pp->content_type);
+ pp->content_type = NULL;
+ pp->nlen = strlen (pp->nested_boundary);
+ pp->state = PP_Nested_Init;
+ state_changed = 1;
+ break;
+ }
+ pp->state = PP_ProcessValueToBoundary;
+ pp->value_offset = 0;
+ state_changed = 1;
+ break;
case PP_ProcessValueToBoundary:
- if (MHD_NO == process_value_to_boundary(pp,
- &ioff,
- pp->boundary,
- pp->blen,
- PP_PerformCleanup,
- PP_Done))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- break;
- }
- break;
- case PP_PerformCleanup:
- /* clean up state of one multipart form-data element! */
- pp->have = NE_none;
- free_unmarked(pp);
- if (pp->nested_boundary != NULL)
- {
- free (pp->nested_boundary);
- pp->nested_boundary = NULL;
- }
- pp->state = PP_ProcessEntryHeaders;
- max = 1;
- break;
- case PP_Nested_Init:
- if (pp->nested_boundary == NULL)
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- if (MHD_NO == find_boundary(pp,
- pp->nested_boundary,
- pp->nlen,
- &ioff,
- PP_Nested_PerformMarking,
- PP_Init /* or PP_Error? */))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- goto END;
- }
- break;
- case PP_Nested_PerformMarking:
- /* remember what headers were given
- globally */
- pp->have = NE_none;
- if (pp->content_name != NULL)
- pp->have |= NE_content_name;
- if (pp->content_type != NULL)
- pp->have |= NE_content_type;
- if (pp->content_filename != NULL)
- pp->have |= NE_content_filename;
- if (pp->content_transfer_encoding != NULL)
- pp->have |= NE_content_transfer_encoding;
- pp->state = PP_Nested_ProcessEntryHeaders;
- max = 1;
- break;
- case PP_Nested_ProcessEntryHeaders:
- pp->value_offset = 0;
- if (MHD_NO == process_multipart_headers(pp, &ioff, PP_Nested_ProcessValueToBoundary))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- else
- goto END;
- }
- max = 1;
+ if (MHD_NO == process_value_to_boundary (pp,
+ &ioff,
+ pp->boundary,
+ pp->blen,
+ PP_PerformCleanup,
+ PP_Done))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ break;
+ }
+ break;
+ case PP_PerformCleanup:
+ /* clean up state of one multipart form-data element! */
+ pp->have = NE_none;
+ free_unmarked (pp);
+ if (pp->nested_boundary != NULL)
+ {
+ free (pp->nested_boundary);
+ pp->nested_boundary = NULL;
+ }
+ pp->state = PP_ProcessEntryHeaders;
+ state_changed = 1;
+ break;
+ case PP_Nested_Init:
+ if (pp->nested_boundary == NULL)
+ {
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ if (MHD_NO == find_boundary (pp,
+ pp->nested_boundary,
+ pp->nlen,
+ &ioff,
+ PP_Nested_PerformMarking,
+ PP_Init /* or PP_Error? */ ))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ goto END;
+ }
+ break;
+ case PP_Nested_PerformMarking:
+ /* remember what headers were given
+ globally */
+ pp->have = NE_none;
+ if (pp->content_name != NULL)
+ pp->have |= NE_content_name;
+ if (pp->content_type != NULL)
+ pp->have |= NE_content_type;
+ if (pp->content_filename != NULL)
+ pp->have |= NE_content_filename;
+ if (pp->content_transfer_encoding != NULL)
+ pp->have |= NE_content_transfer_encoding;
+ pp->state = PP_Nested_ProcessEntryHeaders;
+ state_changed = 1;
+ break;
+ case PP_Nested_ProcessEntryHeaders:
+ pp->value_offset = 0;
+ if (MHD_NO ==
+ process_multipart_headers (pp, &ioff,
+ PP_Nested_ProcessValueToBoundary))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ else
+ goto END;
+ }
+ state_changed = 1;
+ break;
+ case PP_Nested_ProcessValueToBoundary:
+ if (MHD_NO == process_value_to_boundary (pp,
+ &ioff,
+ pp->nested_boundary,
+ pp->nlen,
+ PP_Nested_PerformCleanup,
+ PP_Init))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ break;
+ }
+ break;
+ case PP_Nested_PerformCleanup:
+ free_unmarked (pp);
+ pp->state = PP_Nested_ProcessEntryHeaders;
+ state_changed = 1;
break;
- case PP_Nested_ProcessValueToBoundary:
- if (MHD_NO == process_value_to_boundary(pp,
- &ioff,
- pp->nested_boundary,
- pp->nlen,
- PP_Nested_PerformCleanup,
- PP_Init))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- break;
- }
- break;
- case PP_Nested_PerformCleanup:
- free_unmarked(pp);
- pp->state = PP_Nested_ProcessEntryHeaders;
- max = 1;
- break;
default:
- abort (); /* should never happen! */
+ abort (); /* should never happen! */
}
-AGAIN:
- if (ioff > 0)
+ AGAIN:
+ if (ioff > 0)
{
memmove (buf, &buf[ioff], pp->buffer_pos - ioff);
pp->buffer_pos -= ioff;
ioff = 0;
- max = 1;
- }
+ state_changed = 1;
+ }
}
END:
if (ioff != 0)
@@ -979,10 +962,10 @@ END:
memmove (buf, &buf[ioff], pp->buffer_pos - ioff);
pp->buffer_pos -= ioff;
}
- if (poff < post_data_len)
+ if (poff < post_data_len)
{
pp->state = PP_Error;
- return MHD_NO; /* serious error */
+ return MHD_NO; /* serious error */
}
return MHD_YES;
}
@@ -1027,9 +1010,9 @@ MHD_destroy_post_processor (struct MHD_PostProcessor *pp)
the post-processing may have been interrupted
at any stage */
pp->have = NE_none;
- free_unmarked(pp);
+ free_unmarked (pp);
if (pp->nested_boundary != NULL)
- free(pp->nested_boundary);
+ free (pp->nested_boundary);
free (pp);
}
diff --git a/src/daemon/postprocessor_test.c b/src/daemon/postprocessor_test.c
index a931b300..6641fe1e 100644
--- a/src/daemon/postprocessor_test.c
+++ b/src/daemon/postprocessor_test.c
@@ -40,10 +40,10 @@
* Each series of checks should be terminated by
* five NULL-entries.
*/
-const char * want[] = {
+const char *want[] = {
#define URL_DATA "abc=def&x=5"
#define URL_START 0
- "abc", NULL, NULL, NULL, "def",
+ "abc", NULL, NULL, NULL, "def",
"x", NULL, NULL, NULL, "5",
#define URL_END (URL_START + 10)
NULL, NULL, NULL, NULL, NULL,
@@ -63,81 +63,80 @@ const char * want[] = {
};
static int
-mismatch(const char * a, const char * b) {
- if (a == b)
+mismatch (const char *a, const char *b)
+{
+ if (a == b)
return 0;
- if ( (a == NULL) ||
- (b == NULL) )
+ if ((a == NULL) || (b == NULL))
return 1;
- return 0 != strcmp(a, b);
+ return 0 != strcmp (a, b);
}
static int
-value_checker(void * cls,
- enum MHD_ValueKind kind,
- const char * key,
- const char * filename,
- const char * content_type,
- const char * transfer_encoding,
- const char * data,
- size_t off,
- size_t size) {
- int * want_off = cls;
+value_checker (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data, size_t off, size_t size)
+{
+ int *want_off = cls;
int idx = *want_off;
#if 0
- fprintf(stderr,
- "VC: `%s' `%s' `%s' `%s' `%.*s'\n",
- key, filename, content_type, transfer_encoding, size, data);
+ fprintf (stderr,
+ "VC: `%s' `%s' `%s' `%s' `%.*s'\n",
+ key, filename, content_type, transfer_encoding, size, data);
#endif
if (size == 0)
return MHD_YES;
- if ( (idx < 0) ||
- (want[idx] == NULL) ||
- (0 != strcmp(key, want[idx])) ||
- (mismatch(filename, want[idx+1])) ||
- (mismatch(content_type, want[idx+2])) ||
- (mismatch(transfer_encoding, want[idx+3])) ||
- (0 != memcmp(data, &want[idx+4][off], size)) )
+ if ((idx < 0) ||
+ (want[idx] == NULL) ||
+ (0 != strcmp (key, want[idx])) ||
+ (mismatch (filename, want[idx + 1])) ||
+ (mismatch (content_type, want[idx + 2])) ||
+ (mismatch (transfer_encoding, want[idx + 3])) ||
+ (0 != memcmp (data, &want[idx + 4][off], size)))
{
*want_off = -1;
return MHD_NO;
}
- if (off + size == strlen(want[idx+4]))
+ if (off + size == strlen (want[idx + 4]))
*want_off = idx + 5;
return MHD_YES;
-
+
}
static int
-test_urlencoding() {
+test_urlencoding ()
+{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
- struct MHD_PostProcessor * pp;
+ struct MHD_PostProcessor *pp;
unsigned int want_off = URL_START;
int i;
int delta;
size_t size;
- memset(&connection, 0, sizeof(struct MHD_Connection));
- memset(&header, 0, sizeof(struct MHD_HTTP_Header));
+ memset (&connection, 0, sizeof (struct MHD_Connection));
+ memset (&header, 0, sizeof (struct MHD_HTTP_Header));
connection.headers_received = &header;
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
header.kind = MHD_HEADER_KIND;
- pp = MHD_create_post_processor(&connection,
- 1024,
- &value_checker,
- &want_off);
+ pp = MHD_create_post_processor (&connection,
+ 1024, &value_checker, &want_off);
i = 0;
- size = strlen(URL_DATA);
- while (i < size) {
- delta = 1 + random() % (size - i);
- MHD_post_process(pp, &URL_DATA[i], delta);
- i += delta;
- }
- MHD_destroy_post_processor(pp);
+ size = strlen (URL_DATA);
+ while (i < size)
+ {
+ delta = 1 + random () % (size - i);
+ MHD_post_process (pp, &URL_DATA[i], delta);
+ i += delta;
+ }
+ MHD_destroy_post_processor (pp);
if (want_off != URL_END)
return 1;
return 0;
@@ -145,33 +144,34 @@ test_urlencoding() {
static int
-test_multipart() {
+test_multipart ()
+{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
- struct MHD_PostProcessor * pp;
+ struct MHD_PostProcessor *pp;
unsigned int want_off = FORM_START;
int i;
int delta;
size_t size;
- memset(&connection, 0, sizeof(struct MHD_Connection));
- memset(&header, 0, sizeof(struct MHD_HTTP_Header));
+ memset (&connection, 0, sizeof (struct MHD_Connection));
+ memset (&header, 0, sizeof (struct MHD_HTTP_Header));
connection.headers_received = &header;
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
- header.value = MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
+ header.value =
+ MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
header.kind = MHD_HEADER_KIND;
- pp = MHD_create_post_processor(&connection,
- 1024,
- &value_checker,
- &want_off);
+ pp = MHD_create_post_processor (&connection,
+ 1024, &value_checker, &want_off);
i = 0;
- size = strlen(FORM_DATA);
- while (i < size) {
- delta = 1 + random() % (size - i);
- MHD_post_process(pp, &FORM_DATA[i], delta);
- i += delta;
- }
- MHD_destroy_post_processor(pp);
+ size = strlen (FORM_DATA);
+ while (i < size)
+ {
+ delta = 1 + random () % (size - i);
+ MHD_post_process (pp, &FORM_DATA[i], delta);
+ i += delta;
+ }
+ MHD_destroy_post_processor (pp);
if (want_off != FORM_END)
return 2;
return 0;
@@ -179,33 +179,34 @@ test_multipart() {
static int
-test_nested_multipart() {
+test_nested_multipart ()
+{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
- struct MHD_PostProcessor * pp;
+ struct MHD_PostProcessor *pp;
unsigned int want_off = FORM_NESTED_START;
int i;
int delta;
size_t size;
- memset(&connection, 0, sizeof(struct MHD_Connection));
- memset(&header, 0, sizeof(struct MHD_HTTP_Header));
+ memset (&connection, 0, sizeof (struct MHD_Connection));
+ memset (&header, 0, sizeof (struct MHD_HTTP_Header));
connection.headers_received = &header;
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
- header.value = MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
+ header.value =
+ MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
header.kind = MHD_HEADER_KIND;
- pp = MHD_create_post_processor(&connection,
- 1024,
- &value_checker,
- &want_off);
+ pp = MHD_create_post_processor (&connection,
+ 1024, &value_checker, &want_off);
i = 0;
- size = strlen(FORM_NESTED_DATA);
- while (i < size) {
- delta = 1 + random() % (size - i);
- MHD_post_process(pp, &FORM_NESTED_DATA[i], delta);
- i += delta;
- }
- MHD_destroy_post_processor(pp);
+ size = strlen (FORM_NESTED_DATA);
+ while (i < size)
+ {
+ delta = 1 + random () % (size - i);
+ MHD_post_process (pp, &FORM_NESTED_DATA[i], delta);
+ i += delta;
+ }
+ MHD_destroy_post_processor (pp);
if (want_off != FORM_NESTED_END)
return 4;
return 0;
@@ -216,9 +217,9 @@ main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
- errorCount += test_urlencoding();
- errorCount += test_multipart();
- errorCount += test_nested_multipart();
+ errorCount += test_urlencoding ();
+ errorCount += test_multipart ();
+ errorCount += test_nested_multipart ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
return errorCount != 0; /* 0 == pass */
diff --git a/src/daemon/response.c b/src/daemon/response.c
index ea1fe9c0..3089e6c1 100644
--- a/src/daemon/response.c
+++ b/src/daemon/response.c
@@ -238,10 +238,10 @@ MHD_create_response_from_data (size_t size,
{
tmp = malloc (size);
if (tmp == NULL)
- {
- free(retVal);
- return NULL;
- }
+ {
+ free (retVal);
+ return NULL;
+ }
memcpy (tmp, data, size);
must_free = 1;
data = tmp;