1/*
2     This file is part of libmicrohttpd
3     Copyright (C) 2007-2013 Daniel Pittman and Christian Grothoff
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18*/
19
20/**
21 * @file postprocessor.c
22 * @brief  Methods for parsing POST data
23 * @author Christian Grothoff
24 */
25
26#include "internal.h"
27
28/**
29 * Size of on-stack buffer that we use for un-escaping of the value.
30 * We use a pretty small value to be nice to the stack on embedded
31 * systems.
32 */
33#define XBUF_SIZE 512
34
35/**
36 * States in the PP parser's state machine.
37 */
38enum PP_State
39{
40  /* general states */
41  PP_Error,
42  PP_Done,
43  PP_Init,
44  PP_NextBoundary,
45
46  /* url encoding-states */
47  PP_ProcessValue,
48  PP_ExpectNewLine,
49
50  /* post encoding-states  */
51  PP_ProcessEntryHeaders,
52  PP_PerformCheckMultipart,
53  PP_ProcessValueToBoundary,
54  PP_PerformCleanup,
55
56  /* nested post-encoding states */
57  PP_Nested_Init,
58  PP_Nested_PerformMarking,
59  PP_Nested_ProcessEntryHeaders,
60  PP_Nested_ProcessValueToBoundary,
61  PP_Nested_PerformCleanup
62
63};
64
65
66enum RN_State
67{
68  /**
69   * No RN-preprocessing in this state.
70   */
71  RN_Inactive = 0,
72
73  /**
74   * If the next character is CR, skip it.  Otherwise,
75   * just go inactive.
76   */
77  RN_OptN = 1,
78
79  /**
80   * Expect LFCR (and only LFCR).  As always, we also
81   * expect only LF or only CR.
82   */
83  RN_Full = 2,
84
85  /**
86   * Expect either LFCR or '--'LFCR.  If '--'LFCR, transition into dash-state
87   * for the main state machine
88   */
89  RN_Dash = 3,
90
91  /**
92   * Got a single dash, expect second dash.
93   */
94  RN_Dash2 = 4
95};
96
97
98/**
99 * Bits for the globally known fields that
100 * should not be deleted when we exit the
101 * nested state.
102 */
103enum NE_State
104{
105  NE_none = 0,
106  NE_content_name = 1,
107  NE_content_type = 2,
108  NE_content_filename = 4,
109  NE_content_transfer_encoding = 8
110};
111
112
113/**
114 * Internal state of the post-processor.  Note that the fields
115 * are sorted by type to enable optimal packing by the compiler.
116 */
117struct MHD_PostProcessor
118{
119
120  /**
121   * The connection for which we are doing
122   * POST processing.
123   */
124  struct MHD_Connection *connection;
125
126  /**
127   * Function to call with POST data.
128   */
129  MHD_PostDataIterator ikvi;
130
131  /**
132   * Extra argument to ikvi.
133   */
134  void *cls;
135
136  /**
137   * Encoding as given by the headers of the
138   * connection.
139   */
140  const char *encoding;
141
142  /**
143   * Primary boundary (points into encoding string)
144   */
145  const char *boundary;
146
147  /**
148   * Nested boundary (if we have multipart/mixed encoding).
149   */
150  char *nested_boundary;
151
152  /**
153   * Pointer to the name given in disposition.
154   */
155  char *content_name;
156
157  /**
158   * Pointer to the (current) content type.
159   */
160  char *content_type;
161
162  /**
163   * Pointer to the (current) filename.
164   */
165  char *content_filename;
166
167  /**
168   * Pointer to the (current) encoding.
169   */
170  char *content_transfer_encoding;
171
172  /**
173   * Unprocessed value bytes due to escape
174   * sequences (URL-encoding only).
175   */
176  char xbuf[8];
177
178  /**
179   * Size of our buffer for the key.
180   */
181  size_t buffer_size;
182
183  /**
184   * Current position in the key buffer.
185   */
186  size_t buffer_pos;
187
188  /**
189   * Current position in xbuf.
190   */
191  size_t xbuf_pos;
192
193  /**
194   * Current offset in the value being processed.
195   */
196  uint64_t value_offset;
197
198  /**
199   * strlen(boundary) -- if boundary != NULL.
200   */
201  size_t blen;
202
203  /**
204   * strlen(nested_boundary) -- if nested_boundary != NULL.
205   */
206  size_t nlen;
207
208  /**
209   * Do we have to call the 'ikvi' callback when processing the
210   * multipart post body even if the size of the payload is zero?
211   * Set to #MHD_YES whenever we parse a new multiparty entry header,
212   * and to #MHD_NO the first time we call the 'ikvi' callback.
213   * Used to ensure that we do always call 'ikvi' even if the
214   * payload is empty (but not more than once).
215   */
216  int must_ikvi;
217
218  /**
219   * State of the parser.
220   */
221  enum PP_State state;
222
223  /**
224   * Side-state-machine: skip LRCR (or just LF).
225   * Set to 0 if we are not in skip mode.  Set to 2
226   * if a LFCR is expected, set to 1 if a CR should
227   * be skipped if it is the next character.
228   */
229  enum RN_State skip_rn;
230
231  /**
232   * If we are in skip_rn with "dash" mode and
233   * do find 2 dashes, what state do we go into?
234   */
235  enum PP_State dash_state;
236
237  /**
238   * Which headers are global? (used to tell which
239   * headers were only valid for the nested multipart).
240   */
241  enum NE_State have;
242
243};
244
245
246/**
247 * Create a `struct MHD_PostProcessor`.
248 *
249 * A `struct MHD_PostProcessor` can be used to (incrementally) parse
250 * the data portion of a POST request.  Note that some buggy browsers
251 * fail to set the encoding type.  If you want to support those, you
252 * may have to call #MHD_set_connection_value with the proper encoding
253 * type before creating a post processor (if no supported encoding
254 * type is set, this function will fail).
255 *
256 * @param connection the connection on which the POST is
257 *        happening (used to determine the POST format)
258 * @param buffer_size maximum number of bytes to use for
259 *        internal buffering (used only for the parsing,
260 *        specifically the parsing of the keys).  A
261 *        tiny value (256-1024) should be sufficient.
262 *        Do NOT use a value smaller than 256.  For good
263 *        performance, use 32 or 64k (i.e. 65536).
264 * @param iter iterator to be called with the parsed data,
265 *        Must NOT be NULL.
266 * @param iter_cls first argument to @a iter
267 * @return NULL on error (out of memory, unsupported encoding),
268 *         otherwise a PP handle
269 * @ingroup request
270 */
271struct MHD_PostProcessor *
272MHD_create_post_processor (struct MHD_Connection *connection,
273                           size_t buffer_size,
274                           MHD_PostDataIterator iter, void *iter_cls)
275{
276  struct MHD_PostProcessor *ret;
277  const char *encoding;
278  const char *boundary;
279  size_t blen;
280
281  if ((buffer_size < 256) || (connection == NULL) || (iter == NULL))
282    mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
283  encoding = MHD_lookup_connection_value (connection,
284                                          MHD_HEADER_KIND,
285                                          MHD_HTTP_HEADER_CONTENT_TYPE);
286  if (encoding == NULL)
287    return NULL;
288  boundary = NULL;
289  if (!MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, encoding,
290                        strlen (MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
291    {
292      if (!MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, encoding,
293                       strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
294        return NULL;
295      boundary =
296        &encoding[strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
297      /* Q: should this be "strcasestr"? */
298      boundary = strstr (boundary, "boundary=");
299      if (NULL == boundary)
300	return NULL; /* failed to determine boundary */
301      boundary += strlen ("boundary=");
302      blen = strlen (boundary);
303      if ((blen == 0) || (blen * 2 + 2 > buffer_size))
304        return NULL;            /* (will be) out of memory or invalid boundary */
305      if ( (boundary[0] == '"') && (boundary[blen - 1] == '"') )
306	{
307	  /* remove enclosing quotes */
308	  ++boundary;
309	  blen -= 2;
310	}
311    }
312  else
313    blen = 0;
314  buffer_size += 4; /* round up to get nice block sizes despite boundary search */
315
316  /* add +1 to ensure we ALWAYS have a zero-termination at the end */
317  if (NULL == (ret = malloc (sizeof (struct MHD_PostProcessor) + buffer_size + 1)))
318    return NULL;
319  memset (ret, 0, sizeof (struct MHD_PostProcessor) + buffer_size + 1);
320  ret->connection = connection;
321  ret->ikvi = iter;
322  ret->cls = iter_cls;
323  ret->encoding = encoding;
324  ret->buffer_size = buffer_size;
325  ret->state = PP_Init;
326  ret->blen = blen;
327  ret->boundary = boundary;
328  ret->skip_rn = RN_Inactive;
329  return ret;
330}
331
332
333/**
334 * Process url-encoded POST data.
335 *
336 * @param pp post processor context
337 * @param post_data upload data
338 * @param post_data_len number of bytes in @a post_data
339 * @return #MHD_YES on success, #MHD_NO if there was an error processing the data
340 */
341static int
342post_process_urlencoded (struct MHD_PostProcessor *pp,
343                         const char *post_data,
344			 size_t post_data_len)
345{
346  size_t equals;
347  size_t amper;
348  size_t poff;
349  size_t xoff;
350  size_t delta;
351  int end_of_value_found;
352  char *buf;
353  char xbuf[XBUF_SIZE + 1];
354
355  buf = (char *) &pp[1];
356  poff = 0;
357  while (poff < post_data_len)
358    {
359      switch (pp->state)
360        {
361        case PP_Error:
362          return MHD_NO;
363        case PP_Done:
364          /* did not expect to receive more data */
365          pp->state = PP_Error;
366          return MHD_NO;
367        case PP_Init:
368          equals = 0;
369          while ((equals + poff < post_data_len) &&
370                 (post_data[equals + poff] != '='))
371            equals++;
372          if (equals + pp->buffer_pos > pp->buffer_size)
373            {
374              pp->state = PP_Error;     /* out of memory */
375              return MHD_NO;
376            }
377          memcpy (&buf[pp->buffer_pos], &post_data[poff], equals);
378          pp->buffer_pos += equals;
379          if (equals + poff == post_data_len)
380            return MHD_YES;     /* no '=' yet */
381          buf[pp->buffer_pos] = '\0';   /* 0-terminate key */
382          pp->buffer_pos = 0;   /* reset for next key */
383	  MHD_unescape_plus (buf);
384          MHD_http_unescape (buf);
385          poff += equals + 1;
386          pp->state = PP_ProcessValue;
387          pp->value_offset = 0;
388          break;
389        case PP_ProcessValue:
390          /* obtain rest of value from previous iteration */
391          memcpy (xbuf, pp->xbuf, pp->xbuf_pos);
392          xoff = pp->xbuf_pos;
393          pp->xbuf_pos = 0;
394
395          /* find last position in input buffer that is part of the value */
396          amper = 0;
397          while ((amper + poff < post_data_len) &&
398                 (amper < XBUF_SIZE) &&
399                 (post_data[amper + poff] != '&') &&
400                 (post_data[amper + poff] != '\n') &&
401                 (post_data[amper + poff] != '\r'))
402            amper++;
403          end_of_value_found = ((amper + poff < post_data_len) &&
404                                ((post_data[amper + poff] == '&') ||
405                                 (post_data[amper + poff] == '\n') ||
406                                 (post_data[amper + poff] == '\r')));
407          /* compute delta, the maximum number of bytes that we will be able to
408             process right now (either amper-limited of xbuf-size limited) */
409          delta = amper;
410          if (delta > XBUF_SIZE - xoff)
411            delta = XBUF_SIZE - xoff;
412
413          /* move input into processing buffer */
414          memcpy (&xbuf[xoff], &post_data[poff], delta);
415          xoff += delta;
416          poff += delta;
417
418          /* find if escape sequence is at the end of the processing buffer;
419             if so, exclude those from processing (reduce delta to point at
420             end of processed region) */
421          delta = xoff;
422          if ((delta > 0) && (xbuf[delta - 1] == '%'))
423            delta--;
424          else if ((delta > 1) && (xbuf[delta - 2] == '%'))
425            delta -= 2;
426
427          /* if we have an incomplete escape sequence, save it to
428             pp->xbuf for later */
429          if (delta < xoff)
430            {
431              memcpy (pp->xbuf, &xbuf[delta], xoff - delta);
432              pp->xbuf_pos = xoff - delta;
433              xoff = delta;
434            }
435
436          /* If we have nothing to do (delta == 0) and
437             not just because the value is empty (are
438             waiting for more data), go for next iteration */
439          if ((xoff == 0) && (poff == post_data_len))
440            continue;
441
442          /* unescape */
443          xbuf[xoff] = '\0';    /* 0-terminate in preparation */
444	  MHD_unescape_plus (xbuf);
445          xoff = MHD_http_unescape (xbuf);
446          /* finally: call application! */
447	  pp->must_ikvi = MHD_NO;
448          if (MHD_NO == pp->ikvi (pp->cls, MHD_POSTDATA_KIND, (const char *) &pp[1],    /* key */
449                                  NULL, NULL, NULL, xbuf, pp->value_offset,
450                                  xoff))
451            {
452              pp->state = PP_Error;
453              return MHD_NO;
454            }
455          pp->value_offset += xoff;
456
457          /* are we done with the value? */
458          if (end_of_value_found)
459            {
460              /* we found the end of the value! */
461              if ((post_data[poff] == '\n') || (post_data[poff] == '\r'))
462                {
463                  pp->state = PP_ExpectNewLine;
464                }
465              else if (post_data[poff] == '&')
466                {
467                  poff++;       /* skip '&' */
468                  pp->state = PP_Init;
469                }
470            }
471          break;
472        case PP_ExpectNewLine:
473          if ((post_data[poff] == '\n') || (post_data[poff] == '\r'))
474            {
475              poff++;
476              /* we are done, report error if we receive any more... */
477              pp->state = PP_Done;
478              return MHD_YES;
479            }
480          return MHD_NO;
481        default:
482          mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);          /* should never happen! */
483        }
484    }
485  return MHD_YES;
486}
487
488
489/**
490 * If the given line matches the prefix, strdup the
491 * rest of the line into the suffix ptr.
492 *
493 * @param prefix prefix to match
494 * @param line line to match prefix in
495 * @param suffix set to a copy of the rest of the line, starting at the end of the match
496 * @return #MHD_YES if there was a match, #MHD_NO if not
497 */
498static int
499try_match_header (const char *prefix, char *line, char **suffix)
500{
501  if (NULL != *suffix)
502    return MHD_NO;
503  while (*line != 0)
504    {
505      if (MHD_str_equal_caseless_n_ (prefix, line, strlen (prefix)))
506        {
507          *suffix = strdup (&line[strlen (prefix)]);
508          return MHD_YES;
509        }
510      ++line;
511    }
512  return MHD_NO;
513}
514
515
516/**
517 *
518 * @param pp post processor context
519 * @param boundary boundary to look for
520 * @param blen number of bytes in boundary
521 * @param ioffptr set to the end of the boundary if found,
522 *                otherwise incremented by one (FIXME: quirky API!)
523 * @param next_state state to which we should advance the post processor
524 *                   if the boundary is found
525 * @param next_dash_state dash_state to which we should advance the
526 *                   post processor if the boundary is found
527 * @return #MHD_NO if the boundary is not found, #MHD_YES if we did find it
528 */
529static int
530find_boundary (struct MHD_PostProcessor *pp,
531               const char *boundary,
532               size_t blen,
533               size_t *ioffptr,
534               enum PP_State next_state, enum PP_State next_dash_state)
535{
536  char *buf = (char *) &pp[1];
537  const char *dash;
538
539  if (pp->buffer_pos < 2 + blen)
540    {
541      if (pp->buffer_pos == pp->buffer_size)
542        pp->state = PP_Error;   /* out of memory */
543      // ++(*ioffptr);
544      return MHD_NO;            /* not enough data */
545    }
546  if ((0 != memcmp ("--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen)))
547    {
548      if (pp->state != PP_Init)
549        {
550          /* garbage not allowed */
551          pp->state = PP_Error;
552        }
553      else
554        {
555          /* skip over garbage (RFC 2046, 5.1.1) */
556          dash = memchr (buf, '-', pp->buffer_pos);
557          if (NULL == dash)
558            (*ioffptr) += pp->buffer_pos; /* skip entire buffer */
559          else
560            if (dash == buf)
561              (*ioffptr)++; /* at least skip one byte */
562            else
563              (*ioffptr) += dash - buf; /* skip to first possible boundary */
564        }
565      return MHD_NO;            /* expected boundary */
566    }
567  /* remove boundary from buffer */
568  (*ioffptr) += 2 + blen;
569  /* next: start with headers */
570  pp->skip_rn = RN_Dash;
571  pp->state = next_state;
572  pp->dash_state = next_dash_state;
573  return MHD_YES;
574}
575
576
577/**
578 * In buf, there maybe an expression '$key="$value"'.  If that is the
579 * case, copy a copy of $value to destination.
580 *
581 * If destination is already non-NULL, do nothing.
582 */
583static void
584try_get_value (const char *buf,
585	       const char *key,
586	       char **destination)
587{
588  const char *spos;
589  const char *bpos;
590  const char *endv;
591  size_t klen;
592  size_t vlen;
593
594  if (NULL != *destination)
595    return;
596  bpos = buf;
597  klen = strlen (key);
598  while (NULL != (spos = strstr (bpos, key)))
599    {
600      if ((spos[klen] != '=') || ((spos != buf) && (spos[-1] != ' ')))
601        {
602          /* no match */
603          bpos = spos + 1;
604          continue;
605        }
606      if (spos[klen + 1] != '"')
607        return;                 /* not quoted */
608      if (NULL == (endv = strchr (&spos[klen + 2], '\"')))
609        return;                 /* no end-quote */
610      vlen = endv - spos - klen - 1;
611      *destination = malloc (vlen);
612      if (NULL == *destination)
613        return;                 /* out of memory */
614      (*destination)[vlen - 1] = '\0';
615      memcpy (*destination, &spos[klen + 2], vlen - 1);
616      return;                   /* success */
617    }
618}
619
620
621/**
622 * Go over the headers of the part and update
623 * the fields in "pp" according to what we find.
624 * If we are at the end of the headers (as indicated
625 * by an empty line), transition into next_state.
626 *
627 * @param pp post processor context
628 * @param ioffptr set to how many bytes have been
629 *                processed
630 * @param next_state state to which the post processor should
631 *                be advanced if we find the end of the headers
632 * @return #MHD_YES if we can continue processing,
633 *         #MHD_NO on error or if we do not have
634 *                enough data yet
635 */
636static int
637process_multipart_headers (struct MHD_PostProcessor *pp,
638                           size_t *ioffptr, enum PP_State next_state)
639{
640  char *buf = (char *) &pp[1];
641  size_t newline;
642
643  newline = 0;
644  while ((newline < pp->buffer_pos) &&
645         (buf[newline] != '\r') && (buf[newline] != '\n'))
646    newline++;
647  if (newline == pp->buffer_size)
648    {
649      pp->state = PP_Error;
650      return MHD_NO;            /* out of memory */
651    }
652  if (newline == pp->buffer_pos)
653    return MHD_NO;              /* will need more data */
654  if (0 == newline)
655    {
656      /* empty line - end of headers */
657      pp->skip_rn = RN_Full;
658      pp->state = next_state;
659      return MHD_YES;
660    }
661  /* got an actual header */
662  if (buf[newline] == '\r')
663    pp->skip_rn = RN_OptN;
664  buf[newline] = '\0';
665  if (MHD_str_equal_caseless_n_ ("Content-disposition: ",
666                        buf, strlen ("Content-disposition: ")))
667    {
668      try_get_value (&buf[strlen ("Content-disposition: ")],
669                     "name", &pp->content_name);
670      try_get_value (&buf[strlen ("Content-disposition: ")],
671                     "filename", &pp->content_filename);
672    }
673  else
674    {
675      try_match_header ("Content-type: ", buf, &pp->content_type);
676      try_match_header ("Content-Transfer-Encoding: ",
677                        buf, &pp->content_transfer_encoding);
678    }
679  (*ioffptr) += newline + 1;
680  return MHD_YES;
681}
682
683
684/**
685 * We have the value until we hit the given boundary;
686 * process accordingly.
687 *
688 * @param pp post processor context
689 * @param ioffptr incremented based on the number of bytes processed
690 * @param boundary the boundary to look for
691 * @param blen strlen(boundary)
692 * @param next_state what state to go into after the
693 *        boundary was found
694 * @param next_dash_state state to go into if the next
695 *        boundary ends with "--"
696 * @return #MHD_YES if we can continue processing,
697 *         #MHD_NO on error or if we do not have
698 *                enough data yet
699 */
700static int
701process_value_to_boundary (struct MHD_PostProcessor *pp,
702                           size_t *ioffptr,
703                           const char *boundary,
704                           size_t blen,
705                           enum PP_State next_state,
706                           enum PP_State next_dash_state)
707{
708  char *buf = (char *) &pp[1];
709  size_t newline;
710  const char *r;
711
712  /* all data in buf until the boundary
713     (\r\n--+boundary) is part of the value */
714  newline = 0;
715  while (1)
716    {
717      while (newline + 4 < pp->buffer_pos)
718        {
719          r = memchr (&buf[newline], '\r', pp->buffer_pos - newline - 4);
720          if (NULL == r)
721          {
722            newline = pp->buffer_pos - 4;
723            break;
724          }
725          newline = r - buf;
726          if (0 == memcmp ("\r\n--", &buf[newline], 4))
727            break;
728          newline++;
729        }
730      if (newline + pp->blen + 4 <= pp->buffer_pos)
731        {
732          /* can check boundary */
733          if (0 != memcmp (&buf[newline + 4], boundary, pp->blen))
734            {
735              /* no boundary, "\r\n--" is part of content, skip */
736              newline += 4;
737              continue;
738            }
739          else
740            {
741              /* boundary found, process until newline then
742                 skip boundary and go back to init */
743              pp->skip_rn = RN_Dash;
744              pp->state = next_state;
745              pp->dash_state = next_dash_state;
746              (*ioffptr) += pp->blen + 4;       /* skip boundary as well */
747              buf[newline] = '\0';
748              break;
749            }
750        }
751      else
752        {
753          /* cannot check for boundary, process content that
754             we have and check again later; except, if we have
755             no content, abort (out of memory) */
756          if ((0 == newline) && (pp->buffer_pos == pp->buffer_size))
757            {
758              pp->state = PP_Error;
759              return MHD_NO;
760            }
761          break;
762        }
763    }
764  /* newline is either at beginning of boundary or
765     at least at the last character that we are sure
766     is not part of the boundary */
767  if ( ( (MHD_YES == pp->must_ikvi) ||
768	 (0 != newline) ) &&
769       (MHD_NO == pp->ikvi (pp->cls,
770			    MHD_POSTDATA_KIND,
771			    pp->content_name,
772			    pp->content_filename,
773			    pp->content_type,
774			    pp->content_transfer_encoding,
775			    buf, pp->value_offset, newline)) )
776    {
777      pp->state = PP_Error;
778      return MHD_NO;
779    }
780  pp->must_ikvi = MHD_NO;
781  pp->value_offset += newline;
782  (*ioffptr) += newline;
783  return MHD_YES;
784}
785
786
787/**
788 *
789 * @param pp post processor context
790 */
791static void
792free_unmarked (struct MHD_PostProcessor *pp)
793{
794  if ((NULL != pp->content_name) && (0 == (pp->have & NE_content_name)))
795    {
796      free (pp->content_name);
797      pp->content_name = NULL;
798    }
799  if ((NULL != pp->content_type) && (0 == (pp->have & NE_content_type)))
800    {
801      free (pp->content_type);
802      pp->content_type = NULL;
803    }
804  if ((NULL != pp->content_filename) &&
805      (0 == (pp->have & NE_content_filename)))
806    {
807      free (pp->content_filename);
808      pp->content_filename = NULL;
809    }
810  if ((NULL != pp->content_transfer_encoding) &&
811      (0 == (pp->have & NE_content_transfer_encoding)))
812    {
813      free (pp->content_transfer_encoding);
814      pp->content_transfer_encoding = NULL;
815    }
816}
817
818
819/**
820 * Decode multipart POST data.
821 *
822 * @param pp post processor context
823 * @param post_data data to decode
824 * @param post_data_len number of bytes in @a post_data
825 * @return #MHD_NO on error,
826 */
827static int
828post_process_multipart (struct MHD_PostProcessor *pp,
829                        const char *post_data,
830			size_t post_data_len)
831{
832  char *buf;
833  size_t max;
834  size_t ioff;
835  size_t poff;
836  int state_changed;
837
838  buf = (char *) &pp[1];
839  ioff = 0;
840  poff = 0;
841  state_changed = 1;
842  while ((poff < post_data_len) ||
843         ((pp->buffer_pos > 0) && (state_changed != 0)))
844    {
845      /* first, move as much input data
846         as possible to our internal buffer */
847      max = pp->buffer_size - pp->buffer_pos;
848      if (max > post_data_len - poff)
849        max = post_data_len - poff;
850      memcpy (&buf[pp->buffer_pos], &post_data[poff], max);
851      poff += max;
852      pp->buffer_pos += max;
853      if ((max == 0) && (state_changed == 0) && (poff < post_data_len))
854        {
855          pp->state = PP_Error;
856          return MHD_NO;        /* out of memory */
857        }
858      state_changed = 0;
859
860      /* first state machine for '\r'-'\n' and '--' handling */
861      switch (pp->skip_rn)
862        {
863        case RN_Inactive:
864          break;
865        case RN_OptN:
866          if (buf[0] == '\n')
867            {
868              ioff++;
869              pp->skip_rn = RN_Inactive;
870              goto AGAIN;
871            }
872          /* fall-through! */
873        case RN_Dash:
874          if (buf[0] == '-')
875            {
876              ioff++;
877              pp->skip_rn = RN_Dash2;
878              goto AGAIN;
879            }
880          pp->skip_rn = RN_Full;
881          /* fall-through! */
882        case RN_Full:
883          if (buf[0] == '\r')
884            {
885              if ((pp->buffer_pos > 1) && (buf[1] == '\n'))
886                {
887                  pp->skip_rn = RN_Inactive;
888                  ioff += 2;
889                }
890              else
891                {
892                  pp->skip_rn = RN_OptN;
893                  ioff++;
894                }
895              goto AGAIN;
896            }
897          if (buf[0] == '\n')
898            {
899              ioff++;
900              pp->skip_rn = RN_Inactive;
901              goto AGAIN;
902            }
903          pp->skip_rn = RN_Inactive;
904          pp->state = PP_Error;
905          return MHD_NO;        /* no '\r\n' */
906        case RN_Dash2:
907          if (buf[0] == '-')
908            {
909              ioff++;
910              pp->skip_rn = RN_Full;
911              pp->state = pp->dash_state;
912              goto AGAIN;
913            }
914          pp->state = PP_Error;
915          break;
916        }
917
918      /* main state engine */
919      switch (pp->state)
920        {
921        case PP_Error:
922          return MHD_NO;
923        case PP_Done:
924          /* did not expect to receive more data */
925          pp->state = PP_Error;
926          return MHD_NO;
927        case PP_Init:
928          /**
929           * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything
930           * prior to the first multipart boundary:
931           *
932           * > There appears to be room for additional information prior
933           * > to the first boundary delimiter line and following the
934           * > final boundary delimiter line.  These areas should
935           * > generally be left blank, and implementations must ignore
936           * > anything that appears before the first boundary delimiter
937           * > line or after the last one.
938           */
939          (void) find_boundary (pp,
940				pp->boundary,
941				pp->blen,
942				&ioff,
943				PP_ProcessEntryHeaders, PP_Done);
944          break;
945        case PP_NextBoundary:
946          if (MHD_NO == find_boundary (pp,
947                                       pp->boundary,
948                                       pp->blen,
949                                       &ioff,
950                                       PP_ProcessEntryHeaders, PP_Done))
951            {
952              if (pp->state == PP_Error)
953                return MHD_NO;
954              goto END;
955            }
956          break;
957        case PP_ProcessEntryHeaders:
958	  pp->must_ikvi = MHD_YES;
959          if (MHD_NO ==
960              process_multipart_headers (pp, &ioff, PP_PerformCheckMultipart))
961            {
962              if (pp->state == PP_Error)
963                return MHD_NO;
964              else
965                goto END;
966            }
967          state_changed = 1;
968          break;
969        case PP_PerformCheckMultipart:
970          if ((pp->content_type != NULL) &&
971              (MHD_str_equal_caseless_n_ (pp->content_type,
972                                 "multipart/mixed",
973                                 strlen ("multipart/mixed"))))
974            {
975              pp->nested_boundary = strstr (pp->content_type, "boundary=");
976              if (pp->nested_boundary == NULL)
977                {
978                  pp->state = PP_Error;
979                  return MHD_NO;
980                }
981              pp->nested_boundary =
982                strdup (&pp->nested_boundary[strlen ("boundary=")]);
983              if (pp->nested_boundary == NULL)
984                {
985                  /* out of memory */
986                  pp->state = PP_Error;
987                  return MHD_NO;
988                }
989              /* free old content type, we will need that field
990                 for the content type of the nested elements */
991              free (pp->content_type);
992              pp->content_type = NULL;
993              pp->nlen = strlen (pp->nested_boundary);
994              pp->state = PP_Nested_Init;
995              state_changed = 1;
996              break;
997            }
998          pp->state = PP_ProcessValueToBoundary;
999          pp->value_offset = 0;
1000          state_changed = 1;
1001          break;
1002        case PP_ProcessValueToBoundary:
1003          if (MHD_NO == process_value_to_boundary (pp,
1004                                                   &ioff,
1005                                                   pp->boundary,
1006                                                   pp->blen,
1007                                                   PP_PerformCleanup,
1008                                                   PP_Done))
1009            {
1010              if (pp->state == PP_Error)
1011                return MHD_NO;
1012              break;
1013            }
1014          break;
1015        case PP_PerformCleanup:
1016          /* clean up state of one multipart form-data element! */
1017          pp->have = NE_none;
1018          free_unmarked (pp);
1019          if (pp->nested_boundary != NULL)
1020            {
1021              free (pp->nested_boundary);
1022              pp->nested_boundary = NULL;
1023            }
1024          pp->state = PP_ProcessEntryHeaders;
1025          state_changed = 1;
1026          break;
1027        case PP_Nested_Init:
1028          if (pp->nested_boundary == NULL)
1029            {
1030              pp->state = PP_Error;
1031              return MHD_NO;
1032            }
1033          if (MHD_NO == find_boundary (pp,
1034                                       pp->nested_boundary,
1035                                       pp->nlen,
1036                                       &ioff,
1037                                       PP_Nested_PerformMarking,
1038                                       PP_NextBoundary /* or PP_Error? */ ))
1039            {
1040              if (pp->state == PP_Error)
1041                return MHD_NO;
1042              goto END;
1043            }
1044          break;
1045        case PP_Nested_PerformMarking:
1046          /* remember what headers were given
1047             globally */
1048          pp->have = NE_none;
1049          if (pp->content_name != NULL)
1050            pp->have |= NE_content_name;
1051          if (pp->content_type != NULL)
1052            pp->have |= NE_content_type;
1053          if (pp->content_filename != NULL)
1054            pp->have |= NE_content_filename;
1055          if (pp->content_transfer_encoding != NULL)
1056            pp->have |= NE_content_transfer_encoding;
1057          pp->state = PP_Nested_ProcessEntryHeaders;
1058          state_changed = 1;
1059          break;
1060        case PP_Nested_ProcessEntryHeaders:
1061          pp->value_offset = 0;
1062          if (MHD_NO ==
1063              process_multipart_headers (pp, &ioff,
1064                                         PP_Nested_ProcessValueToBoundary))
1065            {
1066              if (pp->state == PP_Error)
1067                return MHD_NO;
1068              else
1069                goto END;
1070            }
1071          state_changed = 1;
1072          break;
1073        case PP_Nested_ProcessValueToBoundary:
1074          if (MHD_NO == process_value_to_boundary (pp,
1075                                                   &ioff,
1076                                                   pp->nested_boundary,
1077                                                   pp->nlen,
1078                                                   PP_Nested_PerformCleanup,
1079                                                   PP_NextBoundary))
1080            {
1081              if (pp->state == PP_Error)
1082                return MHD_NO;
1083              break;
1084            }
1085          break;
1086        case PP_Nested_PerformCleanup:
1087          free_unmarked (pp);
1088          pp->state = PP_Nested_ProcessEntryHeaders;
1089          state_changed = 1;
1090          break;
1091        default:
1092          mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);          /* should never happen! */
1093        }
1094    AGAIN:
1095      if (ioff > 0)
1096        {
1097          memmove (buf, &buf[ioff], pp->buffer_pos - ioff);
1098          pp->buffer_pos -= ioff;
1099          ioff = 0;
1100          state_changed = 1;
1101        }
1102    }
1103END:
1104  if (ioff != 0)
1105    {
1106      memmove (buf, &buf[ioff], pp->buffer_pos - ioff);
1107      pp->buffer_pos -= ioff;
1108    }
1109  if (poff < post_data_len)
1110    {
1111      pp->state = PP_Error;
1112      return MHD_NO;            /* serious error */
1113    }
1114  return MHD_YES;
1115}
1116
1117
1118/**
1119 * Parse and process POST data.  Call this function when POST data is
1120 * available (usually during an #MHD_AccessHandlerCallback) with the
1121 * "upload_data" and "upload_data_size".  Whenever possible, this will
1122 * then cause calls to the #MHD_PostDataIterator.
1123 *
1124 * @param pp the post processor
1125 * @param post_data @a post_data_len bytes of POST data
1126 * @param post_data_len length of @a post_data
1127 * @return #MHD_YES on success, #MHD_NO on error
1128 *         (out-of-memory, iterator aborted, parse error)
1129 * @ingroup request
1130 */
1131int
1132MHD_post_process (struct MHD_PostProcessor *pp,
1133                  const char *post_data, size_t post_data_len)
1134{
1135  if (0 == post_data_len)
1136    return MHD_YES;
1137  if (NULL == pp)
1138    return MHD_NO;
1139  if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, pp->encoding,
1140                         strlen(MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
1141    return post_process_urlencoded (pp, post_data, post_data_len);
1142  if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, pp->encoding,
1143                   strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
1144    return post_process_multipart (pp, post_data, post_data_len);
1145  /* this should never be reached */
1146  return MHD_NO;
1147}
1148
1149
1150/**
1151 * Release PostProcessor resources.
1152 *
1153 * @param pp post processor context to destroy
1154 * @return #MHD_YES if processing completed nicely,
1155 *         #MHD_NO if there were spurious characters / formatting
1156 *                problems; it is common to ignore the return
1157 *                value of this function
1158 * @ingroup request
1159 */
1160int
1161MHD_destroy_post_processor (struct MHD_PostProcessor *pp)
1162{
1163  int ret;
1164
1165  if (NULL == pp)
1166    return MHD_YES;
1167  if (PP_ProcessValue == pp->state)
1168  {
1169    /* key without terminated value left at the end of the
1170       buffer; fake receiving a termination character to
1171       ensure it is also processed */
1172    post_process_urlencoded (pp, "\n", 1);
1173  }
1174  /* These internal strings need cleaning up since
1175     the post-processing may have been interrupted
1176     at any stage */
1177  if ((pp->xbuf_pos > 0) ||
1178      ( (pp->state != PP_Done) &&
1179	(pp->state != PP_ExpectNewLine)))
1180    ret = MHD_NO;
1181  else
1182    ret = MHD_YES;
1183  pp->have = NE_none;
1184  free_unmarked (pp);
1185  if (pp->nested_boundary != NULL)
1186    free (pp->nested_boundary);
1187  free (pp);
1188  return ret;
1189}
1190
1191/* end of postprocessor.c */
1192