121 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;
375 const char *value_start,
376 const char *value_end,
377 const char *last_escape)
389 if (
NULL != last_escape)
391 if (((
size_t) (value_end - last_escape)) <
sizeof (pp->xbuf))
393 pp->xbuf_pos = value_end - last_escape;
396 value_end - last_escape);
397 value_end = last_escape;
400 while ( (value_start != value_end) ||
404 size_t delta = value_end - value_start;
415 value_start += delta;
420 (
'%' == xbuf[xoff - 1]) )
437 else if ( (xoff > 1) &&
438 (
'%' == xbuf[xoff - 2]) )
463 if ( (pp->must_ikvi || (0 != xoff)) )
465 pp->must_ikvi =
false;
466 if (
MHD_NO == pp->ikvi (pp->cls,
468 (
const char *) &pp[1],
480 pp->value_offset += xoff;
502 const char *post_data,
503 size_t post_data_len)
505 char *kbuf = (
char *) &pp[1];
507 const char *start_key =
NULL;
508 const char *end_key =
NULL;
509 const char *start_value =
NULL;
510 const char *end_value =
NULL;
511 const char *last_escape =
NULL;
516 while ( ( (poff < post_data_len) ||
528 if (
NULL == start_key)
529 start_key = &post_data[poff];
530 pp->must_ikvi =
true;
531 switch (post_data[poff])
535 end_key = &post_data[poff];
541 end_key = &post_data[poff];
550 end_key = &post_data[poff];
561 if (
NULL == start_value)
562 start_value = &post_data[poff];
563 switch (post_data[poff])
571 end_value = &post_data[poff];
574 (start_value != end_value) )
581 pp->value_offset = 0;
590 end_value = &post_data[poff];
598 last_escape = &post_data[poff];
622 switch (post_data[poff])
633 if ( (pp->buffer_pos + (end_key - start_key) >=
635 (pp->buffer_pos + (end_key - start_key) <
643 if (
NULL != start_key)
645 memcpy (&kbuf[pp->buffer_pos],
647 end_key - start_key);
648 pp->buffer_pos += end_key - start_key;
651 pp->must_unescape_key =
true;
653 if (pp->must_unescape_key)
655 kbuf[pp->buffer_pos] =
'\0';
658 pp->must_unescape_key =
false;
664 pp->value_offset = 0;
679 if (
NULL != start_key)
682 end_key = &post_data[poff];
683 if (pp->buffer_pos + (end_key - start_key) >= pp->buffer_size)
688 memcpy (&kbuf[pp->buffer_pos],
690 end_key - start_key);
691 pp->buffer_pos += end_key - start_key;
692 pp->must_unescape_key =
true;
696 if ( (
NULL != start_value) &&
700 if (pp->must_unescape_key)
702 kbuf[pp->buffer_pos] =
'\0';
705 pp->must_unescape_key =
false;
707 if (
NULL == end_value)
708 end_value = &post_data[poff];
713 pp->must_ikvi =
false;
748 *suffix = strdup (&line[prefix_len]);
772 const char *boundary,
778 char *buf = (
char *) &pp[1];
781 if (pp->buffer_pos < 2 + blen)
783 if (pp->buffer_pos == pp->buffer_size)
788 if ( (0 != memcmp (
"--",
791 (0 != memcmp (&buf[2],
807 (*ioffptr) += pp->buffer_pos;
808 else if (dash == buf)
811 (*ioffptr) += dash - buf;
816 (*ioffptr) += 2 + blen;
819 pp->state = next_state;
820 pp->dash_state = next_dash_state;
842 if (
NULL != *destination)
846 while (
NULL != (spos = strstr (bpos, key)))
848 if ( (spos[klen] !=
'=') ||
850 (spos[-1] !=
' ') ) )
856 if (spos[klen + 1] !=
'"')
858 if (
NULL == (endv = strchr (&spos[klen + 2],
861 vlen = endv - spos - klen - 1;
862 *destination = malloc (vlen);
863 if (
NULL == *destination)
865 (*destination)[vlen - 1] =
'\0';
866 memcpy (*destination,
894 char *buf = (
char *) &pp[1];
898 while ( (newline < pp->buffer_pos) &&
899 (buf[newline] !=
'\r') &&
900 (buf[newline] !=
'\n') )
902 if (newline == pp->buffer_size)
907 if (newline == pp->buffer_pos)
913 pp->state = next_state;
917 if (buf[newline] ==
'\r')
929 &pp->content_filename);
940 &pp->content_transfer_encoding);
942 (*ioffptr) += newline + 1;
966 const char *boundary,
971 char *buf = (
char *) &pp[1];
980 while (newline + 4 < pp->buffer_pos)
982 r = memchr (&buf[newline],
984 pp->buffer_pos - newline - 4);
987 newline = pp->buffer_pos - 4;
991 if (0 == memcmp (
"\r\n--",
997 if (newline + blen + 4 <= pp->buffer_pos)
1000 if (0 != memcmp (&buf[newline + 4],
1013 pp->state = next_state;
1014 pp->dash_state = next_dash_state;
1015 (*ioffptr) += blen + 4;
1016 buf[newline] =
'\0';
1025 if ( (0 == newline) &&
1026 (pp->buffer_pos == pp->buffer_size) )
1037 if ( ( (pp->must_ikvi) ||
1039 (
MHD_NO == pp->ikvi (pp->cls,
1042 pp->content_filename,
1044 pp->content_transfer_encoding,
1052 pp->must_ikvi =
false;
1053 pp->value_offset += newline;
1054 (*ioffptr) += newline;
1066 if ( (
NULL != pp->content_name) &&
1069 free (pp->content_name);
1070 pp->content_name =
NULL;
1072 if ( (
NULL != pp->content_type) &&
1075 free (pp->content_type);
1076 pp->content_type =
NULL;
1078 if ( (
NULL != pp->content_filename) &&
1081 free (pp->content_filename);
1082 pp->content_filename =
NULL;
1084 if ( (
NULL != pp->content_transfer_encoding) &&
1087 free (pp->content_transfer_encoding);
1088 pp->content_transfer_encoding =
NULL;
1103 const char *post_data,
1104 size_t post_data_len)
1112 buf = (
char *) &pp[1];
1116 while ( (poff < post_data_len) ||
1117 ( (pp->buffer_pos > 0) &&
1118 (0 != state_changed) ) )
1122 max = pp->buffer_size - pp->buffer_pos;
1123 if (max > post_data_len - poff)
1124 max = post_data_len - poff;
1125 memcpy (&buf[pp->buffer_pos],
1129 pp->buffer_pos += max;
1131 (0 == state_changed) &&
1132 (poff < post_data_len) )
1140 switch (pp->skip_rn)
1164 if ( (pp->buffer_pos > 1) &&
1191 pp->state = pp->dash_state;
1240 pp->must_ikvi =
true;
1254 if ( (
NULL != pp->content_type) &&
1259 pp->nested_boundary = strstr (pp->content_type,
1261 if (
NULL == pp->nested_boundary)
1266 pp->nested_boundary =
1268 if (
NULL == pp->nested_boundary)
1276 free (pp->content_type);
1277 pp->content_type =
NULL;
1278 pp->nlen = strlen (pp->nested_boundary);
1284 pp->value_offset = 0;
1304 if (
NULL != pp->nested_boundary)
1306 free (pp->nested_boundary);
1307 pp->nested_boundary =
NULL;
1313 if (
NULL == pp->nested_boundary)
1319 pp->nested_boundary,
1334 if (
NULL != pp->content_name)
1336 if (
NULL != pp->content_type)
1338 if (
NULL != pp->content_filename)
1340 if (
NULL != pp->content_transfer_encoding)
1346 pp->value_offset = 0;
1362 pp->nested_boundary,
1388 pp->buffer_pos - ioff);
1389 pp->buffer_pos -= ioff;
1399 pp->buffer_pos - ioff);
1400 pp->buffer_pos -= ioff;
1402 if (poff < post_data_len)
1426 const char *post_data,
1427 size_t post_data_len)
1429 if (0 == post_data_len)
1481 if ( (pp->xbuf_pos > 0) ||
1489 if (
NULL != pp->nested_boundary)
1490 free (pp->nested_boundary);
#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA
#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED
_MHD_EXTERN enum MHD_Result MHD_post_process(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
_MHD_EXTERN 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_destroy_post_processor(struct MHD_PostProcessor *pp)
_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)
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 int post_process_urlencoded(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 int post_process_multipart(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
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 void free_unmarked(struct MHD_PostProcessor *pp)
static int process_multipart_headers(struct MHD_PostProcessor *pp, size_t *ioffptr, enum PP_State next_state)
enum MHD_CONNECTION_STATE state