122struct MHD_PostProcessor
144 const char *encoding;
149 const char *boundary;
154 char *nested_boundary;
169 char *content_filename;
174 char *content_transfer_encoding;
199 uint64_t value_offset;
225 bool must_unescape_key;
255struct MHD_PostProcessor *
261 struct MHD_PostProcessor *ret;
262 const char *encoding;
263 const char *boundary;
266 if ( (buffer_size < 256) ||
267 (
NULL == connection) ||
295 boundary = strstr (boundary,
"boundary=");
296 if (
NULL == boundary)
299 blen = strlen (boundary);
301 (blen * 2 + 2 > buffer_size) )
303 if ( (boundary[0] ==
'"') &&
304 (boundary[blen - 1] ==
'"') )
319 ret->connection = connection;
322 ret->encoding = encoding;
323 ret->buffer_size = buffer_size;
326 ret->boundary = boundary;
351 const char *value_start,
352 const char *value_end,
353 const char *last_escape)
364 if (0 != pp->xbuf_pos)
370 if ( (
NULL != last_escape) &&
371 (((
size_t) (value_end - last_escape)) <
sizeof (pp->xbuf)) )
373 pp->xbuf_pos = value_end - last_escape;
376 value_end - last_escape);
377 value_end = last_escape;
379 while ( (value_start != value_end) ||
383 size_t delta = value_end - value_start;
396 value_start += delta;
402 (
'%' == xbuf[xoff - 1]) )
419 else if ( (xoff > 1) &&
420 (
'%' == xbuf[xoff - 2]) )
448 if (pp->must_ikvi || (0 != xoff) )
450 pp->must_ikvi =
false;
451 if (
MHD_NO == pp->ikvi (pp->cls,
453 (
const char *) &pp[1],
465 pp->value_offset += xoff;
490 const char *post_data,
491 size_t post_data_len)
493 char *kbuf = (
char *) &pp[1];
495 const char *start_key =
NULL;
496 const char *end_key =
NULL;
497 const char *start_value =
NULL;
498 const char *end_value =
NULL;
499 const char *last_escape =
NULL;
504 while ( ( (poff < post_data_len) ||
520 switch (post_data[poff])
541 start_key = &post_data[poff];
542 pp->must_ikvi =
true;
554 switch (post_data[poff])
559 end_key = &post_data[poff];
566 end_key = &post_data[poff];
574 end_key = &post_data[poff];
581 start_key = post_data;
588 if (
NULL == start_value)
589 start_value = &post_data[poff];
590 switch (post_data[poff])
598 end_value = &post_data[poff];
601 (start_value != end_value) )
608 pp->value_offset = 0;
617 end_value = &post_data[poff];
619 (start_value != end_value) )
628 last_escape = &post_data[poff];
652 switch (post_data[poff])
666 const size_t key_len = end_key - start_key;
669 if ( (pp->buffer_pos + key_len >= pp->buffer_size) ||
670 (pp->buffer_pos + key_len < pp->buffer_pos) )
677 memcpy (&kbuf[pp->buffer_pos],
680 pp->buffer_pos += key_len;
683 pp->must_unescape_key =
true;
690 if (pp->must_unescape_key)
692 kbuf[pp->buffer_pos] =
'\0';
695 pp->must_unescape_key =
false;
703 pp->value_offset = 0;
728 if (
NULL != start_key)
733 end_key = &post_data[poff];
734 key_len = end_key - start_key;
736 if (pp->buffer_pos + key_len >= pp->buffer_size)
741 memcpy (&kbuf[pp->buffer_pos],
744 pp->buffer_pos += key_len;
745 pp->must_unescape_key =
true;
749 if ( (
NULL != start_value) &&
753 if (pp->must_unescape_key)
755 kbuf[pp->buffer_pos] =
'\0';
758 pp->must_unescape_key =
false;
760 if (
NULL == end_value)
761 end_value = &post_data[poff];
762 if ( (
NULL != last_escape) &&
763 (2 < (end_value - last_escape)) )
769 pp->must_ikvi =
false;
804 *suffix = strdup (&line[prefix_len]);
828 const char *boundary,
834 char *buf = (
char *) &pp[1];
837 if (pp->buffer_pos < 2 + blen)
839 if (pp->buffer_pos == pp->buffer_size)
844 if ( (0 != memcmp (
"--",
847 (0 != memcmp (&buf[2],
863 (*ioffptr) += pp->buffer_pos;
864 else if (dash == buf)
867 (*ioffptr) += dash - buf;
872 (*ioffptr) += 2 + blen;
875 pp->state = next_state;
876 pp->dash_state = next_dash_state;
898 if (
NULL != *destination)
902 while (
NULL != (spos = strstr (bpos, key)))
904 if ( (spos[klen] !=
'=') ||
906 (spos[-1] !=
' ') ) )
912 if (spos[klen + 1] !=
'"')
914 if (
NULL == (endv = strchr (&spos[klen + 2],
917 vlen = endv - spos - klen - 1;
918 *destination = malloc (vlen);
919 if (
NULL == *destination)
921 (*destination)[vlen - 1] =
'\0';
922 memcpy (*destination,
950 char *buf = (
char *) &pp[1];
954 while ( (newline < pp->buffer_pos) &&
955 (buf[newline] !=
'\r') &&
956 (buf[newline] !=
'\n') )
958 if (newline == pp->buffer_size)
963 if (newline == pp->buffer_pos)
969 pp->state = next_state;
973 if (buf[newline] ==
'\r')
985 &pp->content_filename);
996 &pp->content_transfer_encoding);
998 (*ioffptr) += newline + 1;
1022 const char *boundary,
1027 char *buf = (
char *) &pp[1];
1036 while (newline + 4 < pp->buffer_pos)
1038 r = memchr (&buf[newline],
1040 pp->buffer_pos - newline - 4);
1043 newline = pp->buffer_pos - 4;
1047 if (0 == memcmp (
"\r\n--",
1053 if (newline + blen + 4 <= pp->buffer_pos)
1056 if (0 != memcmp (&buf[newline + 4],
1069 pp->state = next_state;
1070 pp->dash_state = next_dash_state;
1071 (*ioffptr) += blen + 4;
1072 buf[newline] =
'\0';
1081 if ( (0 == newline) &&
1082 (pp->buffer_pos == pp->buffer_size) )
1093 if ( ( (pp->must_ikvi) ||
1095 (
MHD_NO == pp->ikvi (pp->cls,
1098 pp->content_filename,
1100 pp->content_transfer_encoding,
1108 pp->must_ikvi =
false;
1109 pp->value_offset += newline;
1110 (*ioffptr) += newline;
1122 if ( (
NULL != pp->content_name) &&
1125 free (pp->content_name);
1126 pp->content_name =
NULL;
1128 if ( (
NULL != pp->content_type) &&
1131 free (pp->content_type);
1132 pp->content_type =
NULL;
1134 if ( (
NULL != pp->content_filename) &&
1137 free (pp->content_filename);
1138 pp->content_filename =
NULL;
1140 if ( (
NULL != pp->content_transfer_encoding) &&
1143 free (pp->content_transfer_encoding);
1144 pp->content_transfer_encoding =
NULL;
1159 const char *post_data,
1160 size_t post_data_len)
1168 buf = (
char *) &pp[1];
1172 while ( (poff < post_data_len) ||
1173 ( (pp->buffer_pos > 0) &&
1174 (0 != state_changed) ) )
1178 max = pp->buffer_size - pp->buffer_pos;
1179 if (max > post_data_len - poff)
1180 max = post_data_len - poff;
1181 memcpy (&buf[pp->buffer_pos],
1185 pp->buffer_pos += max;
1187 (0 == state_changed) &&
1188 (poff < post_data_len) )
1196 switch (pp->skip_rn)
1220 if ( (pp->buffer_pos > 1) &&
1247 pp->state = pp->dash_state;
1296 pp->must_ikvi =
true;
1310 if ( (
NULL != pp->content_type) &&
1315 pp->nested_boundary = strstr (pp->content_type,
1317 if (
NULL == pp->nested_boundary)
1322 pp->nested_boundary =
1324 if (
NULL == pp->nested_boundary)
1332 free (pp->content_type);
1333 pp->content_type =
NULL;
1334 pp->nlen = strlen (pp->nested_boundary);
1340 pp->value_offset = 0;
1360 if (
NULL != pp->nested_boundary)
1362 free (pp->nested_boundary);
1363 pp->nested_boundary =
NULL;
1369 if (
NULL == pp->nested_boundary)
1375 pp->nested_boundary,
1390 if (
NULL != pp->content_name)
1392 if (
NULL != pp->content_type)
1394 if (
NULL != pp->content_filename)
1396 if (
NULL != pp->content_transfer_encoding)
1402 pp->value_offset = 0;
1418 pp->nested_boundary,
1444 pp->buffer_pos - ioff);
1445 pp->buffer_pos -= ioff;
1455 pp->buffer_pos - ioff);
1456 pp->buffer_pos -= ioff;
1458 if (poff < post_data_len)
1469 const char *post_data,
1470 size_t post_data_len)
1472 if (0 == post_data_len)
1514 if ( (pp->xbuf_pos > 0) ||
1522 if (
NULL != pp->nested_boundary)
1523 free (pp->nested_boundary);
#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA
#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED
enum MHD_Result MHD_destroy_post_processor(struct MHD_PostProcessor *pp)
enum MHD_Result MHD_post_process(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
struct MHD_PostProcessor * MHD_create_post_processor(struct MHD_Connection *connection, size_t buffer_size, MHD_PostDataIterator iter, void *iter_cls)
_MHD_EXTERN enum MHD_Result 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_PanicCallback mhd_panic
void * MHD_calloc_(size_t nelem, size_t elsize)
int MHD_str_equal_caseless_n_(const char *const str1, const char *const str2, size_t maxlen)
#define MHD_STATICSTR_LEN_(macro)
MHD internal shared structures.
Header for platform missing functions.
Header for string manipulating helpers.
_MHD_EXTERN size_t MHD_http_unescape(char *val)
enum MHD_Result(* 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 enum MHD_Result post_process_multipart(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
static int try_match_header(const char *prefix, size_t prefix_len, char *line, char **suffix)
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)
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)
@ NE_content_transfer_encoding
static void process_value(struct MHD_PostProcessor *pp, const char *value_start, const char *value_end, const char *last_escape)
@ PP_Nested_PerformMarking
@ PP_PerformCheckMultipart
@ PP_Nested_ProcessEntryHeaders
@ PP_Nested_PerformCleanup
@ PP_ProcessValueToBoundary
@ PP_Nested_ProcessValueToBoundary
static void try_get_value(const char *buf, const char *key, char **destination)
static enum MHD_Result post_process_urlencoded(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
static void free_unmarked(struct MHD_PostProcessor *pp)
static int process_multipart_headers(struct MHD_PostProcessor *pp, size_t *ioffptr, enum PP_State next_state)