Diff for /libaitwww/src/mime.c between versions 1.1.1.1.2.1 and 1.4.6.1

version 1.1.1.1.2.1, 2012/03/09 09:38:55 version 1.4.6.1, 2013/01/17 14:52:44
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 45  SUCH DAMAGE. Line 45  SUCH DAMAGE.
 */  */
 #include "global.h"  #include "global.h"
 #include "mime.h"  #include "mime.h"
 #include "tools.h"  
   
   
 static int decode_quoted(char *, int, char *);  static int decode_quoted(char *, int, char *);
Line 69  bd_begin(const char *str) Line 68  bd_begin(const char *str)
         char *s;          char *s;
         int len = strlen(str) + 6;          int len = strlen(str) + 6;
   
        s = malloc(len + 1);        s = e_malloc(len + 1);
         if (!s) {          if (!s) {
                LOGERR;                www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                 return NULL;                  return NULL;
         } else {          } else {
                 snprintf(s, len + 1, "\r\n--%s\r\n", str);                  snprintf(s, len + 1, "\r\n--%s\r\n", str);
Line 87  bd_end(const char *str) Line 86  bd_end(const char *str)
         char *s;          char *s;
         int len = strlen(str) + 8;          int len = strlen(str) + 8;
   
        s = malloc(len + 1);        s = e_malloc(len + 1);
         if (!s) {          if (!s) {
                LOGERR;                www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                 return NULL;                  return NULL;
         } else {          } else {
                 snprintf(s, len + 1, "\r\n--%s--\r\n", str);                  snprintf(s, len + 1, "\r\n--%s--\r\n", str);
Line 151  freeHeader(struct tagMIME * __restrict m) Line 150  freeHeader(struct tagMIME * __restrict m)
         struct tagCGI *c;          struct tagCGI *c;
   
         while ((c = SLIST_FIRST(&m->mime_header))) {          while ((c = SLIST_FIRST(&m->mime_header))) {
                if (c->cgi_name)                ait_freeVar(&c->cgi_name);
                        free(c->cgi_name);                ait_freeVar(&c->cgi_value);
                if (c->cgi_value)
                        free(c->cgi_value); 
                 SLIST_REMOVE_HEAD(&m->mime_header, cgi_node);                  SLIST_REMOVE_HEAD(&m->mime_header, cgi_node);
                free(c);                e_free(c);
         }          }
 }  }
   
static char *static ait_val_t *
 hdrValue(const char *str, size_t len, const char **end)  hdrValue(const char *str, size_t len, const char **end)
 {  {
         const char *e, *crlf = NULL;          const char *e, *crlf = NULL;
         char *tmp, *s = NULL;          char *tmp, *s = NULL;
         int off = 0;          int off = 0;
           ait_val_t *ret = NULL;
   
         e = str + len;          e = str + len;
         while (str < e) {          while (str < e) {
                if ((crlf = findtextpos(str, e - str, CRLF, strlen(CRLF)))) {                if (!(crlf = findtextpos(str, e - str, CRLF, strlen(CRLF)))) {
                        www_SetErr(EBADMSG, "Bad MIME format message");                        www_SetErr(EFAULT, "Bad header format of MIME part");
                         return NULL;                          return NULL;
                 }                  }
   
                tmp = realloc(s, crlf - str + off + 1);                tmp = e_realloc(s, crlf - str + off + 1);
                 if (!tmp) {                  if (!tmp) {
                        LOGERR;                        www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                        free(s);                        e_free(s);
                         return NULL;                          return NULL;
                 } else                  } else
                         s = tmp;                          s = tmp;
Line 195  hdrValue(const char *str, size_t len, const char **end Line 194  hdrValue(const char *str, size_t len, const char **end
         }          }
   
         *end = crlf + strlen(CRLF);          *end = crlf + strlen(CRLF);
        return s;        ret = ait_makeVar(string, s);
         if (!ret)
                 www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
         e_free(s);
 
         return ret;
 }  }
   
 static inline int  static inline int
Line 328  mime_parseMultiPart(const char *str, size_t len, const Line 332  mime_parseMultiPart(const char *str, size_t len, const
         mime_t *mime = NULL;          mime_t *mime = NULL;
         struct iovec bd[2];          struct iovec bd[2];
         struct tagMIME *m, *old = NULL;          struct tagMIME *m, *old = NULL;
        const char *next;        const char *next = NULL;
   
         if (!str | !bdtag) {          if (!str | !bdtag) {
                 www_SetErr(EINVAL, "String or boundary tag is NULL");                  www_SetErr(EINVAL, "String or boundary tag is NULL");
Line 336  mime_parseMultiPart(const char *str, size_t len, const Line 340  mime_parseMultiPart(const char *str, size_t len, const
         }          }
   
         /* init MIME */          /* init MIME */
        mime = malloc(sizeof(mime_t));        mime = e_malloc(sizeof(mime_t));
         if (!mime) {          if (!mime) {
                LOGERR;                www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                 return NULL;                  return NULL;
         } else {          } else {
                 memset(mime, 0, sizeof(mime_t));                  memset(mime, 0, sizeof(mime_t));
Line 348  mime_parseMultiPart(const char *str, size_t len, const Line 352  mime_parseMultiPart(const char *str, size_t len, const
         /* prepare boundary format */          /* prepare boundary format */
         bd[0].iov_base = bd_begin(bdtag);          bd[0].iov_base = bd_begin(bdtag);
         if (!bd[0].iov_base) {          if (!bd[0].iov_base) {
                free(mime);                e_free(mime);
                 return NULL;                  return NULL;
         } else          } else
                 bd[0].iov_len = strlen(bd[0].iov_base);                  bd[0].iov_len = strlen(bd[0].iov_base);
         bd[1].iov_base = bd_end(bdtag);          bd[1].iov_base = bd_end(bdtag);
         if (!bd[1].iov_base) {          if (!bd[1].iov_base) {
                free(bd[0].iov_base);                e_free(bd[0].iov_base);
                free(mime);                e_free(mime);
                 return NULL;                  return NULL;
         } else          } else
                 bd[1].iov_len = strlen(bd[1].iov_base);                  bd[1].iov_len = strlen(bd[1].iov_base);
   
           /* check boundary tag */
         if (memcmp(str, strstr(bd[0].iov_base, "--"), strlen(strstr(bd[0].iov_base, "--")))) {          if (memcmp(str, strstr(bd[0].iov_base, "--"), strlen(strstr(bd[0].iov_base, "--")))) {
                www_SetErr(EBADMSG, "Bad content data, not found boundary tag");                www_SetErr(EFAULT, "Bad content data, not found boundary tag");
                free(bd[1].iov_base);                e_free(bd[1].iov_base);
                free(bd[0].iov_base);                e_free(bd[0].iov_base);
                free(mime);                e_free(mime);
                 return NULL;                  return NULL;
         } else {          } else {
                 str += strlen(strstr(bd[0].iov_base, "--"));                  str += strlen(strstr(bd[0].iov_base, "--"));
                 len -= strlen(strstr(bd[0].iov_base, "--"));                  len -= strlen(strstr(bd[0].iov_base, "--"));
         }          }
   
        while (42) {        while (len > 0) {
                m = malloc(sizeof(struct tagMIME));                m = e_malloc(sizeof(struct tagMIME));
                 if (!m) {                  if (!m) {
                        LOGERR;                        www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                         mime_close(&mime);                          mime_close(&mime);
                        free(bd[1].iov_base);                        e_free(bd[1].iov_base);
                        free(bd[0].iov_base);                        e_free(bd[0].iov_base);
                         return NULL;                          return NULL;
                 } else {                  } else {
                         memset(m, 0, sizeof(struct tagMIME));                          memset(m, 0, sizeof(struct tagMIME));
Line 389  mime_parseMultiPart(const char *str, size_t len, const Line 395  mime_parseMultiPart(const char *str, size_t len, const
                 /* parse message between tags */                  /* parse message between tags */
                 if (mime_readPart(m, str, next - str)) {                  if (mime_readPart(m, str, next - str)) {
                         mime_close(&mime);                          mime_close(&mime);
                        free(bd[1].iov_base);                        e_free(bd[1].iov_base);
                        free(bd[0].iov_base);                        e_free(bd[0].iov_base);
                         return NULL;                          return NULL;
                 }                  }
   
Line 418  mime_parseMultiPart(const char *str, size_t len, const Line 424  mime_parseMultiPart(const char *str, size_t len, const
         len -= bd[0].iov_len;          len -= bd[0].iov_len;
         */          */
   
           e_free(bd[1].iov_base);
           e_free(bd[0].iov_base);
   
         if (end)          if (end)
                 *end = str;                  *end = str;
         return mime;          return mime;
Line 427  static inline void Line 436  static inline void
 freeMIME(struct tagMIME * __restrict m)  freeMIME(struct tagMIME * __restrict m)
 {  {
         if (m->mime_body.iov_base)          if (m->mime_body.iov_base)
                free(m->mime_body.iov_base);                e_free(m->mime_body.iov_base);
         if (m->mime_prolog.iov_base)          if (m->mime_prolog.iov_base)
                free(m->mime_prolog.iov_base);                e_free(m->mime_prolog.iov_base);
         if (m->mime_epilog.iov_base)          if (m->mime_epilog.iov_base)
                free(m->mime_epilog.iov_base);                e_free(m->mime_epilog.iov_base);
   
         freeHeader(m);          freeHeader(m);
         mime_close(&m->mime_attach);          mime_close(&m->mime_attach);
Line 454  mime_close(mime_t ** __restrict mime) Line 463  mime_close(mime_t ** __restrict mime)
         while ((m = SLIST_FIRST(*mime))) {          while ((m = SLIST_FIRST(*mime))) {
                 SLIST_REMOVE_HEAD(*mime, mime_node);                  SLIST_REMOVE_HEAD(*mime, mime_node);
                 freeMIME(m);                  freeMIME(m);
                free(m);                e_free(m);
         }          }
   
        free(*mime);        e_free(*mime);
         *mime = NULL;          *mime = NULL;
 }  }
   
Line 491  mime_parseHeader(struct tagMIME * __restrict m, const  Line 500  mime_parseHeader(struct tagMIME * __restrict m, const 
                 colon = memchr(str, ':', e - str);                  colon = memchr(str, ':', e - str);
                 eoh = findtextpos(str, e - str, CRLF, strlen(CRLF));                  eoh = findtextpos(str, e - str, CRLF, strlen(CRLF));
                 if (!colon || !eoh || colon > eoh) {                  if (!colon || !eoh || colon > eoh) {
                        www_SetErr(EBADMSG, "Bad MIME format message");                        www_SetErr(EFAULT, "Bad MIME format message");
                         freeHeader(m);                          freeHeader(m);
                         return -1;                          return -1;
                 }                  }
   
                c = malloc(sizeof(struct tagCGI));                c = e_malloc(sizeof(struct tagCGI));
                 if (!c) {                  if (!c) {
                        LOGERR;                        www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                         freeHeader(m);                          freeHeader(m);
                         return -1;                          return -1;
                 }                  }
                 /* get name */                  /* get name */
                c->cgi_name = malloc(colon - str + 1);                c->cgi_name = ait_allocVar();
                 if (!c->cgi_name) {                  if (!c->cgi_name) {
                        LOGERR;                        www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                        free(c);                        e_free(c);
                         freeHeader(m);                          freeHeader(m);
                         return -1;                          return -1;
                } else {                } else
                        memcpy(c->cgi_name, str, colon - str);                        AIT_SET_STRLCPY(c->cgi_name, str, colon - str + 1);
                        c->cgi_name[colon - str] = 0; 
                } 
                 /* get value */                  /* get value */
                 c->cgi_value = hdrValue(colon + 1, e - colon - 1, &str);                  c->cgi_value = hdrValue(colon + 1, e - colon - 1, &str);
                   if (!c->cgi_value) {
                           free(c->cgi_name);
                           free(c);
                           freeHeader(m);
                           return -1;
                   }
   
                 if (!old)                  if (!old)
                         SLIST_INSERT_HEAD(&m->mime_header, c, cgi_node);                          SLIST_INSERT_HEAD(&m->mime_header, c, cgi_node);
Line 539  inline const char * Line 552  inline const char *
 mime_getValue(struct tagMIME * __restrict m, const char *name)  mime_getValue(struct tagMIME * __restrict m, const char *name)
 {  {
         struct tagCGI *c;          struct tagCGI *c;
         const char *v = NULL;  
   
         SLIST_FOREACH(c, &m->mime_header, cgi_node)          SLIST_FOREACH(c, &m->mime_header, cgi_node)
                if (!strcmp(c->cgi_name, name)) {                if (!strcasecmp(AIT_GET_STR(c->cgi_name), name))
                        v = c->cgi_value;                        return AIT_GET_STR(c->cgi_value);
                        break;
                }        return NULL;
        return v; 
 }  }
   
 /*  /*
Line 563  mime_readPart(struct tagMIME * __restrict m, const cha Line 574  mime_readPart(struct tagMIME * __restrict m, const cha
         const char *eoh, *ct, *eb;          const char *eoh, *ct, *eb;
         cgi_t *attr;          cgi_t *attr;
         struct iovec bd;          struct iovec bd;
           ait_val_t *v;
   
        if (!m || !str) {        if (!m || !str || (ssize_t) len < 0) {
                www_SetErr(EINVAL, "Mime part or string is NULL");                www_SetErr(EINVAL, "Mime part, string is NULL or length is less 0");
                 return -1;                  return -1;
         }          }
   
Line 575  mime_readPart(struct tagMIME * __restrict m, const cha Line 587  mime_readPart(struct tagMIME * __restrict m, const cha
         ct = mime_getValue(m, "content-type");          ct = mime_getValue(m, "content-type");
         if (!ct || www_cmptype(ct, "multipart")) {          if (!ct || www_cmptype(ct, "multipart")) {
                 /* not multi part, assign like body element */                  /* not multi part, assign like body element */
                m->mime_body.iov_base = malloc(len - (eoh - str) + 1);                m->mime_body.iov_base = e_malloc(len - (eoh - str) + 1);
                 if (!m->mime_body.iov_base) {
                         www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                         freeHeader(m);
                         return -1;
                 }
                 memcpy(m->mime_body.iov_base, eoh, len - (eoh - str));                  memcpy(m->mime_body.iov_base, eoh, len - (eoh - str));
                 ((char*) m->mime_body.iov_base)[len - (eoh - str)] = 0;                  ((char*) m->mime_body.iov_base)[len - (eoh - str)] = 0;
                 m->mime_body.iov_len = len - (eoh - str) + 1;                  m->mime_body.iov_len = len - (eoh - str) + 1;
         } else {          } else {
                 /* multi part */                  /* multi part */
                 attr = www_parseAttributes(&ct);                  attr = www_parseAttributes(&ct);
                if (!attr)                if (!attr) {
                         freeHeader(m);
                         return -1;                          return -1;
                bd.iov_base = bd_begin(www_getAttribute(attr, "boundary"));                }
                 v = www_getAttribute(attr, "boundary");
                 bd.iov_base = bd_begin(AIT_GET_STR(v));
                 bd.iov_len = strlen(bd.iov_base);                  bd.iov_len = strlen(bd.iov_base);
                 eb = findtextpos(eoh, len - (eoh - str), bd.iov_base, bd.iov_len);                  eb = findtextpos(eoh, len - (eoh - str), bd.iov_base, bd.iov_len);
                free(bd.iov_base);                e_free(bd.iov_base);
   
                 /* set prolog if exists */                  /* set prolog if exists */
                 if (eb != eoh) {                  if (eb != eoh) {
                        m->mime_prolog.iov_base = malloc(eb - eoh + 1);                        m->mime_prolog.iov_base = e_malloc(eb - eoh + 1);
                         if (!m->mime_prolog.iov_base) {                          if (!m->mime_prolog.iov_base) {
                                LOGERR;                                www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                                 www_freeAttributes(&attr);                                  www_freeAttributes(&attr);
                                   freeHeader(m);
                                 return -1;                                  return -1;
                         }                          }
                         memcpy(m->mime_prolog.iov_base, eoh, eb - eoh);                          memcpy(m->mime_prolog.iov_base, eoh, eb - eoh);
Line 602  mime_readPart(struct tagMIME * __restrict m, const cha Line 623  mime_readPart(struct tagMIME * __restrict m, const cha
                         m->mime_prolog.iov_len = eb - eoh + 1;                          m->mime_prolog.iov_len = eb - eoh + 1;
                 }                  }
   
                   v = www_getAttribute(attr, "boundary");
                 m->mime_attach = mime_parseMultiPart(eb + 1, len - (eb + 1 - str),                   m->mime_attach = mime_parseMultiPart(eb + 1, len - (eb + 1 - str), 
                                www_getAttribute(attr, "boundary"), &eoh);                                AIT_GET_STR(v), &eoh);
   
                 /* set epilog if exists */                  /* set epilog if exists */
                 if (eoh - str < len) {                  if (eoh - str < len) {
                        m->mime_epilog.iov_base = malloc(len - (eoh - str) + 1);                        m->mime_epilog.iov_base = e_malloc(len - (eoh - str) + 1);
                         if (!m->mime_epilog.iov_base) {                          if (!m->mime_epilog.iov_base) {
                                LOGERR;                                www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                                 www_freeAttributes(&attr);                                  www_freeAttributes(&attr);
                                   freeHeader(m);
                                 return -1;                                  return -1;
                         }                          }
                         memcpy(m->mime_epilog.iov_base, str, len - (eoh - str));                          memcpy(m->mime_epilog.iov_base, str, len - (eoh - str));
Line 618  mime_readPart(struct tagMIME * __restrict m, const cha Line 641  mime_readPart(struct tagMIME * __restrict m, const cha
                         m->mime_epilog.iov_len = len - (eoh - str) + 1;                          m->mime_epilog.iov_len = len - (eoh - str) + 1;
   
                 }                  }
   
                   www_freeAttributes(&attr);
         }          }
   
         www_freeAttributes(&attr);  
         return 0;          return 0;
 }  }
   
Line 651  mime_calcRawSize(struct tagMIME * __restrict m) Line 675  mime_calcRawSize(struct tagMIME * __restrict m)
         if (!s)          if (!s)
                 return m->mime_body.iov_len;                  return m->mime_body.iov_len;
         /* strip whitespaces */          /* strip whitespaces */
        while (isspace(*s))        while (isspace((int) *s))
                 s++;                  s++;
         t = strchr(s, ';');          t = strchr(s, ';');
         len = t ? strlen(s) : t - s;          len = t ? strlen(s) : t - s;
Line 702  mime_getRawData(struct tagMIME * __restrict m, char *  Line 726  mime_getRawData(struct tagMIME * __restrict m, char * 
         }          }
   
         /* strip whitespaces */          /* strip whitespaces */
        while (isspace(*s))        while (isspace((int) *s))
                 s++;                  s++;
         t = strchr(s, ';');          t = strchr(s, ';');
         len = t ? strlen(s) : t - s;          len = t ? strlen(s) : t - s;

Removed from v.1.1.1.1.2.1  
changed lines
  Added in v.1.4.6.1


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>