/*
     This file is part of libmicrohttpd
     Copyright (C) 2007-2021 Daniel Pittman, Christian Grothoff, and Evgeny Grin

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

/**
 * @file postprocessor.c
 * @brief  Methods for parsing POST data
 * @author Christian Grothoff
 * @author Karlson2k (Evgeny Grin)
 */

#include "postprocessor.h"
#include "internal.h"
#include "mhd_str.h"
#include "mhd_compat.h"
#include "mhd_assert.h"

/**
 * Size of on-stack buffer that we use for un-escaping of the value.
 * We use a pretty small value to be nice to the stack on embedded
 * systems.
 */
#define XBUF_SIZE 512


_MHD_EXTERN struct MHD_PostProcessor *
MHD_create_post_processor (struct MHD_Connection *connection,
                           size_t buffer_size,
                           MHD_PostDataIterator iter,
                           void *iter_cls)
{
  struct MHD_PostProcessor *ret;
  const char *encoding;
  const char *boundary;
  size_t blen;

  if ( (buffer_size < 256) ||
       (NULL == connection) ||
       (NULL == iter))
    MHD_PANIC (_ ("libmicrohttpd API violation.\n"));
  encoding = NULL;
  if (MHD_NO ==
      MHD_lookup_connection_value_n (connection,
                                     MHD_HEADER_KIND,
                                     MHD_HTTP_HEADER_CONTENT_TYPE,
                                     MHD_STATICSTR_LEN_ (
                                       MHD_HTTP_HEADER_CONTENT_TYPE),
                                     &encoding,
                                     NULL))
    return NULL;
  mhd_assert (NULL != encoding);
  boundary = NULL;
  if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
                                   encoding,
                                   MHD_STATICSTR_LEN_ (
                                     MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
  {
    if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
                                     encoding,
                                     MHD_STATICSTR_LEN_ (
                                       MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
      return NULL;
    boundary =
      &encoding[MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
    /* Q: should this be "strcasestr"? */
    boundary = strstr (boundary, "boundary=");
    if (NULL == boundary)
      return NULL; /* failed to determine boundary */
    boundary += MHD_STATICSTR_LEN_ ("boundary=");
    blen = strlen (boundary);
    if ( (blen < 2) ||
         (blen * 2 + 2 > buffer_size) )
      return NULL;              /* (will be) out of memory or invalid boundary */
    if ( (boundary[0] == '"') &&
         (boundary[blen - 1] == '"') )
    {
      /* remove enclosing quotes */
      ++boundary;
      blen -= 2;
    }
  }
  else
    blen = 0;
  buffer_size += 4; /* round up to get nice block sizes despite boundary search */

  /* add +1 to ensure we ALWAYS have a zero-termination at the end */
  if (NULL == (ret = MHD_calloc_ (1, sizeof (struct MHD_PostProcessor)
                                  + buffer_size + 1)))
    return NULL;
  ret->connection = connection;
  ret->ikvi = iter;
  ret->cls = iter_cls;
  ret->encoding = encoding;
  ret->buffer_size = buffer_size;
  ret->state = PP_Init;
  ret->blen = blen;
  ret->boundary = boundary;
  ret->skip_rn = RN_Inactive;
  return ret;
}


/**
 * Give a (possibly partial) value to the application callback.  We have some
 * part of the value in the 'pp->xbuf', the rest is between @a value_start and
 * @a value_end.  If @a last_escape is non-NULL, there may be an incomplete
 * escape sequence at at @a value_escape between @a value_start and @a
 * value_end which we should preserve in 'pp->xbuf' for the future.
 *
 * Unescapes the value and calls the iterator together with the key.  The key
 * must already be in the key buffer allocated and 0-terminated at the end of
 * @a pp at the time of the call.
 *
 * @param[in,out] pp post processor to act upon
 * @param value_start where in memory is the value
 * @param value_end where does the value end
 * @param last_escape last '%'-sign in value range,
 *        if relevant, or NULL
 */
static void
process_value (struct MHD_PostProcessor *pp,
               const char *value_start,
               const char *value_end,
               const char *last_escape)
{
  char xbuf[XBUF_SIZE + 1];
  size_t xoff;

  mhd_assert (pp->xbuf_pos < sizeof (xbuf));
  /* 'value_start' and 'value_end' must be either both non-NULL or both NULL */
  mhd_assert ( (NULL == value_start) || (NULL != value_end) );
  mhd_assert ( (NULL != value_start) || (NULL == value_end) );
  mhd_assert ( (NULL == last_escape) || (NULL != value_start) );
  /* move remaining input from previous round into processing buffer */
  if (0 != pp->xbuf_pos)
    memcpy (xbuf,
            pp->xbuf,
            pp->xbuf_pos);
  xoff = pp->xbuf_pos;
  pp->xbuf_pos = 0;
  if ( (NULL != last_escape) &&
       (((size_t) (value_end - last_escape)) < sizeof (pp->xbuf)) )
  {
    mhd_assert (value_end >= last_escape);
    pp->xbuf_pos = (size_t) (value_end - last_escape);
    memcpy (pp->xbuf,
            last_escape,
            (size_t) (value_end - last_escape));
    value_end = last_escape;
  }
  while ( (value_start != value_end) ||
          (pp->must_ikvi) ||
          (xoff > 0) )
  {
    size_t delta = (size_t) (value_end - value_start);
    bool cut = false;
    size_t clen = 0;

    mhd_assert (value_end >= value_start);

    if (delta > XBUF_SIZE - xoff)
      delta = XBUF_SIZE - xoff;
    /* move (additional) input into processing buffer */
    if (0 != delta)
    {
      memcpy (&xbuf[xoff],
              value_start,
              delta);
      xoff += delta;
      value_start += delta;
    }
    /* find if escape sequence is at the end of the processing buffer;
       if so, exclude those from processing (reduce delta to point at
       end of processed region) */
    if ( (xoff > 0) &&
         ('%' == xbuf[xoff - 1]) )
    {
      cut = (xoff != XBUF_SIZE);
      xoff--;
      if (cut)
      {
        /* move escape sequence into buffer for next function invocation */
        pp->xbuf[0] = '%';
        pp->xbuf_pos = 1;
      }
      else
      {
        /* just skip escape sequence for next loop iteration */
        delta = xoff;
        clen = 1;
      }
    }
    else if ( (xoff > 1) &&
              ('%' == xbuf[xoff - 2]) )
    {
      cut = (xoff != XBUF_SIZE);
      xoff -= 2;
      if (cut)
      {
        /* move escape sequence into buffer for next function invocation */
        memcpy (pp->xbuf,
                &xbuf[xoff],
                2);
        pp->xbuf_pos = 2;
      }
      else
      {
        /* just skip escape sequence for next loop iteration */
        delta = xoff;
        clen = 2;
      }
    }
    mhd_assert (xoff < sizeof (xbuf));
    /* unescape */
    xbuf[xoff] = '\0';        /* 0-terminate in preparation */
    if (0 != xoff)
    {
      MHD_unescape_plus (xbuf);
      xoff = MHD_http_unescape (xbuf);
    }
    /* finally: call application! */
    if (pp->must_ikvi || (0 != xoff) )
    {
      pp->must_ikvi = false;
      if (MHD_NO == pp->ikvi (pp->cls,
                              MHD_POSTDATA_KIND,
                              (const char *) &pp[1],      /* key */
                              NULL,
                              NULL,
                              NULL,
                              xbuf,
                              pp->value_offset,
                              xoff))
      {
        pp->state = PP_Error;
        return;
      }
    }
    pp->value_offset += xoff;
    if (cut)
      break;
    if (0 != clen)
    {
      xbuf[delta] = '%';        /* undo 0-termination */
      memmove (xbuf,
               &xbuf[delta],
               clen);
    }
    xoff = clen;
  }
}


/**
 * Process url-encoded POST data.
 *
 * @param pp post processor context
 * @param post_data upload data
 * @param post_data_len number of bytes in @a post_data
 * @return #MHD_YES on success, #MHD_NO if there was an error processing the data
 */
static enum MHD_Result
post_process_urlencoded (struct MHD_PostProcessor *pp,
                         const char *post_data,
                         size_t post_data_len)
{
  char *kbuf = (char *) &pp[1];
  size_t poff;
  const char *start_key = NULL;
  const char *end_key = NULL;
  const char *start_value = NULL;
  const char *end_value = NULL;
  const char *last_escape = NULL;

  mhd_assert (PP_Callback != pp->state);

  poff = 0;
  while ( ( (poff < post_data_len) ||
            (pp->state == PP_Callback) ) &&
          (pp->state != PP_Error) )
  {
    switch (pp->state)
    {
    case PP_Error:
      /* clearly impossible as per while loop invariant */
      abort ();
      break; /* Unreachable */
    case PP_Init:
      /* initial phase */
      mhd_assert (NULL == start_key);
      mhd_assert (NULL == end_key);
      mhd_assert (NULL == start_value);
      mhd_assert (NULL == end_value);
      switch (post_data[poff])
      {
      case '=':
        /* Case: (no key)'=' */
        /* Empty key with value */
        pp->state = PP_Error;
        continue;
      case '&':
        /* Case: (no key)'&' */
        /* Empty key without value */
        poff++;
        continue;
      case '\n':
      case '\r':
        /* Case: (no key)'\n' or (no key)'\r' */
        pp->state = PP_Done;
        poff++;
        break;
      default:
        /* normal character, key start, advance! */
        pp->state = PP_ProcessKey;
        start_key = &post_data[poff];
        pp->must_ikvi = true;
        poff++;
        continue;
      }
      break; /* end PP_Init */
    case PP_ProcessKey:
      /* key phase */
      mhd_assert (NULL == start_value);
      mhd_assert (NULL == end_value);
      mhd_assert (NULL != start_key || 0 == poff);
      mhd_assert (0 != poff || NULL == start_key);
      mhd_assert (NULL == end_key);
      switch (post_data[poff])
      {
      case '=':
        /* Case: 'key=' */
        if (0 != poff)
          end_key = &post_data[poff];
        poff++;
        pp->state = PP_ProcessValue;
        break;
      case '&':
        /* Case: 'key&' */
        if (0 != poff)
          end_key = &post_data[poff];
        poff++;
        pp->state = PP_Callback;
        break;
      case '\n':
      case '\r':
        /* Case: 'key\n' or 'key\r' */
        if (0 != poff)
          end_key = &post_data[poff];
        /* No advance here, 'PP_Done' will be selected by next 'PP_Init' phase */
        pp->state = PP_Callback;
        break;
      default:
        /* normal character, advance! */
        if (0 == poff)
          start_key = post_data;
        poff++;
        break;
      }
      mhd_assert (NULL == end_key || NULL != start_key);
      break; /* end PP_ProcessKey */
    case PP_ProcessValue:
      if (NULL == start_value)
        start_value = &post_data[poff];
      switch (post_data[poff])
      {
      case '=':
        /* case 'key==' */
        pp->state = PP_Error;
        continue;
      case '&':
        /* case 'value&' */
        end_value = &post_data[poff];
        poff++;
        if (pp->must_ikvi ||
            (start_value != end_value) )
        {
          pp->state = PP_Callback;
        }
        else
        {
          pp->buffer_pos = 0;
          pp->value_offset = 0;
          pp->state = PP_Init;
          start_value = NULL;
          end_value = NULL;
        }
        continue;
      case '\n':
      case '\r':
        /* Case: 'value\n' or 'value\r' */
        end_value = &post_data[poff];
        if (pp->must_ikvi ||
            (start_value != end_value) )
          pp->state = PP_Callback; /* No poff advance here to set PP_Done in the next iteration */
        else
        {
          poff++;
          pp->state = PP_Done;
        }
        break;
      case '%':
        last_escape = &post_data[poff];
        poff++;
        break;
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        /* character, may be part of escaping */
        poff++;
        continue;
      default:
        /* normal character, no more escaping! */
        last_escape = NULL;
        poff++;
        continue;
      }
      break; /* end PP_ProcessValue */
    case PP_Done:
      switch (post_data[poff])
      {
      case '\n':
      case '\r':
        poff++;
        continue;
      }
      /* unexpected data at the end, fail! */
      pp->state = PP_Error;
      break;
    case PP_Callback:
      mhd_assert ((NULL != end_key) || (NULL == start_key));
      if (1)
      {
        const size_t key_len = (size_t) (end_key - start_key);
        mhd_assert (end_key >= start_key);
        if (0 != key_len)
        {
          if ( (pp->buffer_pos + key_len >= pp->buffer_size) ||
               (pp->buffer_pos + key_len < pp->buffer_pos) )
          {
            /* key too long, cannot parse! */
            pp->state = PP_Error;
            continue;
          }
          /* compute key, if we have not already */
          memcpy (&kbuf[pp->buffer_pos],
                  start_key,
                  key_len);
          pp->buffer_pos += key_len;
          start_key = NULL;
          end_key = NULL;
          pp->must_unescape_key = true;
        }
      }
#ifdef _DEBUG
      else
        mhd_assert (0 != pp->buffer_pos);
#endif /* _DEBUG */
      if (pp->must_unescape_key)
      {
        kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */
        MHD_unescape_plus (kbuf);
        MHD_http_unescape (kbuf);
        pp->must_unescape_key = false;
      }
      process_value (pp,
                     start_value,
                     end_value,
                     NULL);
      if (PP_Error == pp->state)
        continue;
      pp->value_offset = 0;
      start_value = NULL;
      end_value = NULL;
      pp->buffer_pos = 0;
      pp->state = PP_Init;
      break;
    case PP_NextBoundary:
    case PP_ProcessEntryHeaders:
    case PP_PerformCheckMultipart:
    case PP_ProcessValueToBoundary:
    case PP_PerformCleanup:
    case PP_Nested_Init:
    case PP_Nested_PerformMarking:
    case PP_Nested_ProcessEntryHeaders:
    case PP_Nested_ProcessValueToBoundary:
    case PP_Nested_PerformCleanup:
    default:
      MHD_PANIC (_ ("internal error.\n")); /* should never happen! */
    }
    mhd_assert ((end_key == NULL) || (start_key != NULL));
    mhd_assert ((end_value == NULL) || (start_value != NULL));
  }

  mhd_assert (PP_Callback != pp->state);

  if (PP_Error == pp->state)
  {
    /* State in error, returning failure */
    return MHD_NO;
  }

  /* save remaining data for next iteration */
  if (NULL != start_key)
  {
    size_t key_len;
    mhd_assert ((PP_ProcessKey == pp->state) || (NULL != end_key));
    if (NULL == end_key)
      end_key = &post_data[poff];
    mhd_assert (end_key >= start_key);
    key_len = (size_t) (end_key - start_key);
    mhd_assert (0 != key_len); /* it must be always non-zero here */
    if (pp->buffer_pos + key_len >= pp->buffer_size)
    {
      pp->state = PP_Error;
      return MHD_NO;
    }
    memcpy (&kbuf[pp->buffer_pos],
            start_key,
            key_len);
    pp->buffer_pos += key_len;
    pp->must_unescape_key = true;
    start_key = NULL;
    end_key = NULL;
  }
  if ( (NULL != start_value) &&
       (PP_ProcessValue == pp->state) )
  {
    /* compute key, if we have not already */
    if (pp->must_unescape_key)
    {
      kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */
      MHD_unescape_plus (kbuf);
      MHD_http_unescape (kbuf);
      pp->must_unescape_key = false;
    }
    if (NULL == end_value)
      end_value = &post_data[poff];
    if ( (NULL != last_escape) &&
         (2 < (end_value - last_escape)) )
      last_escape = NULL;
    process_value (pp,
                   start_value,
                   end_value,
                   last_escape);
    pp->must_ikvi = false;
  }
  if (PP_Error == pp->state)
  {
    /* State in error, returning failure */
    return MHD_NO;
  }
  return MHD_YES;
}


/**
 * If the given line matches the prefix, strdup the
 * rest of the line into the suffix ptr.
 *
 * @param prefix prefix to match
 * @param prefix_len length of @a prefix
 * @param line line to match prefix in
 * @param suffix set to a copy of the rest of the line, starting at the end of the match
 * @return #MHD_YES if there was a match, #MHD_NO if not
 */
static int
try_match_header (const char *prefix,
                  size_t prefix_len,
                  char *line,
                  char **suffix)
{
  if (NULL != *suffix)
    return MHD_NO;
  while (0 != *line)
  {
    if (MHD_str_equal_caseless_n_ (prefix,
                                   line,
                                   prefix_len))
    {
      *suffix = strdup (&line[prefix_len]);
      return MHD_YES;
    }
    ++line;
  }
  return MHD_NO;
}


/**
 *
 * @param pp post processor context
 * @param boundary boundary to look for
 * @param blen number of bytes in boundary
 * @param ioffptr set to the end of the boundary if found,
 *                otherwise incremented by one (FIXME: quirky API!)
 * @param next_state state to which we should advance the post processor
 *                   if the boundary is found
 * @param next_dash_state dash_state to which we should advance the
 *                   post processor if the boundary is found
 * @return #MHD_NO if the boundary is not found, #MHD_YES if we did find it
 */
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)
{
  char *buf = (char *) &pp[1];
  const char *dash;

  if (pp->buffer_pos < 2 + blen)
  {
    if (pp->buffer_pos == pp->buffer_size)
      pp->state = PP_Error;     /* out of memory */
    /* ++(*ioffptr); */
    return MHD_NO;              /* not enough data */
  }
  if ( (0 != memcmp ("--",
                     buf,
                     2)) ||
       (0 != memcmp (&buf[2],
                     boundary,
                     blen)))
  {
    if (pp->state != PP_Init)
    {
      /* garbage not allowed */
      pp->state = PP_Error;
    }
    else
    {
      /* skip over garbage (RFC 2046, 5.1.1) */
      dash = memchr (buf,
                     '-',
                     pp->buffer_pos);
      if (NULL == dash)
        (*ioffptr) += pp->buffer_pos;         /* skip entire buffer */
      else if (dash == buf)
        (*ioffptr)++;                         /* at least skip one byte */
      else
        (*ioffptr) += (size_t) (dash - buf);  /* skip to first possible boundary */
    }
    return MHD_NO;                            /* expected boundary */
  }
  /* remove boundary from buffer */
  (*ioffptr) += 2 + blen;
  /* next: start with headers */
  pp->skip_rn = RN_Dash;
  pp->state = next_state;
  pp->dash_state = next_dash_state;
  return MHD_YES;
}


/**
 * In buf, there maybe an expression '$key="$value"'.  If that is the
 * case, copy a copy of $value to destination.
 *
 * If destination is already non-NULL, do nothing.
 */
static void
try_get_value (const char *buf,
               const char *key,
               char **destination)
{
  const char *spos;
  const char *bpos;
  const char *endv;
  size_t klen;
  size_t vlen;

  if (NULL != *destination)
    return;
  bpos = buf;
  klen = strlen (key);
  while (NULL != (spos = strstr (bpos, key)))
  {
    if ( (spos[klen] != '=') ||
         ( (spos != buf) &&
           (spos[-1] != ' ') ) )
    {
      /* no match */
      bpos = spos + 1;
      continue;
    }
    if (spos[klen + 1] != '"')
      return;                   /* not quoted */
    if (NULL == (endv = strchr (&spos[klen + 2],
                                '\"')))
      return;                   /* no end-quote */
    vlen = (size_t) (endv - spos) - klen - 1;
    *destination = malloc (vlen);
    if (NULL == *destination)
      return;                   /* out of memory */
    (*destination)[vlen - 1] = '\0';
    memcpy (*destination,
            &spos[klen + 2],
            vlen - 1);
    return;                     /* success */
  }
}


/**
 * Go over the headers of the part and update
 * the fields in "pp" according to what we find.
 * If we are at the end of the headers (as indicated
 * by an empty line), transition into next_state.
 *
 * @param pp post processor context
 * @param ioffptr set to how many bytes have been
 *                processed
 * @param next_state state to which the post processor should
 *                be advanced if we find the end of the headers
 * @return #MHD_YES if we can continue processing,
 *         #MHD_NO on error or if we do not have
 *                enough data yet
 */
static int
process_multipart_headers (struct MHD_PostProcessor *pp,
                           size_t *ioffptr,
                           enum PP_State next_state)
{
  char *buf = (char *) &pp[1];
  size_t newline;

  newline = 0;
  while ( (newline < pp->buffer_pos) &&
          (buf[newline] != '\r') &&
          (buf[newline] != '\n') )
    newline++;
  if (newline == pp->buffer_size)
  {
    pp->state = PP_Error;
    return MHD_NO;              /* out of memory */
  }
  if (newline == pp->buffer_pos)
    return MHD_NO;              /* will need more data */
  if (0 == newline)
  {
    /* empty line - end of headers */
    pp->skip_rn = RN_Full;
    pp->state = next_state;
    return MHD_YES;
  }
  /* got an actual header */
  if (buf[newline] == '\r')
    pp->skip_rn = RN_OptN;
  buf[newline] = '\0';
  if (MHD_str_equal_caseless_n_ ("Content-disposition: ",
                                 buf,
                                 MHD_STATICSTR_LEN_ ("Content-disposition: ")))
  {
    try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
                   "name",
                   &pp->content_name);
    try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
                   "filename",
                   &pp->content_filename);
  }
  else
  {
    try_match_header ("Content-type: ",
                      MHD_STATICSTR_LEN_ ("Content-type: "),
                      buf,
                      &pp->content_type);
    try_match_header ("Content-Transfer-Encoding: ",
                      MHD_STATICSTR_LEN_ ("Content-Transfer-Encoding: "),
                      buf,
                      &pp->content_transfer_encoding);
  }
  (*ioffptr) += newline + 1;
  return MHD_YES;
}


