aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-03-31 18:03:25 +0000
committerChristian Grothoff <christian@grothoff.org>2013-03-31 18:03:25 +0000
commit49e8a611599e6bb644f29f93ea20ae1cdcf667a9 (patch)
treea5cc6ea3b0efb2eb9ff83c8589f337bafe21568c
parent1d2db05d10f5811226307eca0692bca3cf7182c3 (diff)
downloadlibmicrohttpd-49e8a611599e6bb644f29f93ea20ae1cdcf667a9.tar.gz
libmicrohttpd-49e8a611599e6bb644f29f93ea20ae1cdcf667a9.zip
optimize post processor block size
-rw-r--r--src/daemon/postprocessor.c80
1 files changed, 67 insertions, 13 deletions
diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c
index 838f71f5..98437744 100644
--- a/src/daemon/postprocessor.c
+++ b/src/daemon/postprocessor.c
@@ -206,6 +206,16 @@ struct MHD_PostProcessor
206 size_t nlen; 206 size_t nlen;
207 207
208 /** 208 /**
209 * Do we have to call the 'ikvi' callback when processing the
210 * multipart post body even if the size of the payload is zero?
211 * Set to MHD_YES whenever we parse a new multiparty entry header,
212 * and to MHD_NO the first time we call the 'ikvi' callback.
213 * Used to ensure that we do always call 'ikvi' even if the
214 * payload is empty (but not more than once).
215 */
216 int must_ikvi;
217
218 /**
209 * State of the parser. 219 * State of the parser.
210 */ 220 */
211 enum PP_State state; 221 enum PP_State state;
@@ -295,8 +305,10 @@ MHD_create_post_processor (struct MHD_Connection *connection,
295 } 305 }
296 else 306 else
297 blen = 0; 307 blen = 0;
298 ret = malloc (sizeof (struct MHD_PostProcessor) + buffer_size + 1); 308 buffer_size += 4; /* round up to get nice block sizes despite boundary search */
299 if (ret == NULL) 309
310 /* add +1 to ensure we ALWAYS have a zero-termination at the end */
311 if (NULL == (ret = malloc (sizeof (struct MHD_PostProcessor) + buffer_size + 1)))
300 return NULL; 312 return NULL;
301 memset (ret, 0, sizeof (struct MHD_PostProcessor) + buffer_size + 1); 313 memset (ret, 0, sizeof (struct MHD_PostProcessor) + buffer_size + 1);
302 ret->connection = connection; 314 ret->connection = connection;
@@ -311,8 +323,14 @@ MHD_create_post_processor (struct MHD_Connection *connection,
311 return ret; 323 return ret;
312} 324}
313 325
326
314/** 327/**
315 * Process url-encoded POST data. 328 * Process url-encoded POST data.
329 *
330 * @param pp post processor context
331 * @param post_data upload data
332 * @param post_data_len number of bytes in upload_data
333 * @return MHD_YES on success, MHD_NO if there was an error processing the data
316 */ 334 */
317static int 335static int
318post_process_urlencoded (struct MHD_PostProcessor *pp, 336post_process_urlencoded (struct MHD_PostProcessor *pp,
@@ -418,6 +436,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
418 xbuf[xoff] = '\0'; /* 0-terminate in preparation */ 436 xbuf[xoff] = '\0'; /* 0-terminate in preparation */
419 xoff = MHD_http_unescape (NULL, NULL, xbuf); 437 xoff = MHD_http_unescape (NULL, NULL, xbuf);
420 /* finally: call application! */ 438 /* finally: call application! */
439 pp->must_ikvi = MHD_NO;
421 if (MHD_NO == pp->ikvi (pp->cls, MHD_POSTDATA_KIND, (const char *) &pp[1], /* key */ 440 if (MHD_NO == pp->ikvi (pp->cls, MHD_POSTDATA_KIND, (const char *) &pp[1], /* key */
422 NULL, NULL, NULL, xbuf, pp->value_offset, 441 NULL, NULL, NULL, xbuf, pp->value_offset,
423 xoff)) 442 xoff))
@@ -458,10 +477,14 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
458 return MHD_YES; 477 return MHD_YES;
459} 478}
460 479
480
461/** 481/**
462 * If the given line matches the prefix, strdup the 482 * If the given line matches the prefix, strdup the
463 * rest of the line into the suffix ptr. 483 * rest of the line into the suffix ptr.
464 * 484 *
485 * @param prefix prefix to match
486 * @param line line to match prefix in
487 * @param suffix set to a copy of the rest of the line, starting at the end of the match
465 * @return MHD_YES if there was a match, MHD_NO if not 488 * @return MHD_YES if there was a match, MHD_NO if not
466 */ 489 */
467static int 490static int
@@ -481,6 +504,11 @@ try_match_header (const char *prefix, char *line, char **suffix)
481 return MHD_NO; 504 return MHD_NO;
482} 505}
483 506
507
508/**
509 *
510 * @param pp post processor context
511 */
484static int 512static int
485find_boundary (struct MHD_PostProcessor *pp, 513find_boundary (struct MHD_PostProcessor *pp,
486 const char *boundary, 514 const char *boundary,
@@ -512,16 +540,18 @@ find_boundary (struct MHD_PostProcessor *pp,
512 return MHD_YES; 540 return MHD_YES;
513} 541}
514 542
543
515/** 544/**
516 * In buf, there maybe an expression 545 * In buf, there maybe an expression '$key="$value"'. If that is the
517 * '$key="$value"'. If that is the case, 546 * case, copy a copy of $value to destination.
518 * copy a copy of $value to destination.
519 * 547 *
520 * If destination is already non-NULL, 548 * If destination is already non-NULL,
521 * do nothing. 549 * do nothing.
522 */ 550 */
523static void 551static void
524try_get_value (const char *buf, const char *key, char **destination) 552try_get_value (const char *buf,
553 const char *key,
554 char **destination)
525{ 555{
526 const char *spos; 556 const char *spos;
527 const char *bpos; 557 const char *bpos;
@@ -555,12 +585,14 @@ try_get_value (const char *buf, const char *key, char **destination)
555 } 585 }
556} 586}
557 587
588
558/** 589/**
559 * Go over the headers of the part and update 590 * Go over the headers of the part and update
560 * the fields in "pp" according to what we find. 591 * the fields in "pp" according to what we find.
561 * If we are at the end of the headers (as indicated 592 * If we are at the end of the headers (as indicated
562 * by an empty line), transition into next_state. 593 * by an empty line), transition into next_state.
563 * 594 *
595 * @param pp post processor context
564 * @param ioffptr set to how many bytes have been 596 * @param ioffptr set to how many bytes have been
565 * processed 597 * processed
566 * @return MHD_YES if we can continue processing, 598 * @return MHD_YES if we can continue processing,
@@ -614,10 +646,12 @@ process_multipart_headers (struct MHD_PostProcessor *pp,
614 return MHD_YES; 646 return MHD_YES;
615} 647}
616 648
649
617/** 650/**
618 * We have the value until we hit the given boundary; 651 * We have the value until we hit the given boundary;
619 * process accordingly. 652 * process accordingly.
620 * 653 *
654 * @param pp post processor context
621 * @param boundary the boundary to look for 655 * @param boundary the boundary to look for
622 * @param blen strlen(boundary) 656 * @param blen strlen(boundary)
623 * @param next_state what state to go into after the 657 * @param next_state what state to go into after the
@@ -684,22 +718,30 @@ process_value_to_boundary (struct MHD_PostProcessor *pp,
684 /* newline is either at beginning of boundary or 718 /* newline is either at beginning of boundary or
685 at least at the last character that we are sure 719 at least at the last character that we are sure
686 is not part of the boundary */ 720 is not part of the boundary */
687 if (MHD_NO == pp->ikvi (pp->cls, 721 if ( ( (MHD_YES == pp->must_ikvi) ||
688 MHD_POSTDATA_KIND, 722 (0 != newline) ) &&
689 pp->content_name, 723 (MHD_NO == pp->ikvi (pp->cls,
690 pp->content_filename, 724 MHD_POSTDATA_KIND,
691 pp->content_type, 725 pp->content_name,
692 pp->content_transfer_encoding, 726 pp->content_filename,
693 buf, pp->value_offset, newline)) 727 pp->content_type,
728 pp->content_transfer_encoding,
729 buf, pp->value_offset, newline)) )
694 { 730 {
695 pp->state = PP_Error; 731 pp->state = PP_Error;
696 return MHD_NO; 732 return MHD_NO;
697 } 733 }
734 pp->must_ikvi = MHD_NO;
698 pp->value_offset += newline; 735 pp->value_offset += newline;
699 (*ioffptr) += newline; 736 (*ioffptr) += newline;
700 return MHD_YES; 737 return MHD_YES;
701} 738}
702 739
740
741/**
742 *
743 * @param pp post processor context
744 */
703static void 745static void
704free_unmarked (struct MHD_PostProcessor *pp) 746free_unmarked (struct MHD_PostProcessor *pp)
705{ 747{
@@ -727,8 +769,11 @@ free_unmarked (struct MHD_PostProcessor *pp)
727 } 769 }
728} 770}
729 771
772
730/** 773/**
731 * Decode multipart POST data. 774 * Decode multipart POST data.
775 *
776 * @param pp post processor context
732 */ 777 */
733static int 778static int
734post_process_multipart (struct MHD_PostProcessor *pp, 779post_process_multipart (struct MHD_PostProcessor *pp,
@@ -861,6 +906,7 @@ post_process_multipart (struct MHD_PostProcessor *pp,
861 } 906 }
862 break; 907 break;
863 case PP_ProcessEntryHeaders: 908 case PP_ProcessEntryHeaders:
909 pp->must_ikvi = MHD_YES;
864 if (MHD_NO == 910 if (MHD_NO ==
865 process_multipart_headers (pp, &ioff, PP_PerformCheckMultipart)) 911 process_multipart_headers (pp, &ioff, PP_PerformCheckMultipart))
866 { 912 {
@@ -1019,6 +1065,7 @@ END:
1019 return MHD_YES; 1065 return MHD_YES;
1020} 1066}
1021 1067
1068
1022/** 1069/**
1023 * Parse and process POST data. 1070 * Parse and process POST data.
1024 * Call this function when POST data is available 1071 * Call this function when POST data is available
@@ -1052,8 +1099,15 @@ MHD_post_process (struct MHD_PostProcessor *pp,
1052 return MHD_NO; 1099 return MHD_NO;
1053} 1100}
1054 1101
1102
1055/** 1103/**
1056 * Release PostProcessor resources. 1104 * Release PostProcessor resources.
1105 *
1106 * @param pp post processor context to destroy
1107 * @return MHD_YES if processing completed nicely,
1108 * MHD_NO if there were spurious characters / formatting
1109 * problems; it is common to ignore the return
1110 * value of this function
1057 */ 1111 */
1058int 1112int
1059MHD_destroy_post_processor (struct MHD_PostProcessor *pp) 1113MHD_destroy_post_processor (struct MHD_PostProcessor *pp)