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;
254 struct MHD_PostProcessor *
260 struct MHD_PostProcessor *ret;
261 const char *encoding;
262 const char *boundary;
265 if ( (buffer_size < 256) ||
266 (
NULL == connection) ||
294 boundary = strstr (boundary,
"boundary=");
295 if (
NULL == boundary)
298 blen = strlen (boundary);
300 (blen * 2 + 2 > buffer_size) )
302 if ( (boundary[0] ==
'"') &&
303 (boundary[blen - 1] ==
'"') )
318 ret->connection = connection;
321 ret->encoding = encoding;
322 ret->buffer_size = buffer_size;
325 ret->boundary = boundary;
350 const char *value_start,
351 const char *value_end,
352 const char *last_escape)
364 if ( (
NULL != last_escape) &&
365 (((
size_t) (value_end - last_escape)) <
sizeof (pp->xbuf)) )
367 pp->xbuf_pos = value_end - last_escape;
370 value_end - last_escape);
371 value_end = last_escape;
373 while ( (value_start != value_end) ||
377 size_t delta = value_end - value_start;
388 value_start += delta;
393 (
'%' == xbuf[xoff - 1]) )
410 else if ( (xoff > 1) &&
411 (
'%' == xbuf[xoff - 2]) )
436 if (pp->must_ikvi || (0 != xoff) )
438 pp->must_ikvi =
false;
439 if (
MHD_NO == pp->ikvi (pp->cls,
441 (
const char *) &pp[1],
453 pp->value_offset += xoff;
475 const char *post_data,
476 size_t post_data_len)
478 char *kbuf = (
char *) &pp[1];
480 const char *start_key =
NULL;
481 const char *end_key =
NULL;
482 const char *start_value =
NULL;
483 const char *end_value =
NULL;
484 const char *last_escape =
NULL;
489 while ( ( (poff < post_data_len) ||
501 if (
NULL == start_key)
502 start_key = &post_data[poff];
503 pp->must_ikvi =
true;
504 switch (post_data[poff])
508 end_key = &post_data[poff];
514 end_key = &post_data[poff];
523 end_key = &post_data[poff];
534 if (
NULL == start_value)
535 start_value = &post_data[poff];
536 switch (post_data[poff])
544 end_value = &post_data[poff];
547 (start_value != end_value) )
554 pp->value_offset = 0;
563 end_value = &post_data[poff];
571 last_escape = &post_data[poff];
595 switch (post_data[poff])
606 if ( (pp->buffer_pos + (end_key - start_key) >=
608 (pp->buffer_pos + (end_key - start_key) <
616 if (
NULL != start_key)
618 memcpy (&kbuf[pp->buffer_pos],
620 end_key - start_key);
621 pp->buffer_pos += end_key - start_key;
624 pp->must_unescape_key =
true;
626 if (pp->must_unescape_key)
628 kbuf[pp->buffer_pos] =
'\0';
631 pp->must_unescape_key =
false;
639 pp->value_offset = 0;
654 if (
NULL != start_key)
657 end_key = &post_data[poff];
658 if (pp->buffer_pos + (end_key - start_key) >= pp->buffer_size)
663 memcpy (&kbuf[pp->buffer_pos],
665 end_key - start_key);
666 pp->buffer_pos += end_key - start_key;
667 pp->must_unescape_key =
true;
671 if ( (
NULL != start_value) &&
675 if (pp->must_unescape_key)
677 kbuf[pp->buffer_pos] =
'\0';
680 pp->must_unescape_key =
false;
682 if (
NULL == end_value)
683 end_value = &post_data[poff];
688 pp->must_ikvi =
false;
723 *suffix = strdup (&line[prefix_len]);
747 const char *boundary,
753 char *buf = (
char *) &pp[1];
756 if (pp->buffer_pos < 2 + blen)
758 if (pp->buffer_pos == pp->buffer_size)
763 if ( (0 != memcmp (
"--",
766 (0 != memcmp (&buf[2],
782 (*ioffptr) += pp->buffer_pos;
783 else if (dash == buf)
786 (*ioffptr) += dash - buf;
791 (*ioffptr) += 2 + blen;
794 pp->state = next_state;
795 pp->dash_state = next_dash_state;
817 if (
NULL != *destination)
821 while (
NULL != (spos = strstr (bpos, key)))
823 if ( (spos[klen] !=
'=') ||
825 (spos[-1] !=
' ') ) )
831 if (spos[klen + 1] !=
'"')
833 if (
NULL == (endv = strchr (&spos[klen + 2],
836 vlen = endv - spos - klen - 1;
837 *destination = malloc (vlen);
838 if (
NULL == *destination)
840 (*destination)[vlen - 1] =
'\0';
841 memcpy (*destination,
869 char *buf = (
char *) &pp[1];
873 while ( (newline < pp->buffer_pos) &&
874 (buf[newline] !=
'\r') &&
875 (buf[newline] !=
'\n') )
877 if (newline == pp->buffer_size)
882 if (newline == pp->buffer_pos)
888 pp->state = next_state;
892 if (buf[newline] ==
'\r')
904 &pp->content_filename);
915 &pp->content_transfer_encoding);
917 (*ioffptr) += newline + 1;
941 const char *boundary,
946 char *buf = (
char *) &pp[1];
955 while (newline + 4 < pp->buffer_pos)
957 r = memchr (&buf[newline],
959 pp->buffer_pos - newline - 4);
962 newline = pp->buffer_pos - 4;
966 if (0 == memcmp (
"\r\n--",
972 if (newline + blen + 4 <= pp->buffer_pos)
975 if (0 != memcmp (&buf[newline + 4],
988 pp->state = next_state;
989 pp->dash_state = next_dash_state;
990 (*ioffptr) += blen + 4;
1000 if ( (0 == newline) &&
1001 (pp->buffer_pos == pp->buffer_size) )
1012 if ( ( (pp->must_ikvi) ||
1014 (
MHD_NO == pp->ikvi (pp->cls,
1017 pp->content_filename,
1019 pp->content_transfer_encoding,
1027 pp->must_ikvi =
false;
1028 pp->value_offset += newline;
1029 (*ioffptr) += newline;
1041 if ( (
NULL != pp->content_name) &&
1044 free (pp->content_name);
1045 pp->content_name =
NULL;
1047 if ( (
NULL != pp->content_type) &&
1050 free (pp->content_type);
1051 pp->content_type =
NULL;
1053 if ( (
NULL != pp->content_filename) &&
1056 free (pp->content_filename);
1057 pp->content_filename =
NULL;
1059 if ( (
NULL != pp->content_transfer_encoding) &&
1062 free (pp->content_transfer_encoding);
1063 pp->content_transfer_encoding =
NULL;
1078 const char *post_data,
1079 size_t post_data_len)
1087 buf = (
char *) &pp[1];
1091 while ( (poff < post_data_len) ||
1092 ( (pp->buffer_pos > 0) &&
1093 (0 != state_changed) ) )
1097 max = pp->buffer_size - pp->buffer_pos;
1098 if (max > post_data_len - poff)
1099 max = post_data_len - poff;
1100 memcpy (&buf[pp->buffer_pos],
1104 pp->buffer_pos += max;
1106 (0 == state_changed) &&
1107 (poff < post_data_len) )
1115 switch (pp->skip_rn)
1139 if ( (pp->buffer_pos > 1) &&
1166 pp->state = pp->dash_state;
1215 pp->must_ikvi =
true;
1229 if ( (
NULL != pp->content_type) &&
1234 pp->nested_boundary = strstr (pp->content_type,
1236 if (
NULL == pp->nested_boundary)
1241 pp->nested_boundary =
1243 if (
NULL == pp->nested_boundary)
1251 free (pp->content_type);
1252 pp->content_type =
NULL;
1253 pp->nlen = strlen (pp->nested_boundary);
1259 pp->value_offset = 0;
1279 if (
NULL != pp->nested_boundary)
1281 free (pp->nested_boundary);
1282 pp->nested_boundary =
NULL;
1288 if (
NULL == pp->nested_boundary)
1294 pp->nested_boundary,
1309 if (
NULL != pp->content_name)
1311 if (
NULL != pp->content_type)
1313 if (
NULL != pp->content_filename)
1315 if (
NULL != pp->content_transfer_encoding)
1321 pp->value_offset = 0;
1337 pp->nested_boundary,
1363 pp->buffer_pos - ioff);
1364 pp->buffer_pos -= ioff;
1374 pp->buffer_pos - ioff);
1375 pp->buffer_pos -= ioff;
1377 if (poff < post_data_len)
1388 const char *post_data,
1389 size_t post_data_len)
1391 if (0 == post_data_len)
1433 if ( (pp->xbuf_pos > 0) ||
1441 if (
NULL != pp->nested_boundary)
1442 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)
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