120 struct MHD_PostProcessor
143 const char *encoding;
148 const char *boundary;
153 char *nested_boundary;
168 char *content_filename;
173 char *content_transfer_encoding;
198 uint64_t value_offset;
224 bool must_unescape_key;
279 struct MHD_PostProcessor *
285 struct MHD_PostProcessor *ret;
286 const char *encoding;
287 const char *boundary;
290 if ( (buffer_size < 256) ||
291 (
NULL == connection) ||
319 boundary = strstr (boundary,
"boundary=");
320 if (
NULL == boundary)
323 blen = strlen (boundary);
325 (blen * 2 + 2 > buffer_size) )
327 if ( (boundary[0] ==
'"') &&
328 (boundary[blen - 1] ==
'"') )
343 ret->connection = connection;
346 ret->encoding = encoding;
347 ret->buffer_size = buffer_size;
350 ret->boundary = boundary;
379 const char *value_start,
380 const char *value_end,
381 const char *last_escape)
392 if (
NULL != last_escape)
394 if (value_end - last_escape <
sizeof (pp->xbuf))
396 pp->xbuf_pos = value_end - last_escape;
399 value_end - last_escape);
400 value_end = last_escape;
403 while ( (value_start != value_end) ||
407 size_t delta = value_end - value_start;
420 if ((xoff + delta > 0) &&
421 (
'%' == xbuf[xoff + delta - 1]))
423 else if ((xoff + delta > 1) &&
424 (
'%' == xbuf[xoff + delta - 2]))
428 value_start += delta;
435 pp->must_ikvi =
false;
436 if (
MHD_NO == pp->ikvi (pp->cls,
438 (
const char *) &pp[1],
449 pp->value_offset += xoff;
465 const char *post_data,
466 size_t post_data_len)
468 char *kbuf = (
char *) &pp[1];
470 const char *start_key =
NULL;
471 const char *end_key =
NULL;
472 const char *start_value =
NULL;
473 const char *end_value =
NULL;
474 const char *last_escape =
NULL;
477 while ( ( (poff < post_data_len) ||
488 if (
NULL == start_key)
489 start_key = &post_data[poff];
490 pp->must_ikvi =
true;
491 switch (post_data[poff])
495 end_key = &post_data[poff];
501 end_key = &post_data[poff];
510 end_key = &post_data[poff];
521 if (
NULL == start_value)
522 start_value = &post_data[poff];
523 switch (post_data[poff]) {
530 end_value = &post_data[poff];
532 if ( pp->must_ikvi ||
533 (start_value != end_value) )
540 pp->value_offset = 0;
547 end_value = &post_data[poff];
555 last_escape = &post_data[poff];
579 switch (post_data[poff]) {
589 if ( (pp->buffer_pos + (end_key - start_key) >
591 (pp->buffer_pos + (end_key - start_key) <
599 if (
NULL != start_key)
601 memcpy (&kbuf[pp->buffer_pos],
603 end_key - start_key);
604 pp->buffer_pos += end_key - start_key;
607 pp->must_unescape_key =
true;
609 if (pp->must_unescape_key)
611 kbuf[pp->buffer_pos] =
'\0';
614 pp->must_unescape_key =
false;
620 pp->value_offset = 0;
635 if (
NULL != start_key)
638 end_key = &post_data[poff];
639 memcpy (&kbuf[pp->buffer_pos],
641 end_key - start_key);
642 pp->buffer_pos += end_key - start_key;
643 pp->must_unescape_key =
true;
647 if ( (
NULL != start_value) &&
651 if (pp->must_unescape_key)
653 kbuf[pp->buffer_pos] =
'\0';
656 pp->must_unescape_key =
false;
658 if (
NULL == end_value)
659 end_value = &post_data[poff];
664 pp->must_ikvi =
false;
694 *suffix = strdup (&line[prefix_len]);
718 const char *boundary,
724 char *buf = (
char *) &pp[1];
727 if (pp->buffer_pos < 2 + blen)
729 if (pp->buffer_pos == pp->buffer_size)
734 if ( (0 != memcmp (
"--",
737 (0 != memcmp (&buf[2],
753 (*ioffptr) += pp->buffer_pos;
754 else if (dash == buf)
757 (*ioffptr) += dash - buf;
762 (*ioffptr) += 2 + blen;
765 pp->state = next_state;
766 pp->dash_state = next_dash_state;
788 if (
NULL != *destination)
792 while (
NULL != (spos = strstr (bpos, key)))
794 if ( (spos[klen] !=
'=') ||
796 (spos[-1] !=
' ') ) )
802 if (spos[klen + 1] !=
'"')
804 if (
NULL == (endv = strchr (&spos[klen + 2],
807 vlen = endv - spos - klen - 1;
808 *destination = malloc (vlen);
809 if (
NULL == *destination)
811 (*destination)[vlen - 1] =
'\0';
812 memcpy (*destination,
840 char *buf = (
char *) &pp[1];
844 while ( (newline < pp->buffer_pos) &&
845 (buf[newline] !=
'\r') &&
846 (buf[newline] !=
'\n') )
848 if (newline == pp->buffer_size)
853 if (newline == pp->buffer_pos)
859 pp->state = next_state;
863 if (buf[newline] ==
'\r')
875 &pp->content_filename);
886 &pp->content_transfer_encoding);
888 (*ioffptr) += newline + 1;
912 const char *boundary,
917 char *buf = (
char *) &pp[1];
926 while (newline + 4 < pp->buffer_pos)
928 r = memchr (&buf[newline],
930 pp->buffer_pos - newline - 4);
933 newline = pp->buffer_pos - 4;
937 if (0 == memcmp (
"\r\n--",
943 if (newline + blen + 4 <= pp->buffer_pos)
946 if (0 != memcmp (&buf[newline + 4],
959 pp->state = next_state;
960 pp->dash_state = next_dash_state;
961 (*ioffptr) += blen + 4;
971 if ( (0 == newline) &&
972 (pp->buffer_pos == pp->buffer_size) )
983 if ( ( (pp->must_ikvi) ||
985 (
MHD_NO == pp->ikvi (pp->cls,
988 pp->content_filename,
990 pp->content_transfer_encoding,
998 pp->must_ikvi =
false;
999 pp->value_offset += newline;
1000 (*ioffptr) += newline;
1012 if ( (
NULL != pp->content_name) &&
1015 free (pp->content_name);
1016 pp->content_name =
NULL;
1018 if ( (
NULL != pp->content_type) &&
1021 free (pp->content_type);
1022 pp->content_type =
NULL;
1024 if ( (
NULL != pp->content_filename) &&
1027 free (pp->content_filename);
1028 pp->content_filename =
NULL;
1030 if ( (
NULL != pp->content_transfer_encoding) &&
1033 free (pp->content_transfer_encoding);
1034 pp->content_transfer_encoding =
NULL;
1049 const char *post_data,
1050 size_t post_data_len)
1058 buf = (
char *) &pp[1];
1062 while ( (poff < post_data_len) ||
1063 ( (pp->buffer_pos > 0) &&
1064 (0 != state_changed) ) )
1068 max = pp->buffer_size - pp->buffer_pos;
1069 if (max > post_data_len - poff)
1070 max = post_data_len - poff;
1071 memcpy (&buf[pp->buffer_pos],
1075 pp->buffer_pos += max;
1077 (0 == state_changed) &&
1078 (poff < post_data_len) )
1086 switch (pp->skip_rn)
1110 if ( (pp->buffer_pos > 1) &&
1137 pp->state = pp->dash_state;
1185 pp->must_ikvi =
true;
1199 if ( (
NULL != pp->content_type) &&
1204 pp->nested_boundary = strstr (pp->content_type,
1206 if (
NULL == pp->nested_boundary)
1211 pp->nested_boundary =
1213 if (
NULL == pp->nested_boundary)
1221 free (pp->content_type);
1222 pp->content_type =
NULL;
1223 pp->nlen = strlen (pp->nested_boundary);
1229 pp->value_offset = 0;
1249 if (
NULL != pp->nested_boundary)
1251 free (pp->nested_boundary);
1252 pp->nested_boundary =
NULL;
1258 if (
NULL == pp->nested_boundary)
1264 pp->nested_boundary,
1279 if (
NULL != pp->content_name)
1281 if (
NULL != pp->content_type)
1283 if (
NULL != pp->content_filename)
1285 if (
NULL != pp->content_transfer_encoding)
1291 pp->value_offset = 0;
1307 pp->nested_boundary,
1333 pp->buffer_pos - ioff);
1334 pp->buffer_pos -= ioff;
1344 pp->buffer_pos - ioff);
1345 pp->buffer_pos -= ioff;
1347 if (poff < post_data_len)
1371 const char *post_data,
1372 size_t post_data_len)
1374 if (0 == post_data_len)
1426 if ( (pp->xbuf_pos > 0) ||
1433 if (
NULL != pp->nested_boundary)
1434 free (pp->nested_boundary);
int MHD_str_equal_caseless_n_(const char *const str1, const char *const str2, size_t maxlen)
Header for platform missing functions.
enum MHD_CONNECTION_STATE state
MHD_PanicCallback mhd_panic
void * MHD_calloc_(size_t nelem, size_t elsize)
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)
static int try_match_header(const char *prefix, size_t prefix_len, char *line, char **suffix)
internal shared structures
Header for string manipulating helpers.
_MHD_EXTERN int MHD_post_process(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
#define MHD_STATICSTR_LEN_(macro)
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)
#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED
static void free_unmarked(struct MHD_PostProcessor *pp)
static void process_value(struct MHD_PostProcessor *pp, const char *value_start, const char *value_end, const char *last_escape)
#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_EXTERN int MHD_lookup_connection_value_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, size_t key_size, const char **value_ptr, size_t *value_size_ptr)
void MHD_unescape_plus(char *arg)
_MHD_EXTERN size_t MHD_http_unescape(char *val)
static void try_get_value(const char *buf, const char *key, char **destination)