static void
_mime_received_bytes(void *data, const unsigned char *bytes, int size)
{
  int i = 0;
  char *id, *type, *location;
  mime_callback_data_t *cbdata = (mime_callback_data_t *) data;

  if (!cbdata)
  {
    log_error1
      ("MIME transport error Called <received bytes> without initializing\n");
    return;
  }
  if (!cbdata->current_part)
  {
    log_error1
      ("MIME transport error Called <received bytes> without initializing\n");
    return;
  }
/*  log_verbose4("Received %d bytes (%p), header_search = %d", 
    size, data, cbdata->header_search);
*/
  if (cbdata->header_search < 4)
  {
    /* Find \r\n\r\n in bytes */
    for (i = 0; i < size; i++)
    {
      if (cbdata->header_search == 0)
      {
        if (bytes[i] == '\r')
          cbdata->header_search++;
        else
        {
          cbdata->header[cbdata->header_index++] = bytes[i];
          cbdata->header_search = 0;
        }
      }

      else if (cbdata->header_search == 1)
      {
        if (bytes[i] == '\n')
          cbdata->header_search++;
        else
        {
          cbdata->header[cbdata->header_index++] = '\r';
          cbdata->header[cbdata->header_index++] = bytes[i];
          cbdata->header_search = 0;
        }
      }

      else if (cbdata->header_search == 2)
      {
        if (bytes[i] == '\r')
          cbdata->header_search++;
        else
        {
          cbdata->header[cbdata->header_index++] = '\r';
          cbdata->header[cbdata->header_index++] = '\n';
          cbdata->header[cbdata->header_index++] = bytes[i];
          cbdata->header_search = 0;
        }
      }

      else if (cbdata->header_search == 3)
      {
        if (bytes[i] == '\n')
        {
          cbdata->header[cbdata->header_index++] = '\r';
          cbdata->header[cbdata->header_index++] = '\n';
          cbdata->header[cbdata->header_index++] = '\0';
          cbdata->header_search = 4;
          cbdata->current_part->header = _mime_process_header(cbdata->header);
          hpairnode_dump_deep(cbdata->current_part->header);
          /* set id */
          id = hpairnode_get(cbdata->current_part->header, HEADER_CONTENT_ID);
          if (id != NULL)
          {
            strcpy(cbdata->current_part->id, id);
            if (!strcmp(id, cbdata->root_id))
              cbdata->message->root_part = cbdata->current_part;
          }
          location =
            hpairnode_get(cbdata->current_part->header,
                          HEADER_CONTENT_LOCATION);
          if (location != NULL)
          {
            strcpy(cbdata->current_part->location, location);
          }
          type =
            hpairnode_get(cbdata->current_part->header, HEADER_CONTENT_TYPE);
          if (type != NULL)
          {
            strcpy(cbdata->current_part->content_type, type);
          }
          i++;
          break;
        }
        else
        {
          cbdata->header[cbdata->header_index++] = '\r';
          cbdata->header[cbdata->header_index++] = '\n';
          cbdata->header[cbdata->header_index++] = '\r';
          cbdata->header[cbdata->header_index++] = bytes[i];
          cbdata->header_search = 0;
        }
      }
      /* TODO (#1#): Check for cbdata->header overflow */

    }                           /* for (i=0;i<size;i++) */
  }                             /* if (cbdata->header_search < 4) */

  if (i >= size - 1)
    return;

  /* Write remaining bytes into the file or buffer (if root) (buffer is
     disabled in this version) */
  if (cbdata->current_fd)
    fwrite(&(bytes[i]), 1, size - i, cbdata->current_fd);
}
herror_t
mime_get_attachments(content_type_t * ctype, http_input_stream_t * in,
                     attachments_t ** dest)
{
  /* MIME variables */
  attachments_t *mimeMessage;
  part_t *part, *tmp_part = NULL;
  char *boundary, *root_id;

  /* Check for MIME message */
  if (!(ctype && !strcmp(ctype->type, "multipart/related")))
    return herror_new("mime_get_attachments", MIME_ERROR_NOT_MIME_MESSAGE,
                      "Not a MIME message '%s'", ctype->type);

  boundary = hpairnode_get(ctype->params, "boundary");
  root_id = hpairnode_get(ctype->params, "start");
  if (boundary == NULL)
  {
    /* TODO (#1#): Handle Error in http form */
    log_error1("'boundary' not set for multipart/related");
    return herror_new("mime_get_attachments", MIME_ERROR_NO_BOUNDARY_PARAM,
                      "'boundary' not set for multipart/related");
  }

  if (root_id == NULL)
  {
    /* TODO (#1#): Handle Error in http form */
    log_error1("'start' not set for multipart/related");
    return herror_new("mime_get_attachments", MIME_ERROR_NO_START_PARAM,
                      "'start' not set for multipart/related");
  }

  mimeMessage =
    mime_message_parse(in, root_id, boundary, ".");
  if (mimeMessage == NULL)
  {
    /* TODO (#1#): Handle Error in http form */
    log_error1("MIME Parse Error");
    return herror_new("mime_get_attachments", MIME_ERROR_PARSE_ERROR,
                      "MIME Parse Error");
  }

  /* Find root */
  if (!mimeMessage->root_part)
  {
    attachments_free(mimeMessage);
    return herror_new("mime_get_attachments", MIME_ERROR_NO_ROOT_PART,
                      "No root part found!");
  }

  /* delete root_part from list */
  part = mimeMessage->parts;
  while (part)
  {
    if (part == mimeMessage->root_part)
    {
      if (tmp_part)
        tmp_part->next = part->next;
      else
        mimeMessage->parts = part->next;

      break;
    }
    tmp_part = part;
    part = part->next;
  }
  *dest = mimeMessage;
  return H_OK;
}
コード例 #3
0
ファイル: nanohttp-response.c プロジェクト: rcarz/bonsai
static hresponse_t *
_hresponse_parse_header(const char *buffer)
{
  hresponse_t *res;
  char *s1, *s2, *str;

  /* create response object */
  res = hresponse_new();

  /* *** parse spec *** */
  /* [HTTP/1.1 | 1.2] [CODE] [DESC] */

  /* stage 1: HTTP spec */
  str = (char *) strtok_r((char *) buffer, " ", &s2);
  s1 = s2;
  if (str == NULL)
  {
    log_error("Parse error reading HTTP spec");
    return NULL;
  }

  if (!strcmp(str, "HTTP/1.0"))
    res->version = HTTP_1_0;
  else
    res->version = HTTP_1_1;

  /* stage 2: http code */
  str = (char *) strtok_r(s1, " ", &s2);
  s1 = s2;
  if (str == NULL)
  {
    log_error("Parse error reading HTTP code");
    return NULL;
  }
  res->errcode = atoi(str);

  /* stage 3: description text */
  str = (char *) strtok_r(s1, "\r\n", &s2);
  s1 = s2;
  if (str == NULL)
  {
    log_error("Parse error reading HTTP description");
    return NULL;
  }
/*	res->desc = (char *) malloc(strlen(str) + 1);*/
  strncpy(res->desc, str, RESPONSE_MAX_DESC_SIZE);
  res->desc[strlen(str)] = '\0';

  /* *** parse header *** */
  /* [key]: [value] */
  for (;;)
  {
    str = strtok_r(s1, "\n", &s2);
    s1 = s2;

    /* check if header ends without body */
    if (str == NULL)
    {
      return res;
    }
    /* check also for end of header */
    if (!strcmp(str, "\r"))
    {
      break;
    }
    str[strlen(str) - 1] = '\0';
    res->header = hpairnode_parse(str, ":", res->header);
  }

  /* Check Content-type */
  str = hpairnode_get(res->header, HEADER_CONTENT_TYPE);
  if (str != NULL)
    res->content_type = content_type_new(str);

  /* return response object */
  return res;
}