Diff for /libaitwww/src/mime.c between versions 1.2 and 1.5

version 1.2, 2012/03/10 00:26:49 version 1.5, 2013/05/30 09:25:35
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 header format of MIME part");                        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 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 */          /* 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, "--"));
Line 373  mime_parseMultiPart(const char *str, size_t len, const Line 377  mime_parseMultiPart(const char *str, size_t len, const
         }          }
   
         while (len > 0) {          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 391  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 420  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;
         */          */
   
        free(bd[1].iov_base);        e_free(bd[1].iov_base);
        free(bd[0].iov_base);        e_free(bd[0].iov_base);
   
         if (end)          if (end)
                 *end = str;                  *end = str;
Line 432  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 459  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 496  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) {                  if (!c->cgi_value) {
Line 546  mime_parseHeader(struct tagMIME * __restrict m, const  Line 548  mime_parseHeader(struct tagMIME * __restrict m, const 
  * @name = Header name   * @name = Header name
  * return: NULL not found or !=NULL value   * return: NULL not found or !=NULL value
  */   */
inline const char *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 (!strcasecmp(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 574  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 || (ssize_t) len < 0) {          if (!m || !str || (ssize_t) len < 0) {
                 www_SetErr(EINVAL, "Mime part, string is NULL or length is less 0");                  www_SetErr(EINVAL, "Mime part, string is NULL or length is less 0");
Line 586  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) {                  if (!m->mime_body.iov_base) {
                        LOGERR;                        www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                         freeHeader(m);                          freeHeader(m);
                         return -1;                          return -1;
                 }                  }
Line 602  mime_readPart(struct tagMIME * __restrict m, const cha Line 603  mime_readPart(struct tagMIME * __restrict m, const cha
                         freeHeader(m);                          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);                                  freeHeader(m);
                                 return -1;                                  return -1;
Line 621  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);                                  freeHeader(m);
                                 return -1;                                  return -1;
Line 672  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 723  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.2  
changed lines
  Added in v.1.5


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