httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r227276 - in /httpd/apreq/trunk: include/apreq_version.h library/parser_multipart.c
Date Wed, 03 Aug 2005 23:37:12 GMT
Author: joes
Date: Wed Aug  3 16:37:07 2005
New Revision: 227276

URL: http://svn.apache.org/viewcvs?rev=227276&view=rev
Log:
Allow the multipart parser to handle more than two levels of
depth in multipart parts.  This should allow the parser to 
be usable for handling generic email messages (eg. mod_smtpd).

Modified:
    httpd/apreq/trunk/include/apreq_version.h
    httpd/apreq/trunk/library/parser_multipart.c

Modified: httpd/apreq/trunk/include/apreq_version.h
URL: http://svn.apache.org/viewcvs/httpd/apreq/trunk/include/apreq_version.h?rev=227276&r1=227275&r2=227276&view=diff
==============================================================================
--- httpd/apreq/trunk/include/apreq_version.h (original)
+++ httpd/apreq/trunk/include/apreq_version.h Wed Aug  3 16:37:07 2005
@@ -61,7 +61,7 @@
 #define APREQ_MINOR_VERSION       1
 
 /** patch level */
-#define APREQ_PATCH_VERSION       4
+#define APREQ_PATCH_VERSION       5
 
 /** 
  *  This symbol is defined for internal, "development" copies of libapreq.

Modified: httpd/apreq/trunk/library/parser_multipart.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/trunk/library/parser_multipart.c?rev=227276&r1=227275&r2=227276&view=diff
==============================================================================
--- httpd/apreq/trunk/library/parser_multipart.c (original)
+++ httpd/apreq/trunk/library/parser_multipart.c Wed Aug  3 16:37:07 2005
@@ -42,7 +42,7 @@
     apr_bucket_brigade          *in;
     apr_bucket_brigade          *bb;
     apreq_parser_t              *hdr_parser;
-    apreq_parser_t              *mix_parser;
+    apreq_parser_t              *next_parser;
     const apr_strmatch_pattern  *pattern;
     char                        *bdry;
     enum {
@@ -57,7 +57,7 @@
         MFD_ERROR 
     }                            status;
     apr_bucket                  *eos;
-    char                        *param_name;
+    const char                  *param_name;
     apreq_param_t               *upload;
 };
 
@@ -238,7 +238,7 @@
     ctx->bb = apr_brigade_create(pool, ba);
     ctx->in = apr_brigade_create(pool, ba);
     ctx->eos = apr_bucket_eos_create(ba);
-    ctx->mix_parser = NULL;
+    ctx->next_parser = NULL;
     ctx->param_name = NULL;
     ctx->upload = NULL;
 
@@ -261,12 +261,6 @@
             return APREQ_ERROR_GENERAL;
 
 
-        ctx->mix_parser = apreq_parser_make(pool, ba, "", 
-                                            apreq_parse_multipart,
-                                            parser->brigade_limit,
-                                            parser->temp_dir,
-                                            parser->hook,
-                                            NULL);
         parser->ctx = ctx;
     }
 
@@ -339,21 +333,21 @@
 
     case MFD_POST_HEADER:
         {
-            /* Must handle special case of missing CRLF (mainly
-               coming from empty file uploads). See RFC2065 S5.1.1:
-
-                 body-part = MIME-part-header [CRLF *OCTET]
-
-               So the CRLF we already matched in MFD_HEADER may have been 
-               part of the boundary string! Both Konqueror (v??) and 
-               Mozilla-0.97 are known to emit such blocks.
-
-               Here we first check for this condition with 
-               brigade_start_string, and prefix the brigade with
-               an additional CRLF bucket if necessary.
-            */
+            /*  Must handle special case of missing CRLF (mainly
+             *  coming from empty file uploads). See RFC2065 S5.1.1:
+             *
+             *    body-part = MIME-part-header [CRLF *OCTET]
+             *
+             *  So the CRLF we already matched in MFD_HEADER may have been 
+             *  part of the boundary string! Both Konqueror (v??) and 
+             *  Mozilla-0.97 are known to emit such blocks.
+             *
+             *  Here we first check for this condition with 
+             *  brigade_start_string, and prefix the brigade with
+             *  an additional CRLF bucket if necessary.
+             */
 
