commit 49e8a611599e6bb644f29f93ea20ae1cdcf667a9
parent 1d2db05d10f5811226307eca0692bca3cf7182c3
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 31 Mar 2013 18:03:25 +0000
optimize post processor block size
Diffstat:
1 file changed, 67 insertions(+), 13 deletions(-)
diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c
@@ -206,6 +206,16 @@ struct MHD_PostProcessor
size_t nlen;
/**
+ * Do we have to call the 'ikvi' callback when processing the
+ * multipart post body even if the size of the payload is zero?
+ * Set to MHD_YES whenever we parse a new multiparty entry header,
+ * and to MHD_NO the first time we call the 'ikvi' callback.
+ * Used to ensure that we do always call 'ikvi' even if the
+ * payload is empty (but not more than once).
+ */
+ int must_ikvi;
+
+ /**
* State of the parser.
*/
enum PP_State state;
@@ -295,8 +305,10 @@ MHD_create_post_processor (struct MHD_Connection *connection,
}
else
blen = 0;
- ret = malloc (sizeof (struct MHD_PostProcessor) + buffer_size + 1);
- if (ret == NULL)
+ buffer_size += 4; /* round up to get nice block sizes despite boundary search */
+
+ /* add +1 to ensure we ALWAYS have a zero-termination at the end */
+ if (NULL == (ret = malloc (sizeof (struct MHD_PostProcessor) + buffer_size + 1)))
return NULL;
memset (ret, 0, sizeof (struct MHD_PostProcessor) + buffer_size + 1);
ret->connection = connection;
@@ -311,8 +323,14 @@ MHD_create_post_processor (struct MHD_Connection *connection,
return ret;
}
+
/**
* Process url-encoded POST data.
+ *
+ * @param pp post processor context
+ * @param post_data upload data
+ * @param post_data_len number of bytes in upload_data
+ * @return MHD_YES on success, MHD_NO if there was an error processing the data
*/
static int
post_process_urlencoded (struct MHD_PostProcessor *pp,
@@ -418,6 +436,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
xbuf[xoff] = '\0'; /* 0-terminate in preparation */
xoff = MHD_http_unescape (NULL, NULL, xbuf);
/* finally: call application! */
+ pp->must_ikvi = MHD_NO;
if (MHD_NO == pp->ikvi (pp->cls, MHD_POSTDATA_KIND, (const char *) &pp[1], /* key */
NULL, NULL, NULL, xbuf, pp->value_offset,
xoff))
@@ -458,10 +477,14 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
return MHD_YES;
}
+
/**
* If the given line matches the prefix, strdup the
* rest of the line into the suffix ptr.
*
+ * @param prefix prefix to match
+ * @param line line to match prefix in
+ * @param suffix set to a copy of the rest of the line, starting at the end of the match
* @return MHD_YES if there was a match, MHD_NO if not
*/
static int
@@ -481,6 +504,11 @@ try_match_header (const char *prefix, char *line, char **suffix)
return MHD_NO;
}
+
+/**
+ *
+ * @param pp post processor context
+ */
static int
find_boundary (struct MHD_PostProcessor *pp,
const char *boundary,
@@ -512,16 +540,18 @@ find_boundary (struct MHD_PostProcessor *pp,
return MHD_YES;
}
+
/**
- * In buf, there maybe an expression
- * '$key="$value"'. If that is the case,
- * copy a copy of $value to destination.
+ * 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;
@@ -555,12 +585,14 @@ try_get_value (const char *buf, const char *key, char **destination)
}
}
+
/**
* Go over the headers of the part and update
* 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 pp post processor context
* @param ioffptr set to how many bytes have been
* processed
* @return MHD_YES if we can continue processing,
@@ -614,10 +646,12 @@ process_multipart_headers (struct MHD_PostProcessor *pp,
return MHD_YES;
}
+
/**
* We have the value until we hit the given boundary;
* process accordingly.
*
+ * @param pp post processor context
* @param boundary the boundary to look for
* @param blen strlen(boundary)
* @param next_state what state to go into after the
@@ -684,22 +718,30 @@ process_value_to_boundary (struct MHD_PostProcessor *pp,
/* 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))
+ if ( ( (MHD_YES == pp->must_ikvi) ||
+ (0 != newline) ) &&
+ (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)) )
{
pp->state = PP_Error;
return MHD_NO;
}
+ pp->must_ikvi = MHD_NO;
pp->value_offset += newline;
(*ioffptr) += newline;
return MHD_YES;
}
+
+/**
+ *
+ * @param pp post processor context
+ */
static void
free_unmarked (struct MHD_PostProcessor *pp)
{
@@ -727,8 +769,11 @@ free_unmarked (struct MHD_PostProcessor *pp)
}
}
+
/**
* Decode multipart POST data.
+ *
+ * @param pp post processor context
*/
static int
post_process_multipart (struct MHD_PostProcessor *pp,
@@ -861,6 +906,7 @@ post_process_multipart (struct MHD_PostProcessor *pp,
}
break;
case PP_ProcessEntryHeaders:
+ pp->must_ikvi = MHD_YES;
if (MHD_NO ==
process_multipart_headers (pp, &ioff, PP_PerformCheckMultipart))
{
@@ -1019,6 +1065,7 @@ END:
return MHD_YES;
}
+
/**
* Parse and process POST data.
* Call this function when POST data is available
@@ -1052,8 +1099,15 @@ MHD_post_process (struct MHD_PostProcessor *pp,
return MHD_NO;
}
+
/**
* Release PostProcessor resources.
+ *
+ * @param pp post processor context to destroy
+ * @return MHD_YES if processing completed nicely,
+ * MHD_NO if there were spurious characters / formatting
+ * problems; it is common to ignore the return
+ * value of this function
*/
int
MHD_destroy_post_processor (struct MHD_PostProcessor *pp)