aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/postprocessor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/postprocessor.c')
-rw-r--r--src/microhttpd/postprocessor.c1205
1 files changed, 605 insertions, 600 deletions
diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c
index e9d40ef7..8b6a33ea 100644
--- a/src/microhttpd/postprocessor.c
+++ b/src/microhttpd/postprocessor.c
@@ -291,44 +291,48 @@ MHD_create_post_processor (struct MHD_Connection *connection,
291 if (MHD_NO == MHD_lookup_connection_value_n (connection, 291 if (MHD_NO == MHD_lookup_connection_value_n (connection,
292 MHD_HEADER_KIND, 292 MHD_HEADER_KIND,
293 MHD_HTTP_HEADER_CONTENT_TYPE, 293 MHD_HTTP_HEADER_CONTENT_TYPE,
294 MHD_STATICSTR_LEN_(MHD_HTTP_HEADER_CONTENT_TYPE), 294 MHD_STATICSTR_LEN_ (
295 MHD_HTTP_HEADER_CONTENT_TYPE),
295 &encoding, 296 &encoding,
296 NULL)) 297 NULL))
297 return NULL; 298 return NULL;
298 boundary = NULL; 299 boundary = NULL;
299 if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, 300 if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
300 encoding, 301 encoding,
301 MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED))) 302 MHD_STATICSTR_LEN_ (
303 MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
304 {
305 if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
306 encoding,
307 MHD_STATICSTR_LEN_ (
308 MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
309 return NULL;
310 boundary =
311 &encoding[MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
312 /* Q: should this be "strcasestr"? */
313 boundary = strstr (boundary, "boundary=");
314 if (NULL == boundary)
315 return NULL; /* failed to determine boundary */
316 boundary += MHD_STATICSTR_LEN_ ("boundary=");
317 blen = strlen (boundary);
318 if ( (blen == 0) ||
319 (blen * 2 + 2 > buffer_size) )
320 return NULL; /* (will be) out of memory or invalid boundary */
321 if ( (boundary[0] == '"') &&
322 (boundary[blen - 1] == '"') )
302 { 323 {
303 if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, 324 /* remove enclosing quotes */
304 encoding, 325 ++boundary;
305 MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA))) 326 blen -= 2;
306 return NULL;
307 boundary =
308 &encoding[MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
309 /* Q: should this be "strcasestr"? */
310 boundary = strstr (boundary, "boundary=");
311 if (NULL == boundary)
312 return NULL; /* failed to determine boundary */
313 boundary += MHD_STATICSTR_LEN_ ("boundary=");
314 blen = strlen (boundary);
315 if ( (blen == 0) ||
316 (blen * 2 + 2 > buffer_size) )
317 return NULL; /* (will be) out of memory or invalid boundary */
318 if ( (boundary[0] == '"') &&
319 (boundary[blen - 1] == '"') )
320 {
321 /* remove enclosing quotes */
322 ++boundary;
323 blen -= 2;
324 }
325 } 327 }
328 }
326 else 329 else
327 blen = 0; 330 blen = 0;
328 buffer_size += 4; /* round up to get nice block sizes despite boundary search */ 331 buffer_size += 4; /* round up to get nice block sizes despite boundary search */
329 332
330 /* add +1 to ensure we ALWAYS have a zero-termination at the end */ 333 /* add +1 to ensure we ALWAYS have a zero-termination at the end */
331 if (NULL == (ret = MHD_calloc_ (1, sizeof (struct MHD_PostProcessor) + buffer_size + 1))) 334 if (NULL == (ret = MHD_calloc_ (1, sizeof (struct MHD_PostProcessor)
335 + buffer_size + 1)))
332 return NULL; 336 return NULL;
333 ret->connection = connection; 337 ret->connection = connection;
334 ret->ikvi = iter; 338 ret->ikvi = iter;
@@ -354,7 +358,7 @@ MHD_create_post_processor (struct MHD_Connection *connection,
354static int 358static int
355post_process_urlencoded (struct MHD_PostProcessor *pp, 359post_process_urlencoded (struct MHD_PostProcessor *pp,
356 const char *post_data, 360 const char *post_data,
357 size_t post_data_len) 361 size_t post_data_len)
358{ 362{
359 size_t equals; 363 size_t equals;
360 size_t amper; 364 size_t amper;
@@ -368,149 +372,149 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
368 buf = (char *) &pp[1]; 372 buf = (char *) &pp[1];
369 poff = 0; 373 poff = 0;
370 while (poff < post_data_len) 374 while (poff < post_data_len)
375 {
376 switch (pp->state)
371 { 377 {
372 switch (pp->state) 378 case PP_Error:
379 return MHD_NO;
380 case PP_Done:
381 /* did not expect to receive more data */
382 pp->state = PP_Error;
383 return MHD_NO;
384 case PP_Init:
385 equals = 0;
386 while ((equals + poff < post_data_len) &&
387 (post_data[equals + poff] != '='))
388 equals++;
389 if (equals + pp->buffer_pos > pp->buffer_size)
390 {
391 pp->state = PP_Error; /* out of memory */
392 return MHD_NO;
393 }
394 memcpy (&buf[pp->buffer_pos], &post_data[poff], equals);
395 pp->buffer_pos += equals;
396 if (equals + poff == post_data_len)
397 return MHD_YES; /* no '=' yet */
398 buf[pp->buffer_pos] = '\0'; /* 0-terminate key */
399 pp->buffer_pos = 0; /* reset for next key */
400 MHD_unescape_plus (buf);
401 MHD_http_unescape (buf);
402 poff += equals + 1;
403 pp->state = PP_ProcessValue;
404 pp->value_offset = 0;
405 break;
406 case PP_ProcessValue:
407 /* obtain rest of value from previous iteration */
408 memcpy (xbuf, pp->xbuf, pp->xbuf_pos);
409 xoff = pp->xbuf_pos;
410 pp->xbuf_pos = 0;
411
412 /* find last position in input buffer that is part of the value */
413 amper = 0;
414 while ((amper + poff < post_data_len) &&
415 (amper < XBUF_SIZE) &&
416 (post_data[amper + poff] != '&') &&
417 (post_data[amper + poff] != '\n') &&
418 (post_data[amper + poff] != '\r'))
419 amper++;
420 end_of_value_found = ((amper + poff < post_data_len) &&
421 ((post_data[amper + poff] == '&') ||
422 (post_data[amper + poff] == '\n') ||
423 (post_data[amper + poff] == '\r')));
424 /* compute delta, the maximum number of bytes that we will be able to
425 process right now (either amper-limited of xbuf-size limited) */
426 delta = amper;
427 if (delta > XBUF_SIZE - xoff)
428 delta = XBUF_SIZE - xoff;
429
430 /* move input into processing buffer */
431 memcpy (&xbuf[xoff], &post_data[poff], delta);
432 xoff += delta;
433 poff += delta;
434
435 /* find if escape sequence is at the end of the processing buffer;
436 if so, exclude those from processing (reduce delta to point at
437 end of processed region) */
438 delta = xoff;
439 if ((delta > 0) &&
440 ('%' == xbuf[delta - 1]))
441 delta--;
442 else if ((delta > 1) &&
443 ('%' == xbuf[delta - 2]))
444 delta -= 2;
445
446 /* if we have an incomplete escape sequence, save it to
447 pp->xbuf for later */
448 if (delta < xoff)
449 {
450 memcpy (pp->xbuf,
451 &xbuf[delta],
452 xoff - delta);
453 pp->xbuf_pos = xoff - delta;
454 xoff = delta;
455 }
456
457 /* If we have nothing to do (delta == 0) and
458 not just because the value is empty (are
459 waiting for more data), go for next iteration */
460 if ( (0 == xoff) &&
461 (poff == post_data_len))
462 continue;
463
464 /* unescape */
465 xbuf[xoff] = '\0'; /* 0-terminate in preparation */
466 MHD_unescape_plus (xbuf);
467 xoff = MHD_http_unescape (xbuf);
468 /* finally: call application! */
469 pp->must_ikvi = MHD_NO;
470 if (MHD_NO == pp->ikvi (pp->cls,
471 MHD_POSTDATA_KIND,
472 (const char *) &pp[1], /* key */
473 NULL,
474 NULL,
475 NULL,
476 xbuf,
477 pp->value_offset,
478 xoff))
479 {
480 pp->state = PP_Error;
481 return MHD_NO;
482 }
483 pp->value_offset += xoff;
484
485 /* are we done with the value? */
486 if (end_of_value_found)
487 {
488 /* we found the end of the value! */
489 if ( ('\n' == post_data[poff]) ||
490 ('\r' == post_data[poff]) )
373 { 491 {
374 case PP_Error: 492 pp->state = PP_ExpectNewLine;
375 return MHD_NO; 493 }
376 case PP_Done: 494 else if ('&' == post_data[poff])
377 /* did not expect to receive more data */ 495 {
378 pp->state = PP_Error; 496 poff++; /* skip '&' */
379 return MHD_NO; 497 pp->state = PP_Init;
380 case PP_Init:
381 equals = 0;
382 while ((equals + poff < post_data_len) &&
383 (post_data[equals + poff] != '='))
384 equals++;
385 if (equals + pp->buffer_pos > pp->buffer_size)
386 {
387 pp->state = PP_Error; /* out of memory */
388 return MHD_NO;
389 }
390 memcpy (&buf[pp->buffer_pos], &post_data[poff], equals);
391 pp->buffer_pos += equals;
392 if (equals + poff == post_data_len)
393 return MHD_YES; /* no '=' yet */
394 buf[pp->buffer_pos] = '\0'; /* 0-terminate key */
395 pp->buffer_pos = 0; /* reset for next key */
396 MHD_unescape_plus (buf);
397 MHD_http_unescape (buf);
398 poff += equals + 1;
399 pp->state = PP_ProcessValue;
400 pp->value_offset = 0;
401 break;
402 case PP_ProcessValue:
403 /* obtain rest of value from previous iteration */
404 memcpy (xbuf, pp->xbuf, pp->xbuf_pos);
405 xoff = pp->xbuf_pos;
406 pp->xbuf_pos = 0;
407
408 /* find last position in input buffer that is part of the value */
409 amper = 0;
410 while ((amper + poff < post_data_len) &&
411 (amper < XBUF_SIZE) &&
412 (post_data[amper + poff] != '&') &&
413 (post_data[amper + poff] != '\n') &&
414 (post_data[amper + poff] != '\r'))
415 amper++;
416 end_of_value_found = ((amper + poff < post_data_len) &&
417 ((post_data[amper + poff] == '&') ||
418 (post_data[amper + poff] == '\n') ||
419 (post_data[amper + poff] == '\r')));
420 /* compute delta, the maximum number of bytes that we will be able to
421 process right now (either amper-limited of xbuf-size limited) */
422 delta = amper;
423 if (delta > XBUF_SIZE - xoff)
424 delta = XBUF_SIZE - xoff;
425
426 /* move input into processing buffer */
427 memcpy (&xbuf[xoff], &post_data[poff], delta);
428 xoff += delta;
429 poff += delta;
430
431 /* find if escape sequence is at the end of the processing buffer;
432 if so, exclude those from processing (reduce delta to point at
433 end of processed region) */
434 delta = xoff;
435 if ((delta > 0) &&
436 ('%' == xbuf[delta - 1]))
437 delta--;
438 else if ((delta > 1) &&
439 ('%' == xbuf[delta - 2]))
440 delta -= 2;
441
442 /* if we have an incomplete escape sequence, save it to
443 pp->xbuf for later */
444 if (delta < xoff)
445 {
446 memcpy (pp->xbuf,
447 &xbuf[delta],
448 xoff - delta);
449 pp->xbuf_pos = xoff - delta;
450 xoff = delta;
451 }
452
453 /* If we have nothing to do (delta == 0) and
454 not just because the value is empty (are
455 waiting for more data), go for next iteration */
456 if ( (0 == xoff) &&
457 (poff == post_data_len))
458 continue;
459
460 /* unescape */
461 xbuf[xoff] = '\0'; /* 0-terminate in preparation */
462 MHD_unescape_plus (xbuf);
463 xoff = MHD_http_unescape (xbuf);
464 /* finally: call application! */
465 pp->must_ikvi = MHD_NO;
466 if (MHD_NO == pp->ikvi (pp->cls,
467 MHD_POSTDATA_KIND,
468 (const char *) &pp[1], /* key */
469 NULL,
470 NULL,
471 NULL,
472 xbuf,
473 pp->value_offset,
474 xoff))
475 {
476 pp->state = PP_Error;
477 return MHD_NO;
478 }
479 pp->value_offset += xoff;
480
481 /* are we done with the value? */
482 if (end_of_value_found)
483 {
484 /* we found the end of the value! */
485 if ( ('\n' == post_data[poff]) ||
486 ('\r' == post_data[poff]) )
487 {
488 pp->state = PP_ExpectNewLine;
489 }
490 else if ('&' == post_data[poff])
491 {
492 poff++; /* skip '&' */
493 pp->state = PP_Init;
494 }
495 }
496 break;
497 case PP_ExpectNewLine:
498 if ( ('\n' == post_data[poff]) ||
499 ('\r' == post_data[poff]) )
500 {
501 poff++;
502 /* we are done, report error if we receive any more... */
503 pp->state = PP_Done;
504 return MHD_YES;
505 }
506 return MHD_NO;
507 default:
508 mhd_panic (mhd_panic_cls,
509 __FILE__,
510 __LINE__,
511 NULL); /* should never happen! */
512 } 498 }
499 }
500 break;
501 case PP_ExpectNewLine:
502 if ( ('\n' == post_data[poff]) ||
503 ('\r' == post_data[poff]) )
504 {
505 poff++;
506 /* we are done, report error if we receive any more... */
507 pp->state = PP_Done;
508 return MHD_YES;
509 }
510 return MHD_NO;
511 default:
512 mhd_panic (mhd_panic_cls,
513 __FILE__,
514 __LINE__,
515 NULL); /* should never happen! */
513 } 516 }
517 }
514 return MHD_YES; 518 return MHD_YES;
515} 519}
516 520
@@ -534,16 +538,16 @@ try_match_header (const char *prefix,
534 if (NULL != *suffix) 538 if (NULL != *suffix)
535 return MHD_NO; 539 return MHD_NO;
536 while (0 != *line) 540 while (0 != *line)
541 {
542 if (MHD_str_equal_caseless_n_ (prefix,
543 line,
544 prefix_len))
537 { 545 {
538 if (MHD_str_equal_caseless_n_ (prefix, 546 *suffix = strdup (&line[prefix_len]);
539 line, 547 return MHD_YES;
540 prefix_len))
541 {
542 *suffix = strdup (&line[prefix_len]);
543 return MHD_YES;
544 }
545 ++line;
546 } 548 }
549 ++line;
550 }
547 return MHD_NO; 551 return MHD_NO;
548} 552}
549 553
@@ -573,40 +577,39 @@ find_boundary (struct MHD_PostProcessor *pp,
573 const char *dash; 577 const char *dash;
574 578
575 if (pp->buffer_pos < 2 + blen) 579 if (pp->buffer_pos < 2 + blen)
576 { 580 {
577 if (pp->buffer_pos == pp->buffer_size) 581 if (pp->buffer_pos == pp->buffer_size)
578 pp->state = PP_Error; /* out of memory */ 582 pp->state = PP_Error; /* out of memory */
579 /* ++(*ioffptr); */ 583 /* ++(*ioffptr); */
580 return MHD_NO; /* not enough data */ 584 return MHD_NO; /* not enough data */
581 } 585 }
582 if ( (0 != memcmp ("--", 586 if ( (0 != memcmp ("--",
583 buf, 587 buf,
584 2)) || 588 2)) ||
585 (0 != memcmp (&buf[2], 589 (0 != memcmp (&buf[2],
586 boundary, 590 boundary,
587 blen))) 591 blen)))
592 {
593 if (pp->state != PP_Init)
588 { 594 {
589 if (pp->state != PP_Init) 595 /* garbage not allowed */
590 { 596 pp->state = PP_Error;
591 /* garbage not allowed */ 597 }
592 pp->state = PP_Error; 598 else
593 } 599 {
600 /* skip over garbage (RFC 2046, 5.1.1) */
601 dash = memchr (buf,
602 '-',
603 pp->buffer_pos);
604 if (NULL == dash)
605 (*ioffptr) += pp->buffer_pos; /* skip entire buffer */
606 else if (dash == buf)
607 (*ioffptr)++; /* at least skip one byte */
594 else 608 else
595 { 609 (*ioffptr) += dash - buf; /* skip to first possible boundary */
596 /* skip over garbage (RFC 2046, 5.1.1) */
597 dash = memchr (buf,
598 '-',
599 pp->buffer_pos);
600 if (NULL == dash)
601 (*ioffptr) += pp->buffer_pos; /* skip entire buffer */
602 else
603 if (dash == buf)
604 (*ioffptr)++; /* at least skip one byte */
605 else
606 (*ioffptr) += dash - buf; /* skip to first possible boundary */
607 }
608 return MHD_NO; /* expected boundary */
609 } 610 }
611 return MHD_NO; /* expected boundary */
612 }
610 /* remove boundary from buffer */ 613 /* remove boundary from buffer */
611 (*ioffptr) += 2 + blen; 614 (*ioffptr) += 2 + blen;
612 /* next: start with headers */ 615 /* next: start with headers */
@@ -625,8 +628,8 @@ find_boundary (struct MHD_PostProcessor *pp,
625 */ 628 */
626static void 629static void
627try_get_value (const char *buf, 630try_get_value (const char *buf,
628 const char *key, 631 const char *key,
629 char **destination) 632 char **destination)
630{ 633{
631 const char *spos; 634 const char *spos;
632 const char *bpos; 635 const char *bpos;
@@ -639,30 +642,30 @@ try_get_value (const char *buf,
639 bpos = buf; 642 bpos = buf;
640 klen = strlen (key); 643 klen = strlen (key);
641 while (NULL != (spos = strstr (bpos, key))) 644 while (NULL != (spos = strstr (bpos, key)))
645 {
646 if ( (spos[klen] != '=') ||
647 ( (spos != buf) &&
648 (spos[-1] != ' ') ) )
642 { 649 {
643 if ( (spos[klen] != '=') || 650 /* no match */
644 ( (spos != buf) && 651 bpos = spos + 1;
645 (spos[-1] != ' ') ) ) 652 continue;
646 {
647 /* no match */
648 bpos = spos + 1;
649 continue;
650 }
651 if (spos[klen + 1] != '"')
652 return; /* not quoted */
653 if (NULL == (endv = strchr (&spos[klen + 2],
654 '\"')))
655 return; /* no end-quote */
656 vlen = endv - spos - klen - 1;
657 *destination = malloc (vlen);
658 if (NULL == *destination)
659 return; /* out of memory */
660 (*destination)[vlen - 1] = '\0';
661 memcpy (*destination,
662 &spos[klen + 2],
663 vlen - 1);
664 return; /* success */
665 } 653 }
654 if (spos[klen + 1] != '"')
655 return; /* not quoted */
656 if (NULL == (endv = strchr (&spos[klen + 2],
657 '\"')))
658 return; /* no end-quote */
659 vlen = endv - spos - klen - 1;
660 *destination = malloc (vlen);
661 if (NULL == *destination)
662 return; /* out of memory */
663 (*destination)[vlen - 1] = '\0';
664 memcpy (*destination,
665 &spos[klen + 2],
666 vlen - 1);
667 return; /* success */
668 }
666} 669}
667 670
668 671
@@ -695,19 +698,19 @@ process_multipart_headers (struct MHD_PostProcessor *pp,
695 (buf[newline] != '\n') ) 698 (buf[newline] != '\n') )
696 newline++; 699 newline++;
697 if (newline == pp->buffer_size) 700 if (newline == pp->buffer_size)
698 { 701 {
699 pp->state = PP_Error; 702 pp->state = PP_Error;
700 return MHD_NO; /* out of memory */ 703 return MHD_NO; /* out of memory */
701 } 704 }
702 if (newline == pp->buffer_pos) 705 if (newline == pp->buffer_pos)
703 return MHD_NO; /* will need more data */ 706 return MHD_NO; /* will need more data */
704 if (0 == newline) 707 if (0 == newline)
705 { 708 {
706 /* empty line - end of headers */ 709 /* empty line - end of headers */
707 pp->skip_rn = RN_Full; 710 pp->skip_rn = RN_Full;
708 pp->state = next_state; 711 pp->state = next_state;
709 return MHD_YES; 712 return MHD_YES;
710 } 713 }
711 /* got an actual header */ 714 /* got an actual header */
712 if (buf[newline] == '\r') 715 if (buf[newline] == '\r')
713 pp->skip_rn = RN_OptN; 716 pp->skip_rn = RN_OptN;
@@ -715,25 +718,25 @@ process_multipart_headers (struct MHD_PostProcessor *pp,
715 if (MHD_str_equal_caseless_n_ ("Content-disposition: ", 718 if (MHD_str_equal_caseless_n_ ("Content-disposition: ",
716 buf, 719 buf,
717 MHD_STATICSTR_LEN_ ("Content-disposition: "))) 720 MHD_STATICSTR_LEN_ ("Content-disposition: ")))
718 { 721 {
719 try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")], 722 try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
720 "name", 723 "name",
721 &pp->content_name); 724 &pp->content_name);
722 try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")], 725 try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
723 "filename", 726 "filename",
724 &pp->content_filename); 727 &pp->content_filename);
725 } 728 }
726 else 729 else
727 { 730 {
728 try_match_header ("Content-type: ", 731 try_match_header ("Content-type: ",
729 MHD_STATICSTR_LEN_("Content-type: "), 732 MHD_STATICSTR_LEN_ ("Content-type: "),
730 buf, 733 buf,
731 &pp->content_type); 734 &pp->content_type);
732 try_match_header ("Content-Transfer-Encoding: ", 735 try_match_header ("Content-Transfer-Encoding: ",
733 MHD_STATICSTR_LEN_("Content-Transfer-Encoding: "), 736 MHD_STATICSTR_LEN_ ("Content-Transfer-Encoding: "),
734 buf, 737 buf,
735 &pp->content_transfer_encoding); 738 &pp->content_transfer_encoding);
736 } 739 }
737 (*ioffptr) += newline + 1; 740 (*ioffptr) += newline + 1;
738 return MHD_YES; 741 return MHD_YES;
739} 742}
@@ -771,79 +774,79 @@ process_value_to_boundary (struct MHD_PostProcessor *pp,
771 (\r\n--+boundary) is part of the value */ 774 (\r\n--+boundary) is part of the value */
772 newline = 0; 775 newline = 0;
773 while (1) 776 while (1)
777 {
778 while (newline + 4 < pp->buffer_pos)
774 { 779 {
775 while (newline + 4 < pp->buffer_pos) 780 r = memchr (&buf[newline],
776 { 781 '\r',
777 r = memchr (&buf[newline], 782 pp->buffer_pos - newline - 4);
778 '\r', 783 if (NULL == r)
779 pp->buffer_pos - newline - 4); 784 {
780 if (NULL == r) 785 newline = pp->buffer_pos - 4;
781 { 786 break;
782 newline = pp->buffer_pos - 4; 787 }
783 break; 788 newline = r - buf;
784 } 789 if (0 == memcmp ("\r\n--",
785 newline = r - buf; 790 &buf[newline],
786 if (0 == memcmp ("\r\n--", 791 4))
787 &buf[newline], 792 break;
788 4)) 793 newline++;
789 break; 794 }
790 newline++; 795 if (newline + blen + 4 <= pp->buffer_pos)
791 } 796 {
792 if (newline + blen + 4 <= pp->buffer_pos) 797 /* can check boundary */
793 { 798 if (0 != memcmp (&buf[newline + 4],
794 /* can check boundary */ 799 boundary,
795 if (0 != memcmp (&buf[newline + 4], 800 blen))
796 boundary, 801 {
797 blen)) 802 /* no boundary, "\r\n--" is part of content, skip */
798 { 803 newline += 4;
799 /* no boundary, "\r\n--" is part of content, skip */ 804 continue;
800 newline += 4; 805 }
801 continue;
802 }
803 else
804 {
805 /* boundary found, process until newline then
806 skip boundary and go back to init */
807 pp->skip_rn = RN_Dash;
808 pp->state = next_state;
809 pp->dash_state = next_dash_state;
810 (*ioffptr) += blen + 4; /* skip boundary as well */
811 buf[newline] = '\0';
812 break;
813 }
814 }
815 else 806 else
816 { 807 {
817 /* cannot check for boundary, process content that 808 /* boundary found, process until newline then
818 we have and check again later; except, if we have 809 skip boundary and go back to init */
819 no content, abort (out of memory) */ 810 pp->skip_rn = RN_Dash;
820 if ( (0 == newline) && 811 pp->state = next_state;
821 (pp->buffer_pos == pp->buffer_size) ) 812 pp->dash_state = next_dash_state;
822 { 813 (*ioffptr) += blen + 4; /* skip boundary as well */
823 pp->state = PP_Error; 814 buf[newline] = '\0';
824 return MHD_NO; 815 break;
825 } 816 }
826 break;
827 }
828 } 817 }
818 else
819 {
820 /* cannot check for boundary, process content that
821 we have and check again later; except, if we have
822 no content, abort (out of memory) */
823 if ( (0 == newline) &&
824 (pp->buffer_pos == pp->buffer_size) )
825 {
826 pp->state = PP_Error;
827 return MHD_NO;
828 }
829 break;
830 }
831 }
829 /* newline is either at beginning of boundary or 832 /* newline is either at beginning of boundary or
830 at least at the last character that we are sure 833 at least at the last character that we are sure
831 is not part of the boundary */ 834 is not part of the boundary */
832 if ( ( (MHD_YES == pp->must_ikvi) || 835 if ( ( (MHD_YES == pp->must_ikvi) ||
833 (0 != newline) ) && 836 (0 != newline) ) &&
834 (MHD_NO == pp->ikvi (pp->cls, 837 (MHD_NO == pp->ikvi (pp->cls,
835 MHD_POSTDATA_KIND, 838 MHD_POSTDATA_KIND,
836 pp->content_name, 839 pp->content_name,
837 pp->content_filename, 840 pp->content_filename,
838 pp->content_type, 841 pp->content_type,
839 pp->content_transfer_encoding, 842 pp->content_transfer_encoding,
840 buf, 843 buf,
841 pp->value_offset, 844 pp->value_offset,
842 newline)) ) 845 newline)) )
843 { 846 {
844 pp->state = PP_Error; 847 pp->state = PP_Error;
845 return MHD_NO; 848 return MHD_NO;
846 } 849 }
847 pp->must_ikvi = MHD_NO; 850 pp->must_ikvi = MHD_NO;
848 pp->value_offset += newline; 851 pp->value_offset += newline;
849 (*ioffptr) += newline; 852 (*ioffptr) += newline;
@@ -860,28 +863,28 @@ free_unmarked (struct MHD_PostProcessor *pp)
860{ 863{
861 if ( (NULL != pp->content_name) && 864 if ( (NULL != pp->content_name) &&
862 (0 == (pp->have & NE_content_name)) ) 865 (0 == (pp->have & NE_content_name)) )
863 { 866 {
864 free (pp->content_name); 867 free (pp->content_name);
865 pp->content_name = NULL; 868 pp->content_name = NULL;
866 } 869 }
867 if ( (NULL != pp->content_type) && 870 if ( (NULL != pp->content_type) &&
868 (0 == (pp->have & NE_content_type)) ) 871 (0 == (pp->have & NE_content_type)) )
869 { 872 {
870 free (pp->content_type); 873 free (pp->content_type);
871 pp->content_type = NULL; 874 pp->content_type = NULL;
872 } 875 }
873 if ( (NULL != pp->content_filename) && 876 if ( (NULL != pp->content_filename) &&
874 (0 == (pp->have & NE_content_filename)) ) 877 (0 == (pp->have & NE_content_filename)) )
875 { 878 {
876 free (pp->content_filename); 879 free (pp->content_filename);
877 pp->content_filename = NULL; 880 pp->content_filename = NULL;
878 } 881 }
879 if ( (NULL != pp->content_transfer_encoding) && 882 if ( (NULL != pp->content_transfer_encoding) &&
880 (0 == (pp->have & NE_content_transfer_encoding)) ) 883 (0 == (pp->have & NE_content_transfer_encoding)) )
881 { 884 {
882 free (pp->content_transfer_encoding); 885 free (pp->content_transfer_encoding);
883 pp->content_transfer_encoding = NULL; 886 pp->content_transfer_encoding = NULL;
884 } 887 }
885} 888}
886 889
887 890
@@ -896,7 +899,7 @@ free_unmarked (struct MHD_PostProcessor *pp)
896static int 899static int
897post_process_multipart (struct MHD_PostProcessor *pp, 900post_process_multipart (struct MHD_PostProcessor *pp,
898 const char *post_data, 901 const char *post_data,
899 size_t post_data_len) 902 size_t post_data_len)
900{ 903{
901 char *buf; 904 char *buf;
902 size_t max; 905 size_t max;
@@ -911,294 +914,294 @@ post_process_multipart (struct MHD_PostProcessor *pp,
911 while ( (poff < post_data_len) || 914 while ( (poff < post_data_len) ||
912 ( (pp->buffer_pos > 0) && 915 ( (pp->buffer_pos > 0) &&
913 (0 != state_changed) ) ) 916 (0 != state_changed) ) )
917 {
918 /* first, move as much input data
919 as possible to our internal buffer */
920 max = pp->buffer_size - pp->buffer_pos;
921 if (max > post_data_len - poff)
922 max = post_data_len - poff;
923 memcpy (&buf[pp->buffer_pos],
924 &post_data[poff],
925 max);
926 poff += max;
927 pp->buffer_pos += max;
928 if ( (0 == max) &&
929 (0 == state_changed) &&
930 (poff < post_data_len) )
914 { 931 {
915 /* first, move as much input data 932 pp->state = PP_Error;
916 as possible to our internal buffer */ 933 return MHD_NO; /* out of memory */
917 max = pp->buffer_size - pp->buffer_pos; 934 }
918 if (max > post_data_len - poff) 935 state_changed = 0;
919 max = post_data_len - poff;
920 memcpy (&buf[pp->buffer_pos],
921 &post_data[poff],
922 max);
923 poff += max;
924 pp->buffer_pos += max;
925 if ( (0 == max) &&
926 (0 == state_changed) &&
927 (poff < post_data_len) )
928 {
929 pp->state = PP_Error;
930 return MHD_NO; /* out of memory */
931 }
932 state_changed = 0;
933 936
934 /* first state machine for '\r'-'\n' and '--' handling */ 937 /* first state machine for '\r'-'\n' and '--' handling */
935 switch (pp->skip_rn) 938 switch (pp->skip_rn)
939 {
940 case RN_Inactive:
941 break;
942 case RN_OptN:
943 if (buf[0] == '\n')
944 {
945 ioff++;
946 pp->skip_rn = RN_Inactive;
947 goto AGAIN;
948 }
949 /* fall-through! */
950 case RN_Dash:
951 if (buf[0] == '-')
952 {
953 ioff++;
954 pp->skip_rn = RN_Dash2;
955 goto AGAIN;
956 }
957 pp->skip_rn = RN_Full;
958 /* fall-through! */
959 case RN_Full:
960 if (buf[0] == '\r')
961 {
962 if ( (pp->buffer_pos > 1) &&
963 ('\n' == buf[1]) )
936 { 964 {
937 case RN_Inactive:
938 break;
939 case RN_OptN:
940 if (buf[0] == '\n')
941 {
942 ioff++;
943 pp->skip_rn = RN_Inactive;
944 goto AGAIN;
945 }
946 /* fall-through! */
947 case RN_Dash:
948 if (buf[0] == '-')
949 {
950 ioff++;
951 pp->skip_rn = RN_Dash2;
952 goto AGAIN;
953 }
954 pp->skip_rn = RN_Full;
955 /* fall-through! */
956 case RN_Full:
957 if (buf[0] == '\r')
958 {
959 if ( (pp->buffer_pos > 1) &&
960 ('\n' == buf[1]) )
961 {
962 pp->skip_rn = RN_Inactive;
963 ioff += 2;
964 }
965 else
966 {
967 pp->skip_rn = RN_OptN;
968 ioff++;
969 }
970 goto AGAIN;
971 }
972 if (buf[0] == '\n')
973 {
974 ioff++;
975 pp->skip_rn = RN_Inactive;
976 goto AGAIN;
977 }
978 pp->skip_rn = RN_Inactive; 965 pp->skip_rn = RN_Inactive;
979 pp->state = PP_Error; 966 ioff += 2;
980 return MHD_NO; /* no '\r\n' */
981 case RN_Dash2:
982 if (buf[0] == '-')
983 {
984 ioff++;
985 pp->skip_rn = RN_Full;
986 pp->state = pp->dash_state;
987 goto AGAIN;
988 }
989 pp->state = PP_Error;
990 break;
991 } 967 }
992 968 else
993 /* main state engine */
994 switch (pp->state)
995 { 969 {
996 case PP_Error: 970 pp->skip_rn = RN_OptN;
971 ioff++;
972 }
973 goto AGAIN;
974 }
975 if (buf[0] == '\n')
976 {
977 ioff++;
978 pp->skip_rn = RN_Inactive;
979 goto AGAIN;
980 }
981 pp->skip_rn = RN_Inactive;
982 pp->state = PP_Error;
983 return MHD_NO; /* no '\r\n' */
984 case RN_Dash2:
985 if (buf[0] == '-')
986 {
987 ioff++;
988 pp->skip_rn = RN_Full;
989 pp->state = pp->dash_state;
990 goto AGAIN;
991 }
992 pp->state = PP_Error;
993 break;
994 }
995
996 /* main state engine */
997 switch (pp->state)
998 {
999 case PP_Error:
1000 return MHD_NO;
1001 case PP_Done:
1002 /* did not expect to receive more data */
1003 pp->state = PP_Error;
1004 return MHD_NO;
1005 case PP_Init:
1006 /**
1007 * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything
1008 * prior to the first multipart boundary:
1009 *
1010 * > There appears to be room for additional information prior
1011 * > to the first boundary delimiter line and following the
1012 * > final boundary delimiter line. These areas should
1013 * > generally be left blank, and implementations must ignore
1014 * > anything that appears before the first boundary delimiter
1015 * > line or after the last one.
1016 */
1017 (void) find_boundary (pp,
1018 pp->boundary,
1019 pp->blen,
1020 &ioff,
1021 PP_ProcessEntryHeaders,
1022 PP_Done);
1023 break;
1024 case PP_NextBoundary:
1025 if (MHD_NO == find_boundary (pp,
1026 pp->boundary,
1027 pp->blen,
1028 &ioff,
1029 PP_ProcessEntryHeaders,
1030 PP_Done))
1031 {
1032 if (pp->state == PP_Error)
997 return MHD_NO; 1033 return MHD_NO;
998 case PP_Done: 1034 goto END;
999 /* did not expect to receive more data */ 1035 }
1036 break;
1037 case PP_ProcessEntryHeaders:
1038 pp->must_ikvi = MHD_YES;
1039 if (MHD_NO ==
1040 process_multipart_headers (pp,
1041 &ioff,
1042 PP_PerformCheckMultipart))
1043 {
1044 if (pp->state == PP_Error)
1045 return MHD_NO;
1046 else
1047 goto END;
1048 }
1049 state_changed = 1;
1050 break;
1051 case PP_PerformCheckMultipart:
1052 if ( (NULL != pp->content_type) &&
1053 (MHD_str_equal_caseless_n_ (pp->content_type,
1054 "multipart/mixed",
1055 MHD_STATICSTR_LEN_ ("multipart/mixed"))))
1056 {
1057 pp->nested_boundary = strstr (pp->content_type,
1058 "boundary=");
1059 if (NULL == pp->nested_boundary)
1060 {
1000 pp->state = PP_Error; 1061 pp->state = PP_Error;
1001 return MHD_NO; 1062 return MHD_NO;
1002 case PP_Init:
1003 /**
1004 * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything
1005 * prior to the first multipart boundary:
1006 *
1007 * > There appears to be room for additional information prior
1008 * > to the first boundary delimiter line and following the
1009 * > final boundary delimiter line. These areas should
1010 * > generally be left blank, and implementations must ignore
1011 * > anything that appears before the first boundary delimiter
1012 * > line or after the last one.
1013 */
1014 (void) find_boundary (pp,
1015 pp->boundary,
1016 pp->blen,
1017 &ioff,
1018 PP_ProcessEntryHeaders,
1019 PP_Done);
1020 break;
1021 case PP_NextBoundary:
1022 if (MHD_NO == find_boundary (pp,
1023 pp->boundary,
1024 pp->blen,
1025 &ioff,
1026 PP_ProcessEntryHeaders,
1027 PP_Done))
1028 {
1029 if (pp->state == PP_Error)
1030 return MHD_NO;
1031 goto END;
1032 }
1033 break;
1034 case PP_ProcessEntryHeaders:
1035 pp->must_ikvi = MHD_YES;
1036 if (MHD_NO ==
1037 process_multipart_headers (pp,
1038 &ioff,
1039 PP_PerformCheckMultipart))
1040 {
1041 if (pp->state == PP_Error)
1042 return MHD_NO;
1043 else
1044 goto END;
1045 }
1046 state_changed = 1;
1047 break;
1048 case PP_PerformCheckMultipart:
1049 if ( (NULL != pp->content_type) &&
1050 (MHD_str_equal_caseless_n_ (pp->content_type,
1051 "multipart/mixed",
1052 MHD_STATICSTR_LEN_ ("multipart/mixed"))))
1053 {
1054 pp->nested_boundary = strstr (pp->content_type,
1055 "boundary=");
1056 if (NULL == pp->nested_boundary)
1057 {
1058 pp->state = PP_Error;
1059 return MHD_NO;
1060 }
1061 pp->nested_boundary =
1062 strdup (&pp->nested_boundary[MHD_STATICSTR_LEN_ ("boundary=")]);
1063 if (NULL == pp->nested_boundary)
1064 {
1065 /* out of memory */
1066 pp->state = PP_Error;
1067 return MHD_NO;
1068 }
1069 /* free old content type, we will need that field
1070 for the content type of the nested elements */
1071 free (pp->content_type);
1072 pp->content_type = NULL;
1073 pp->nlen = strlen (pp->nested_boundary);
1074 pp->state = PP_Nested_Init;
1075 state_changed = 1;
1076 break;
1077 }
1078 pp->state = PP_ProcessValueToBoundary;
1079 pp->value_offset = 0;
1080 state_changed = 1;
1081 break;
1082 case PP_ProcessValueToBoundary:
1083 if (MHD_NO == process_value_to_boundary (pp,
1084 &ioff,
1085 pp->boundary,
1086 pp->blen,
1087 PP_PerformCleanup,
1088 PP_Done))
1089 {
1090 if (pp->state == PP_Error)
1091 return MHD_NO;
1092 break;
1093 }
1094 break;
1095 case PP_PerformCleanup:
1096 /* clean up state of one multipart form-data element! */
1097 pp->have = NE_none;
1098 free_unmarked (pp);
1099 if (NULL != pp->nested_boundary)
1100 {
1101 free (pp->nested_boundary);
1102 pp->nested_boundary = NULL;
1103 }
1104 pp->state = PP_ProcessEntryHeaders;
1105 state_changed = 1;
1106 break;
1107 case PP_Nested_Init:
1108 if (NULL == pp->nested_boundary)
1109 {
1110 pp->state = PP_Error;
1111 return MHD_NO;
1112 }
1113 if (MHD_NO == find_boundary (pp,
1114 pp->nested_boundary,
1115 pp->nlen,
1116 &ioff,
1117 PP_Nested_PerformMarking,
1118 PP_NextBoundary /* or PP_Error? */ ))
1119 {
1120 if (pp->state == PP_Error)
1121 return MHD_NO;
1122 goto END;
1123 }
1124 break;
1125 case PP_Nested_PerformMarking:
1126 /* remember what headers were given
1127 globally */
1128 pp->have = NE_none;
1129 if (NULL != pp->content_name)
1130 pp->have |= NE_content_name;
1131 if (NULL != pp->content_type)
1132 pp->have |= NE_content_type;
1133 if (NULL != pp->content_filename)
1134 pp->have |= NE_content_filename;
1135 if (NULL != pp->content_transfer_encoding)
1136 pp->have |= NE_content_transfer_encoding;
1137 pp->state = PP_Nested_ProcessEntryHeaders;
1138 state_changed = 1;
1139 break;
1140 case PP_Nested_ProcessEntryHeaders:
1141 pp->value_offset = 0;
1142 if (MHD_NO ==
1143 process_multipart_headers (pp,
1144 &ioff,
1145 PP_Nested_ProcessValueToBoundary))
1146 {
1147 if (pp->state == PP_Error)
1148 return MHD_NO;
1149 else
1150 goto END;
1151 }
1152 state_changed = 1;
1153 break;
1154 case PP_Nested_ProcessValueToBoundary:
1155 if (MHD_NO == process_value_to_boundary (pp,
1156 &ioff,
1157 pp->nested_boundary,
1158 pp->nlen,
1159 PP_Nested_PerformCleanup,
1160 PP_NextBoundary))
1161 {
1162 if (pp->state == PP_Error)
1163 return MHD_NO;
1164 break;
1165 }
1166 break;
1167 case PP_Nested_PerformCleanup:
1168 free_unmarked (pp);
1169 pp->state = PP_Nested_ProcessEntryHeaders;
1170 state_changed = 1;
1171 break;
1172 default:
1173 mhd_panic (mhd_panic_cls,
1174 __FILE__,
1175 __LINE__,
1176 NULL); /* should never happen! */
1177 } 1063 }
1178 AGAIN: 1064 pp->nested_boundary =
1179 if (ioff > 0) 1065 strdup (&pp->nested_boundary[MHD_STATICSTR_LEN_ ("boundary=")]);
1066 if (NULL == pp->nested_boundary)
1180 { 1067 {
1181 memmove (buf, 1068 /* out of memory */
1182 &buf[ioff], 1069 pp->state = PP_Error;
1183 pp->buffer_pos - ioff); 1070 return MHD_NO;
1184 pp->buffer_pos -= ioff;
1185 ioff = 0;
1186 state_changed = 1;
1187 } 1071 }
1072 /* free old content type, we will need that field
1073 for the content type of the nested elements */
1074 free (pp->content_type);
1075 pp->content_type = NULL;
1076 pp->nlen = strlen (pp->nested_boundary);
1077 pp->state = PP_Nested_Init;
1078 state_changed = 1;
1079 break;
1080 }
1081 pp->state = PP_ProcessValueToBoundary;
1082 pp->value_offset = 0;
1083 state_changed = 1;
1084 break;
1085 case PP_ProcessValueToBoundary:
1086 if (MHD_NO == process_value_to_boundary (pp,
1087 &ioff,
1088 pp->boundary,
1089 pp->blen,
1090 PP_PerformCleanup,
1091 PP_Done))
1092 {
1093 if (pp->state == PP_Error)
1094 return MHD_NO;
1095 break;
1096 }
1097 break;
1098 case PP_PerformCleanup:
1099 /* clean up state of one multipart form-data element! */
1100 pp->have = NE_none;
1101 free_unmarked (pp);
1102 if (NULL != pp->nested_boundary)
1103 {
1104 free (pp->nested_boundary);
1105 pp->nested_boundary = NULL;
1106 }
1107 pp->state = PP_ProcessEntryHeaders;
1108 state_changed = 1;
1109 break;
1110 case PP_Nested_Init:
1111 if (NULL == pp->nested_boundary)
1112 {
1113 pp->state = PP_Error;
1114 return MHD_NO;
1115 }
1116 if (MHD_NO == find_boundary (pp,
1117 pp->nested_boundary,
1118 pp->nlen,
1119 &ioff,
1120 PP_Nested_PerformMarking,
1121 PP_NextBoundary /* or PP_Error? */))
1122 {
1123 if (pp->state == PP_Error)
1124 return MHD_NO;
1125 goto END;
1126 }
1127 break;
1128 case PP_Nested_PerformMarking:
1129 /* remember what headers were given
1130 globally */
1131 pp->have = NE_none;
1132 if (NULL != pp->content_name)
1133 pp->have |= NE_content_name;
1134 if (NULL != pp->content_type)
1135 pp->have |= NE_content_type;
1136 if (NULL != pp->content_filename)
1137 pp->have |= NE_content_filename;
1138 if (NULL != pp->content_transfer_encoding)
1139 pp->have |= NE_content_transfer_encoding;
1140 pp->state = PP_Nested_ProcessEntryHeaders;
1141 state_changed = 1;
1142 break;
1143 case PP_Nested_ProcessEntryHeaders:
1144 pp->value_offset = 0;
1145 if (MHD_NO ==
1146 process_multipart_headers (pp,
1147 &ioff,
1148 PP_Nested_ProcessValueToBoundary))
1149 {
1150 if (pp->state == PP_Error)
1151 return MHD_NO;
1152 else
1153 goto END;
1154 }
1155 state_changed = 1;
1156 break;
1157 case PP_Nested_ProcessValueToBoundary:
1158 if (MHD_NO == process_value_to_boundary (pp,
1159 &ioff,
1160 pp->nested_boundary,
1161 pp->nlen,
1162 PP_Nested_PerformCleanup,
1163 PP_NextBoundary))
1164 {
1165 if (pp->state == PP_Error)
1166 return MHD_NO;
1167 break;
1168 }
1169 break;
1170 case PP_Nested_PerformCleanup:
1171 free_unmarked (pp);
1172 pp->state = PP_Nested_ProcessEntryHeaders;
1173 state_changed = 1;
1174 break;
1175 default:
1176 mhd_panic (mhd_panic_cls,
1177 __FILE__,
1178 __LINE__,
1179 NULL); /* should never happen! */
1188 } 1180 }
1189END: 1181AGAIN:
1190 if (0 != ioff) 1182 if (ioff > 0)
1191 { 1183 {
1192 memmove (buf, 1184 memmove (buf,
1193 &buf[ioff], 1185 &buf[ioff],
1194 pp->buffer_pos - ioff); 1186 pp->buffer_pos - ioff);
1195 pp->buffer_pos -= ioff; 1187 pp->buffer_pos -= ioff;
1188 ioff = 0;
1189 state_changed = 1;
1196 } 1190 }
1191 }
1192END:
1193 if (0 != ioff)
1194 {
1195 memmove (buf,
1196 &buf[ioff],
1197 pp->buffer_pos - ioff);
1198 pp->buffer_pos -= ioff;
1199 }
1197 if (poff < post_data_len) 1200 if (poff < post_data_len)
1198 { 1201 {
1199 pp->state = PP_Error; 1202 pp->state = PP_Error;
1200 return MHD_NO; /* serious error */ 1203 return MHD_NO; /* serious error */
1201 } 1204 }
1202 return MHD_YES; 1205 return MHD_YES;
1203} 1206}
1204 1207
@@ -1227,13 +1230,15 @@ MHD_post_process (struct MHD_PostProcessor *pp,
1227 return MHD_NO; 1230 return MHD_NO;
1228 if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, 1231 if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
1229 pp->encoding, 1232 pp->encoding,
1230 MHD_STATICSTR_LEN_(MHD_HTTP_POST_ENCODING_FORM_URLENCODED))) 1233 MHD_STATICSTR_LEN_ (
1234 MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
1231 return post_process_urlencoded (pp, 1235 return post_process_urlencoded (pp,
1232 post_data, 1236 post_data,
1233 post_data_len); 1237 post_data_len);
1234 if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, 1238 if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
1235 pp->encoding, 1239 pp->encoding,
1236 MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA))) 1240 MHD_STATICSTR_LEN_ (
1241 MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
1237 return post_process_multipart (pp, 1242 return post_process_multipart (pp,
1238 post_data, 1243 post_data,
1239 post_data_len); 1244 post_data_len);