/**
 * We have the value until we hit the given boundary;
 * process accordingly.
 *
 * @param pp post processor context
 * @param ioffptr incremented based on the number of bytes processed
 * @param boundary the boundary to look for
 * @param blen strlen(boundary)
 * @param next_state what state to go into after the
 *        boundary was found
 * @param next_dash_state state to go into if the next
 *        boundary ends with "--"
 * @return #MHD_YES if we can continue processing,
 *         #MHD_NO on error or if we do not have
 *                enough data yet
 */
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)
{
  char *buf = (char *) &pp[1];
  size_t newline;
  const char *r;

  /* all data in buf until the boundary
     (\r\n--+boundary) is part of the value */
  newline = 0;
  while (1)
  {
    while (newline + 4 < pp->buffer_pos)
    {
      r = memchr (&buf[newline],
                  '\r',
                  pp->buffer_pos - newline - 4);
      if (NULL == r)
      {
        newline = pp->buffer_pos - 4;
        break;
      }
      newline = (size_t) (r - buf);
      if (0 == memcmp ("\r\n--",
                       &buf[newline],
                       4))
        break;
      newline++;
    }
    if (newline + blen + 4 <= pp->buffer_pos)
    {
      /* can check boundary */
      if (0 != memcmp (&buf[newline + 4],
                       boundary,
                       blen))
      {
        /* no boundary, "\r\n--" is part of content, skip */
        newline += 4;
        continue;
      }
      else
      {
        /* boundary found, process until newline then
           skip boundary and go back to init */
        pp->skip_rn = RN_Dash;
        pp->state = next_state;
        pp->dash_state = next_dash_state;
        (*ioffptr) += blen + 4;             /* skip boundary as well */
        buf[newline] = '\0';
        break;
      }
    }
    else
    {
      /* cannot check for boundary, process content that
         we have and check again later; except, if we have
         no content, abort (out of memory) */
      if ( (0 == newline) &&
           (pp->buffer_pos == pp->buffer_size) )
      {
        pp->state = PP_Error;
        return MHD_NO;
      }
      break;
    }
  }
  /* newline is either at beginning of boundary or
     at least at the last character that we are sure
     is not part of the boundary */
  if ( ( (pp->must_ikvi) ||
         (0 != newline) ) &&
       (MHD_NO == pp->ikvi (pp->cls,
                            MHD_POSTDATA_KIND,
                            pp->content_name,
                            pp->content_filename,
                            pp->content_type,
                            pp->content_transfer_encoding,
                            buf,
                            pp->value_offset,
                            newline)) )
  {
    pp->state = PP_Error;
    return MHD_NO;
  }
  pp->must_ikvi = false;
  pp->value_offset += newline;
  (*ioffptr) += newline;
  return MHD_YES;
}


