118 struct MHD_PostProcessor
141 const char *encoding;
146 const char *boundary;
151 char *nested_boundary;
166 char *content_filename;
171 char *content_transfer_encoding;
197 uint64_t value_offset;
272 struct MHD_PostProcessor *
278 struct MHD_PostProcessor *ret;
279 const char *encoding;
280 const char *boundary;
283 if ( (buffer_size < 256) ||
284 (
NULL == connection) ||
293 if (
NULL == encoding)
307 boundary = strstr (boundary,
"boundary=");
308 if (
NULL == boundary)
310 boundary += strlen (
"boundary=");
311 blen = strlen (boundary);
313 (blen * 2 + 2 > buffer_size) )
315 if ( (boundary[0] ==
'"') &&
316 (boundary[blen - 1] ==
'"') )
328 if (
NULL == (ret = malloc (
sizeof (
struct MHD_PostProcessor) + buffer_size + 1)))
332 sizeof (
struct MHD_PostProcessor) + buffer_size + 1);
333 ret->connection = connection;
336 ret->encoding = encoding;
337 ret->buffer_size = buffer_size;
340 ret->boundary = boundary;
356 const char *post_data,
357 size_t post_data_len)
364 int end_of_value_found;
368 buf = (
char *) &pp[1];
370 while (poff < post_data_len)
382 while ((equals + poff < post_data_len) &&
383 (post_data[equals + poff] !=
'='))
385 if (equals + pp->buffer_pos > pp->buffer_size)
390 memcpy (&buf[pp->buffer_pos], &post_data[poff], equals);
391 pp->buffer_pos += equals;
392 if (equals + poff == post_data_len)
394 buf[pp->buffer_pos] =
'\0';
400 pp->value_offset = 0;
404 memcpy (xbuf, pp->xbuf, pp->xbuf_pos);
410 while ((amper + poff < post_data_len) &&
412 (post_data[amper + poff] !=
'&') &&
413 (post_data[amper + poff] !=
'\n') &&
414 (post_data[amper + poff] !=
'\r'))
416 end_of_value_found = ((amper + poff < post_data_len) &&
417 ((post_data[amper + poff] ==
'&') ||
418 (post_data[amper + poff] ==
'\n') ||
419 (post_data[amper + poff] ==
'\r')));
427 memcpy (&xbuf[xoff], &post_data[poff], delta);
436 (
'%' == xbuf[delta - 1]))
438 else if ((delta > 1) &&
439 (
'%' == xbuf[delta - 2]))
449 pp->xbuf_pos = xoff - delta;
457 (poff == post_data_len))
466 if (
MHD_NO == pp->ikvi (pp->cls,
468 (
const char *) &pp[1],
479 pp->value_offset += xoff;
482 if (end_of_value_found)
485 if ( (
'\n' == post_data[poff]) ||
486 (
'\r' == post_data[poff]) )
490 else if (
'&' == post_data[poff])
498 if ( (
'\n' == post_data[poff]) ||
499 (
'\r' == post_data[poff]) )
540 *suffix = strdup (&line[strlen (prefix)]);
564 const char *boundary,
570 char *buf = (
char *) &pp[1];
573 if (pp->buffer_pos < 2 + blen)
575 if (pp->buffer_pos == pp->buffer_size)
580 if ( (0 != memcmp (
"--",
583 (0 != memcmp (&buf[2],
599 (*ioffptr) += pp->buffer_pos;
604 (*ioffptr) += dash - buf;
609 (*ioffptr) += 2 + blen;
612 pp->state = next_state;
613 pp->dash_state = next_dash_state;
635 if (
NULL != *destination)
639 while (
NULL != (spos = strstr (bpos, key)))
641 if ( (spos[klen] !=
'=') ||
643 (spos[-1] !=
' ') ) )
649 if (spos[klen + 1] !=
'"')
651 if (
NULL == (endv = strchr (&spos[klen + 2],
654 vlen = endv - spos - klen - 1;
655 *destination = malloc (vlen);
656 if (
NULL == *destination)
658 (*destination)[vlen - 1] =
'\0';
659 memcpy (*destination,
687 char *buf = (
char *) &pp[1];
691 while ( (newline < pp->buffer_pos) &&
692 (buf[newline] !=
'\r') &&
693 (buf[newline] !=
'\n') )
695 if (newline == pp->buffer_size)
700 if (newline == pp->buffer_pos)
706 pp->state = next_state;
710 if (buf[newline] ==
'\r')
715 strlen (
"Content-disposition: ")))
722 &pp->content_filename);
731 &pp->content_transfer_encoding);
733 (*ioffptr) += newline + 1;
757 const char *boundary,
762 char *buf = (
char *) &pp[1];
771 while (newline + 4 < pp->buffer_pos)
773 r = memchr (&buf[newline],
775 pp->buffer_pos - newline - 4);
778 newline = pp->buffer_pos - 4;
782 if (0 == memcmp (
"\r\n--",
788 if (newline + pp->blen + 4 <= pp->buffer_pos)
791 if (0 != memcmp (&buf[newline + 4],
804 pp->state = next_state;
805 pp->dash_state = next_dash_state;
806 (*ioffptr) += pp->blen + 4;
816 if ( (0 == newline) &&
817 (pp->buffer_pos == pp->buffer_size) )
828 if ( ( (
MHD_YES == pp->must_ikvi) ||
830 (
MHD_NO == pp->ikvi (pp->cls,
833 pp->content_filename,
835 pp->content_transfer_encoding,
844 pp->value_offset += newline;
845 (*ioffptr) += newline;
857 if ( (
NULL != pp->content_name) &&
860 free (pp->content_name);
861 pp->content_name =
NULL;
863 if ( (
NULL != pp->content_type) &&
866 free (pp->content_type);
867 pp->content_type =
NULL;
869 if ( (
NULL != pp->content_filename) &&
872 free (pp->content_filename);
873 pp->content_filename =
NULL;
875 if ( (
NULL != pp->content_transfer_encoding) &&
878 free (pp->content_transfer_encoding);
879 pp->content_transfer_encoding =
NULL;
894 const char *post_data,
895 size_t post_data_len)
903 buf = (
char *) &pp[1];
907 while ( (poff < post_data_len) ||
908 ( (pp->buffer_pos > 0) &&
909 (0 != state_changed) ) )
913 max = pp->buffer_size - pp->buffer_pos;
914 if (max > post_data_len - poff)
915 max = post_data_len - poff;
916 memcpy (&buf[pp->buffer_pos],
920 pp->buffer_pos += max;
922 (0 == state_changed) &&
923 (poff < post_data_len) )
955 if ( (pp->buffer_pos > 1) &&
982 pp->state = pp->dash_state;
1045 if ( (
NULL != pp->content_type) &&
1048 strlen (
"multipart/mixed"))))
1050 pp->nested_boundary = strstr (pp->content_type,
1052 if (
NULL == pp->nested_boundary)
1057 pp->nested_boundary =
1058 strdup (&pp->nested_boundary[strlen (
"boundary=")]);
1059 if (
NULL == pp->nested_boundary)
1067 free (pp->content_type);
1068 pp->content_type =
NULL;
1069 pp->nlen = strlen (pp->nested_boundary);
1075 pp->value_offset = 0;
1095 if (
NULL != pp->nested_boundary)
1097 free (pp->nested_boundary);
1098 pp->nested_boundary =
NULL;
1104 if (
NULL == pp->nested_boundary)
1110 pp->nested_boundary,
1125 if (
NULL != pp->content_name)
1127 if (
NULL != pp->content_type)
1129 if (
NULL != pp->content_filename)
1131 if (
NULL != pp->content_transfer_encoding)
1137 pp->value_offset = 0;
1153 pp->nested_boundary,
1179 pp->buffer_pos - ioff);
1180 pp->buffer_pos -= ioff;
1190 pp->buffer_pos - ioff);
1191 pp->buffer_pos -= ioff;
1193 if (poff < post_data_len)
1217 const char *post_data,
1218 size_t post_data_len)
1220 if (0 == post_data_len)
1270 if ( (pp->xbuf_pos > 0) ||
1278 if (
NULL != pp->nested_boundary)
1279 free (pp->nested_boundary);
_MHD_EXTERN const char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
void MHD_unescape_plus(char *arg)
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)
int MHD_str_equal_caseless_n_(const char *const str1, const char *const str2, size_t maxlen)
_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 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)
internal shared structures
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
Header for string manipulating helpers.
static void free_unmarked(struct MHD_PostProcessor *pp)
MHD_PanicCallback mhd_panic
#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 size_t MHD_http_unescape(char *val)
static void try_get_value(const char *buf, const char *key, char **destination)