117 struct MHD_PostProcessor
140 const char *encoding;
145 const char *boundary;
150 char *nested_boundary;
165 char *content_filename;
170 char *content_transfer_encoding;
196 uint64_t value_offset;
271 struct MHD_PostProcessor *
276 struct MHD_PostProcessor *ret;
277 const char *encoding;
278 const char *boundary;
281 if ((buffer_size < 256) || (connection ==
NULL) || (iter ==
NULL))
286 if (encoding ==
NULL)
298 boundary = strstr (boundary,
"boundary=");
299 if (
NULL == boundary)
301 boundary += strlen (
"boundary=");
302 blen = strlen (boundary);
303 if ((blen == 0) || (blen * 2 + 2 > buffer_size))
305 if ( (boundary[0] ==
'"') && (boundary[blen - 1] ==
'"') )
317 if (
NULL == (ret = malloc (
sizeof (
struct MHD_PostProcessor) + buffer_size + 1)))
319 memset (ret, 0,
sizeof (
struct MHD_PostProcessor) + buffer_size + 1);
320 ret->connection = connection;
323 ret->encoding = encoding;
324 ret->buffer_size = buffer_size;
327 ret->boundary = boundary;
343 const char *post_data,
344 size_t post_data_len)
351 int end_of_value_found;
355 buf = (
char *) &pp[1];
357 while (poff < post_data_len)
369 while ((equals + poff < post_data_len) &&
370 (post_data[equals + poff] !=
'='))
372 if (equals + pp->buffer_pos > pp->buffer_size)
377 memcpy (&buf[pp->buffer_pos], &post_data[poff], equals);
378 pp->buffer_pos += equals;
379 if (equals + poff == post_data_len)
381 buf[pp->buffer_pos] =
'\0';
387 pp->value_offset = 0;
391 memcpy (xbuf, pp->xbuf, pp->xbuf_pos);
397 while ((amper + poff < post_data_len) &&
399 (post_data[amper + poff] !=
'&') &&
400 (post_data[amper + poff] !=
'\n') &&
401 (post_data[amper + poff] !=
'\r'))
403 end_of_value_found = ((amper + poff < post_data_len) &&
404 ((post_data[amper + poff] ==
'&') ||
405 (post_data[amper + poff] ==
'\n') ||
406 (post_data[amper + poff] ==
'\r')));
414 memcpy (&xbuf[xoff], &post_data[poff], delta);
422 if ((delta > 0) && (xbuf[delta - 1] ==
'%'))
424 else if ((delta > 1) && (xbuf[delta - 2] ==
'%'))
431 memcpy (pp->xbuf, &xbuf[delta], xoff - delta);
432 pp->xbuf_pos = xoff - delta;
439 if ((xoff == 0) && (poff == post_data_len))
455 pp->value_offset += xoff;
458 if (end_of_value_found)
461 if ((post_data[poff] ==
'\n') || (post_data[poff] ==
'\r'))
465 else if (post_data[poff] ==
'&')
473 if ((post_data[poff] ==
'\n') || (post_data[poff] ==
'\r'))
507 *suffix = strdup (&line[strlen (prefix)]);
531 const char *boundary,
536 char *buf = (
char *) &pp[1];
539 if (pp->buffer_pos < 2 + blen)
541 if (pp->buffer_pos == pp->buffer_size)
546 if ((0 != memcmp (
"--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen)))
556 dash = memchr (buf,
'-', pp->buffer_pos);
558 (*ioffptr) += pp->buffer_pos;
563 (*ioffptr) += dash - buf;
568 (*ioffptr) += 2 + blen;
571 pp->state = next_state;
572 pp->dash_state = next_dash_state;
594 if (
NULL != *destination)
598 while (
NULL != (spos = strstr (bpos, key)))
600 if ((spos[klen] !=
'=') || ((spos != buf) && (spos[-1] !=
' ')))
606 if (spos[klen + 1] !=
'"')
608 if (
NULL == (endv = strchr (&spos[klen + 2],
'\"')))
610 vlen = endv - spos - klen - 1;
611 *destination = malloc (vlen);
612 if (
NULL == *destination)
614 (*destination)[vlen - 1] =
'\0';
615 memcpy (*destination, &spos[klen + 2], vlen - 1);
638 size_t *ioffptr,
enum PP_State next_state)
640 char *buf = (
char *) &pp[1];
644 while ((newline < pp->buffer_pos) &&
645 (buf[newline] !=
'\r') && (buf[newline] !=
'\n'))
647 if (newline == pp->buffer_size)
652 if (newline == pp->buffer_pos)
658 pp->state = next_state;
662 if (buf[newline] ==
'\r')
666 buf, strlen (
"Content-disposition: ")))
669 "name", &pp->content_name);
671 "filename", &pp->content_filename);
677 buf, &pp->content_transfer_encoding);
679 (*ioffptr) += newline + 1;
703 const char *boundary,
708 char *buf = (
char *) &pp[1];
717 while (newline + 4 < pp->buffer_pos)
719 r = memchr (&buf[newline],
'\r', pp->buffer_pos - newline - 4);
722 newline = pp->buffer_pos - 4;
726 if (0 == memcmp (
"\r\n--", &buf[newline], 4))
730 if (newline + pp->blen + 4 <= pp->buffer_pos)
733 if (0 != memcmp (&buf[newline + 4], boundary, pp->blen))
744 pp->state = next_state;
745 pp->dash_state = next_dash_state;
746 (*ioffptr) += pp->blen + 4;
756 if ((0 == newline) && (pp->buffer_pos == pp->buffer_size))
767 if ( ( (
MHD_YES == pp->must_ikvi) ||
769 (
MHD_NO == pp->ikvi (pp->cls,
772 pp->content_filename,
774 pp->content_transfer_encoding,
775 buf, pp->value_offset, newline)) )
781 pp->value_offset += newline;
782 (*ioffptr) += newline;
796 free (pp->content_name);
797 pp->content_name =
NULL;
801 free (pp->content_type);
802 pp->content_type =
NULL;
804 if ((
NULL != pp->content_filename) &&
807 free (pp->content_filename);
808 pp->content_filename =
NULL;
810 if ((
NULL != pp->content_transfer_encoding) &&
813 free (pp->content_transfer_encoding);
814 pp->content_transfer_encoding =
NULL;
829 const char *post_data,
830 size_t post_data_len)
838 buf = (
char *) &pp[1];
842 while ((poff < post_data_len) ||
843 ((pp->buffer_pos > 0) && (state_changed != 0)))
847 max = pp->buffer_size - pp->buffer_pos;
848 if (max > post_data_len - poff)
849 max = post_data_len - poff;
850 memcpy (&buf[pp->buffer_pos], &post_data[poff], max);
852 pp->buffer_pos += max;
853 if ((max == 0) && (state_changed == 0) && (poff < post_data_len))
885 if ((pp->buffer_pos > 1) && (buf[1] ==
'\n'))
911 pp->state = pp->dash_state;
970 if ((pp->content_type !=
NULL) &&
973 strlen (
"multipart/mixed"))))
975 pp->nested_boundary = strstr (pp->content_type,
"boundary=");
976 if (pp->nested_boundary ==
NULL)
981 pp->nested_boundary =
982 strdup (&pp->nested_boundary[strlen (
"boundary=")]);
983 if (pp->nested_boundary ==
NULL)
991 free (pp->content_type);
992 pp->content_type =
NULL;
993 pp->nlen = strlen (pp->nested_boundary);
999 pp->value_offset = 0;
1019 if (pp->nested_boundary !=
NULL)
1021 free (pp->nested_boundary);
1022 pp->nested_boundary =
NULL;
1028 if (pp->nested_boundary ==
NULL)
1034 pp->nested_boundary,
1049 if (pp->content_name !=
NULL)
1051 if (pp->content_type !=
NULL)
1053 if (pp->content_filename !=
NULL)
1055 if (pp->content_transfer_encoding !=
NULL)
1061 pp->value_offset = 0;
1076 pp->nested_boundary,
1097 memmove (buf, &buf[ioff], pp->buffer_pos - ioff);
1098 pp->buffer_pos -= ioff;
1106 memmove (buf, &buf[ioff], pp->buffer_pos - ioff);
1107 pp->buffer_pos -= ioff;
1109 if (poff < post_data_len)
1133 const char *post_data,
size_t post_data_len)
1135 if (0 == post_data_len)
1177 if ((pp->xbuf_pos > 0) ||
1185 if (pp->nested_boundary !=
NULL)
1186 free (pp->nested_boundary);
void MHD_unescape_plus(char *arg)
_MHD_EXTERN const char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
enum MHD_CONNECTION_STATE state
int(* MHD_PostDataIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
static int find_boundary(struct MHD_PostProcessor *pp, const char *boundary, size_t blen, size_t *ioffptr, enum PP_State next_state, enum PP_State next_dash_state)
_MHD_EXTERN int MHD_destroy_post_processor(struct MHD_PostProcessor *pp)
static int process_multipart_headers(struct MHD_PostProcessor *pp, size_t *ioffptr, enum PP_State next_state)
_MHD_EXTERN struct MHD_PostProcessor * MHD_create_post_processor(struct MHD_Connection *connection, size_t buffer_size, MHD_PostDataIterator iter, void *iter_cls)
internal shared structures
_MHD_EXTERN int MHD_post_process(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
static int post_process_urlencoded(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
static int post_process_multipart(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
static int try_match_header(const char *prefix, char *line, char **suffix)
#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED
static void free_unmarked(struct MHD_PostProcessor *pp)
#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA
static int process_value_to_boundary(struct MHD_PostProcessor *pp, size_t *ioffptr, const char *boundary, size_t blen, enum PP_State next_state, enum PP_State next_dash_state)
MHD_PanicCallback mhd_panic
_MHD_EXTERN size_t MHD_http_unescape(char *val)
static void try_get_value(const char *buf, const char *key, char **destination)