/**
 *
 * @param pp post processor context
 */
static void
free_unmarked (struct MHD_PostProcessor *pp)
{
  if ( (NULL != pp->content_name) &&
       (0 == (pp->have & NE_content_name)) )
  {
    free (pp->content_name);
    pp->content_name = NULL;
  }
  if ( (NULL != pp->content_type) &&
       (0 == (pp->have & NE_content_type)) )
  {
    free (pp->content_type);
    pp->content_type = NULL;
  }
  if ( (NULL != pp->content_filename) &&
       (0 == (pp->have & NE_content_filename)) )
  {
    free (pp->content_filename);
    pp->content_filename = NULL;
  }
  if ( (NULL != pp->content_transfer_encoding) &&
       (0 == (pp->have & NE_content_transfer_encoding)) )
  {
    free (pp->content_transfer_encoding);
    pp->content_transfer_encoding = NULL;
  }
}


/**
 * Decode multipart POST data.
 *
 * @param pp post processor context
 * @param post_data data to decode
 * @param post_data_len number of bytes in @a post_data
 * @return #MHD_NO on error,
 */
static enum MHD_Result
post_process_multipart (struct MHD_PostProcessor *pp,
                        const char *post_data,
                        size_t post_data_len)
{
  char *buf;
  size_t max;
  size_t ioff;
  size_t poff;
  int state_changed;

  buf = (char *) &pp[1];
  ioff = 0;
  poff = 0;
  state_changed = 1;
  while ( (poff < post_data_len) ||
          ( (pp->buffer_pos > 0) &&
            (0 != state_changed) ) )
  {
    /* first, move as much input data
       as possible to our internal buffer */
    max = pp->buffer_size - pp->buffer_pos;
    if (max > post_data_len - poff)
      max = post_data_len - poff;
    memcpy (&buf[pp->buffer_pos],
            &post_data[poff],
            max);
    poff += max;
    pp->buffer_pos += max;
    if ( (0 == max) &&
         (0 == state_changed) &&
         (poff < post_data_len) )
    {
      pp->state = PP_Error;
      return MHD_NO;            /* out of memory */
    }
    state_changed = 0;

    /* first state machine for '\r'-'\n' and '--' handling */
    switch (pp->skip_rn)
    {
    case RN_Inactive:
      break;
    case RN_OptN:
      if (buf[0] == '\n')
      {
        ioff++;
        pp->skip_rn = RN_Inactive;
        goto AGAIN;
      }
    /* fall-through! */
    case RN_Dash:
      if (buf[0] == '-')
      {
        ioff++;
        pp->skip_rn = RN_Dash2;
        goto AGAIN;
      }
      pp->skip_rn = RN_Full;
    /* fall-through! */
    case RN_Full:
      if (buf[0] == '\r')
      {
        if ( (pp->buffer_pos > 1) &&
             ('\n' == buf[1]) )
        {
          pp->skip_rn = RN_Inactive;
          ioff += 2;
        }
        else
        {
          pp->skip_rn = RN_OptN;
          ioff++;
        }
        goto AGAIN;
      }
      if (buf[0] == '\n')
      {
        ioff++;
        pp->skip_rn = RN_Inactive;
        goto AGAIN;
      }
      pp->skip_rn = RN_Inactive;
      pp->state = PP_Error;
      return MHD_NO;            /* no '\r\n' */
    case RN_Dash2:
      if (buf[0] == '-')
      {
        ioff++;
        pp->skip_rn = RN_Full;
        pp->state = pp->dash_state;
        goto AGAIN;
      }
      pp->state = PP_Error;
      break;
    }

    /* main state engine */
    switch (pp->state)
    {
    case PP_Error:
      return MHD_NO;
    case PP_Done:
      /* did not expect to receive more data */
      pp->state = PP_Error;
      return MHD_NO;
    case PP_Init:
      /**
       * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything
       * prior to the first multipart boundary:
       *
       * > There appears to be room for additional information prior
       * > to the first boundary delimiter line and following the
       * > final boundary delimiter line.  These areas should
       * > generally be left blank, and implementations must ignore
       * > anything that appears before the first boundary delimiter
       * > line or after the last one.
       */
      (void) find_boundary (pp,
                            pp->boundary,
                            pp->blen,
                            &ioff,
                            PP_ProcessEntryHeaders,
                            PP_Done);
      break;
    case PP_NextBoundary:
      if (MHD_NO == find_boundary (pp,
                                   pp->boundary,
                                   pp->blen,
                                   &ioff,
                                   PP_ProcessEntryHeaders,
                                   PP_Done))
      {
        if (pp->state == PP_Error)
          return MHD_NO;
        goto END;
      }
      break;
    case PP_ProcessEntryHeaders:
      pp->must_ikvi = true;
      if (MHD_NO ==
          process_multipart_headers (pp,
                                     &ioff,
                                     PP_PerformCheckMultipart))
      {
        if (pp->state == PP_Error)
          return MHD_NO;
        else
          goto END;
      }
      state_changed = 1;
      break;
    case PP_PerformCheckMultipart:
      if ( (NULL != pp->content_type) &&
           (MHD_str_equal_caseless_n_ (pp->content_type,
                                       "multipart/mixed",
                                       MHD_STATICSTR_LEN_ ("multipart/mixed"))))
      {
        pp->nested_boundary = strstr (pp->content_type,
                                      "boundary=");
        if (NULL == pp->nested_boundary)
        {
          pp->state = PP_Error;
          return MHD_NO;
        }
        pp->nested_boundary =
          strdup (&pp->nested_boundary[MHD_STATICSTR_LEN_ ("boundary=")]);
        if (NULL == pp->nested_boundary)
        {
          /* out of memory */
          pp->state = PP_Error;
          return MHD_NO;
        }
        /* free old content type, we will need that field
           for the content type of the nested elements */
        free (pp->content_type);
        pp->content_type = NULL;
        pp->nlen = strlen (pp->nested_boundary);
        pp->state = PP_Nested_Init;
        state_changed = 1;
        break;
      }
      pp->state = PP_ProcessValueToBoundary;
      pp->value_offset = 0;
      state_changed = 1;
      break;
    case PP_ProcessValueToBoundary:
      if (MHD_NO == process_value_to_boundary (pp,
                                               &ioff,
                                               pp->boundary,
                                               pp->blen,
                                               PP_PerformCleanup,
                                               PP_Done))
      {
        if (pp->state == PP_Error)
          return MHD_NO;
        break;
      }
      break;
    case PP_PerformCleanup:
      /* clean up state of one multipart form-data element! */
      pp->have = NE_none;
      free_unmarked (pp);
      if (NULL != pp->nested_boundary)
      {
        free (pp->nested_boundary);
        pp->nested_boundary = NULL;
      }
      pp->state = PP_ProcessEntryHeaders;
      state_changed = 1;
      break;
    case PP_Nested_Init:
      if (NULL == pp->nested_boundary)
      {
        pp->state = PP_Error;
        return MHD_NO;
      }
      if (MHD_NO == find_boundary (pp,
                                   pp->nested_boundary,
                                   pp->nlen,
                                   &ioff,
                                   PP_Nested_PerformMarking,
                                   PP_NextBoundary /* or PP_Error? */))
      {
        if (pp->state == PP_Error)
          return MHD_NO;
        goto END;
      }
      break;
    case PP_Nested_PerformMarking:
      /* remember what headers were given
         globally */
      pp->have = NE_none;
      if (NULL != pp->content_name)
        pp->have |= NE_content_name;
      if (NULL != pp->content_type)
        pp->have |= NE_content_type;
      if (NULL != pp->content_filename)
        pp->have |= NE_content_filename;
      if (NULL != pp->content_transfer_encoding)
        pp->have |= NE_content_transfer_encoding;
      pp->state = PP_Nested_ProcessEntryHeaders;
      state_changed = 1;
      break;
    case PP_Nested_ProcessEntryHeaders:
      pp->value_offset = 0;
      if (MHD_NO ==
          process_multipart_headers (pp,
                                     &ioff,
                                     PP_Nested_ProcessValueToBoundary))
      {
        if (pp->state == PP_Error)
          return MHD_NO;
        else
          goto END;
      }
      state_changed = 1;
      break;
    case PP_Nested_ProcessValueToBoundary:
      if (MHD_NO == process_value_to_boundary (pp,
                                               &ioff,
                                               pp->nested_boundary,
                                               pp->nlen,
                                               PP_Nested_PerformCleanup,
                                               PP_NextBoundary))
      {
        if (pp->state == PP_Error)
          return MHD_NO;
        break;
      }
      break;
    case PP_Nested_PerformCleanup:
      free_unmarked (pp);
      pp->state = PP_Nested_ProcessEntryHeaders;
      state_changed = 1;
      break;
    case PP_ProcessKey:
    case PP_ProcessValue:
    case PP_Callback:
    default:
      MHD_PANIC (_ ("internal error.\n")); /* should never happen! */
    }
AGAIN:
    if (ioff > 0)
    {
      memmove (buf,
               &buf[ioff],
               pp->buffer_pos - ioff);
      pp->buffer_pos -= ioff;
      ioff = 0;
      state_changed = 1;
    }
  }
END:
  if (0 != ioff)
  {
    memmove (buf,
             &buf[ioff],
             pp->buffer_pos - ioff);
    pp->buffer_pos -= ioff;
  }
  if (poff < post_data_len)
  {
    pp->state = PP_Error;
    return MHD_NO;              /* serious error */
  }
  return MHD_YES;
}