-            const char *cd, *name, *filename;
+            const char *cd, *ct, *name, *filename;
             apr_size_t nlen, flen;
             apr_bucket *e;
 
@@ -367,7 +361,7 @@
                 /* part has no body- return CRLF to front */
                 e = apr_bucket_immortal_create(CRLF, 2,
                                                 ctx->bb->bucket_alloc);
-                APR_BRIGADE_INSERT_HEAD(ctx->in,e);
+                APR_BRIGADE_INSERT_HEAD(ctx->in, e);
                 break;
 
             default:
@@ -376,90 +370,116 @@
 
             cd = apr_table_get(ctx->info, "Content-Disposition");
 
-            if (cd != NULL) {
+            /*  First check to see if must descend into a new multipart block.
+             *  If we do, create a new parser and pass control to it, running
+             *  the current-scope hooks on any reject data.
+             */
 
-                if (ctx->mix_parser != NULL) {
-                    /* multipart/form-data */
+            ct = apr_table_get(ctx->info, "Content-Type");
 
-                    s = apreq_header_attribute(cd, "name", 4, &name, &nlen);
-                    if (s != APR_SUCCESS) {
-                        ctx->status = MFD_ERROR;
-                        return APREQ_ERROR_GENERAL;
-                    }
+            if (ct != NULL && strncmp(ct, "multipart/", 10) == 0) {
+                struct mfd_ctx *next_ctx;
 
-                    s = apreq_header_attribute(cd, "filename", 
-                                               8, &filename, &flen);
-                    if (s != APR_SUCCESS) {
-                        const char *ct = apr_table_get(ctx->info, 
-                                                       "Content-Type");
-                        if (ct != NULL 
-                            && strncmp(ct, "multipart/mixed", 15) == 0)
-                        {
-                            struct mfd_ctx *mix_ctx;
-                            mix_ctx = create_multipart_context(ct, pool, ba,
-                                                               parser->brigade_limit,
-                                                               parser->temp_dir);
-                            if (mix_ctx == NULL) {
-                                ctx->status = MFD_ERROR;
-                                return APREQ_ERROR_GENERAL;
-                            }
-                            mix_ctx->param_name = apr_pstrmemdup(pool,
-                                                                 name, nlen);
-                            ctx->mix_parser->ctx = mix_ctx;
-                            ctx->status = MFD_MIXED;
-                            goto mfd_parse_brigade;
-                        }
-                        ctx->param_name = apr_pstrmemdup(pool, name, nlen);
-                        ctx->status = MFD_PARAM;
+                next_ctx = create_multipart_context(ct, pool, ba,
+                                                    parser->brigade_limit,
+                                                    parser->temp_dir);
+
+                next_ctx->param_name = "";
+
+                if (cd != NULL) {
+                    s = apreq_header_attribute(cd, "name", 4, &name, &nlen);
+                    if (s == APR_SUCCESS) {
+                        next_ctx->param_name 
+                            = apr_pstrmemdup(pool, name, nlen);
                     }
                     else {
-                        apreq_param_t *param;
+                        const char *cid = apr_table_get(ctx->info,
+                                                        "Content-ID");
+                        if (cid != NULL)
+                            next_ctx->param_name = apr_pstrdup(pool, cid);
+                    }
 
-                        param = apreq_param_make(pool, name, nlen, 
-                                                 filename, flen);
-                        apreq_param_tainted_on(param);
-                        param->info = ctx->info;
-                        param->upload = apr_brigade_create(pool, 
-                                                       ctx->bb->bucket_alloc);
-                        ctx->upload = param;
-                        ctx->status = MFD_UPLOAD;
-                        goto mfd_parse_brigade;
+                }
 
-                    }
+                ctx->next_parser = apreq_parser_make(pool, ba, ct, 
+                                                     apreq_parse_multipart,
+                                                     parser->brigade_limit,
+                                                     parser->temp_dir,
+                                                     parser->hook,
+                                                     next_ctx);
+                ctx->status = MFD_MIXED;
+                goto mfd_parse_brigade;
+
+            }
+
+            /* Look for a normal form-data part. */
+
+            if (cd != NULL && strncmp(cd, "form-data", 9) == 0) {
+                s = apreq_header_attribute(cd, "name", 4, &name, &nlen);
+                if (s != APR_SUCCESS) {
+                    ctx->status = MFD_ERROR;
+                    goto mfd_parse_brigade;
                 }
-                else {
-                    /* multipart/mixed */
-                    s = apreq_header_attribute(cd, "filename", 
-                                               8, &filename, &flen);
-                    if (s != APR_SUCCESS) {
-                        ctx->status = MFD_PARAM;
-                    }
-                    else {
-                        apreq_param_t *param;
-                        name = ctx->param_name;
-                        nlen = strlen(name);
-                        param = apreq_param_make(pool, name, nlen, 
-                                                 filename, flen);
-                        apreq_param_tainted_on(param);
-                        param->info = ctx->info;
-                        param->upload = apr_brigade_create(pool, 
+
+                s = apreq_header_attribute(cd, "filename", 
+                                           8, &filename, &flen);
+                if (s == APR_SUCCESS) {
+                    apreq_param_t *param;
+
+                    param = apreq_param_make(pool, name, nlen, 
+                                             filename, flen);
+                    apreq_param_tainted_on(param);
+                    param->info = ctx->info;
+                    param->upload = apr_brigade_create(pool, 
                                                        ctx->bb->bucket_alloc);
-                        ctx->upload = param;
-                        ctx->status = MFD_UPLOAD;
-                        goto mfd_parse_brigade;
-                    }
+                    ctx->upload = param;
+                    ctx->status = MFD_UPLOAD;
+                    goto mfd_parse_brigade;
+                }
+                else {
+                    ctx->param_name = apr_pstrmemdup(pool, name, nlen);
+                    ctx->status = MFD_PARAM;
+                    /* fall thru */
                 }
             }
-            else {
-                /* multipart/related */
+
+            /* else check for a file part in a multipart section */
+            else if (cd != NULL && strncmp(cd, "file", 4) == 0) {
                 apreq_param_t *param;
-                cd = apr_table_get(ctx->info, "Content-ID");
-                if (cd == NULL) {
+
+                s = apreq_header_attribute(cd, "filename", 
+                                           8, &filename, &flen);
+                if (s != APR_SUCCESS || ctx->param_name == NULL) {
                     ctx->status = MFD_ERROR;
-                    return APREQ_ERROR_GENERAL;
+                    goto mfd_parse_brigade;
                 }
-                name = cd;
+                name = ctx->param_name;
                 nlen = strlen(name);
+                param = apreq_param_make(pool, name, nlen, 
+                                         filename, flen);
+                apreq_param_tainted_on(param);
+                param->info = ctx->info;
+                param->upload = apr_brigade_create(pool, 
+                                                   ctx->bb->bucket_alloc);
+                ctx->upload = param;
+                ctx->status = MFD_UPLOAD;
+                goto mfd_parse_brigade;
+            }
+
+            /* otherwise look for Content-ID in case it's multipart/mixed */
+            else {
+                const char *cid = apr_table_get(ctx->info, "Content-ID");
+                apreq_param_t *param;
+
+                if (cid != NULL) {
+                    name = cid;
+                    nlen = strlen(name);
+                }
+                else {
+                    name = "";
+                    nlen = 0;
+                }
+
                 filename = "";
                 flen = 0;
                 param = apreq_param_make(pool, name, nlen, 
@@ -472,7 +492,6 @@
                 ctx->status = MFD_UPLOAD;
                 goto mfd_parse_brigade;
             }
-
         }
         /* fall through */
 
@@ -584,13 +603,14 @@
 
     case MFD_MIXED:
         {
-            s = apreq_parser_run(ctx->mix_parser, t, ctx->in);
+            s = apreq_parser_run(ctx->next_parser, t, ctx->in);
             switch (s) {
             case APR_SUCCESS:
                 ctx->status = MFD_INIT;
+                ctx->param_name = NULL;
                 goto mfd_parse_brigade;
             case APR_INCOMPLETE:
-                apr_brigade_cleanup(ctx->in);
+                APR_BRIGADE_CONCAT(bb, ctx->in);
                 return APR_INCOMPLETE;
             default:
                 ctx->status = MFD_ERROR;



Mime
View raw message