diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-31 18:03:25 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-31 18:03:25 +0000 |
commit | 49e8a611599e6bb644f29f93ea20ae1cdcf667a9 (patch) | |
tree | a5cc6ea3b0efb2eb9ff83c8589f337bafe21568c | |
parent | 1d2db05d10f5811226307eca0692bca3cf7182c3 (diff) | |
download | libmicrohttpd-49e8a611599e6bb644f29f93ea20ae1cdcf667a9.tar.gz libmicrohttpd-49e8a611599e6bb644f29f93ea20ae1cdcf667a9.zip |
optimize post processor block size
-rw-r--r-- | src/daemon/postprocessor.c | 80 |
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 | */ |
317 | static int | 335 | static int |
318 | post_process_urlencoded (struct MHD_PostProcessor *pp, | 336 | post_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 | */ |
467 | static int | 490 | static 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 | */ | ||
484 | static int | 512 | static int |
485 | find_boundary (struct MHD_PostProcessor *pp, | 513 | find_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 | */ |
523 | static void | 551 | static void |
524 | try_get_value (const char *buf, const char *key, char **destination) | 552 | try_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 | */ | ||
703 | static void | 745 | static void |
704 | free_unmarked (struct MHD_PostProcessor *pp) | 746 | free_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 | */ |
733 | static int | 778 | static int |
734 | post_process_multipart (struct MHD_PostProcessor *pp, | 779 | post_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 | */ |
1058 | int | 1112 | int |
1059 | MHD_destroy_post_processor (struct MHD_PostProcessor *pp) | 1113 | MHD_destroy_post_processor (struct MHD_PostProcessor *pp) |