_MHD_EXTERN enum MHD_Result
MHD_post_process (struct MHD_PostProcessor *pp,
                  const char *post_data,
                  size_t post_data_len)
{
  if (0 == post_data_len)
    return MHD_YES;
  if (NULL == pp)
    return MHD_NO;
  if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
                                 pp->encoding,
                                 MHD_STATICSTR_LEN_ (
                                   MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
    return post_process_urlencoded (pp,
                                    post_data,
                                    post_data_len);
  if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
                                 pp->encoding,
                                 MHD_STATICSTR_LEN_ (
                                   MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
    return post_process_multipart (pp,
                                   post_data,
                                   post_data_len);
  /* this should never be reached */
  return MHD_NO;
}


_MHD_EXTERN enum MHD_Result
MHD_destroy_post_processor (struct MHD_PostProcessor *pp)
{
  enum MHD_Result ret;

  if (NULL == pp)
    return MHD_YES;
  if (PP_ProcessValue == pp->state)
  {
    /* key without terminated value left at the end of the
       buffer; fake receiving a termination character to
       ensure it is also processed */
    post_process_urlencoded (pp,
                             "\n",
                             1);
  }
  /* These internal strings need cleaning up since
     the post-processing may have been interrupted
     at any stage */
  if ( (pp->xbuf_pos > 0) ||
       ( (pp->state != PP_Done) &&
         (pp->state != PP_Init) ) )
    ret = MHD_NO;
  else
    ret = MHD_YES;
  pp->have = NE_none;
  free_unmarked (pp);
  if (NULL != pp->nested_boundary)
    free (pp->nested_boundary);
  free (pp);
  return ret;
}


/* end of postprocessor.c */
