httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject cvs commit: httpd-apreq-2/t parsers.c
Date Mon, 13 Sep 2004 07:04:03 GMT
joes        2004/09/13 00:04:02

  Modified:    .        CHANGES STATUS
               src      apreq_env.c apreq_params.h apreq_parsers.c
                        apreq_version.h
               t        parsers.c
  Log:
  Add apreq_register_parser(), which allows users to add their own parsers to apreq_parser()'s
recognized MIME types.  Also add some memory-management todos in STATUS
  
  Revision  Changes    Path
  1.68      +4 -0      httpd-apreq-2/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/CHANGES,v
  retrieving revision 1.67
  retrieving revision 1.68
  diff -u -r1.67 -r1.68
  --- CHANGES	12 Sep 2004 06:16:43 -0000	1.67
  +++ CHANGES	13 Sep 2004 07:04:02 -0000	1.68
  @@ -6,6 +6,10 @@
   
   
   - C API [joes]
  +  Add apreq_register_parser(), which allows users to add
  +  their own parsers to apreq_parser()'s recognized MIME types.
  +
  +- C API [joes]
     Support "multipart/mixed" file uploads.
     Support XForms' "multipart/related" enctype.
   
  
  
  
  1.85      +12 -1     httpd-apreq-2/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/STATUS,v
  retrieving revision 1.84
  retrieving revision 1.85
  diff -u -r1.84 -r1.85
  --- STATUS	12 Sep 2004 03:04:12 -0000	1.84
  +++ STATUS	13 Sep 2004 07:04:02 -0000	1.85
  @@ -40,6 +40,17 @@
   
   TODO:
   
  +    - Move the xs generation code into buildconf (instead of configure),
  +      and fix glue/perl/Makefile.PL to clean the ./xs dir instead of 
  +      removing it entirely.  % make release will also need fixing
  +      to pick up the xs directory.
  +
  +    - There are too many calls to apreq_env_pool()- lots of these
  +      can be eliminated by caching the pool in the parser's context.
  +
  +    - Add apreq_env_bucket_alloc(env) function to get a per-request 
  +      bucket allocator, which will help the parsers to conserve memory.
  +
       - in glue/perl/t/apreq/cgi.t on Win32, printing to the error log
         hangs if the strings involved are about 10000 in size.
         This doesn't occur in the env/cgi tests - why?
  
  
  
  1.19      +5 -2      httpd-apreq-2/src/apreq_env.c
  
  Index: apreq_env.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_env.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- apreq_env.c	31 Jul 2004 23:56:40 -0000	1.18
  +++ apreq_env.c	13 Sep 2004 07:04:02 -0000	1.19
  @@ -23,9 +23,12 @@
   
   
   static const apreq_env_t *apreq_env;
  +extern void apreq_parser_initialize(void);
  +
   
   APREQ_DECLARE(const apreq_env_t *) apreq_env_module(const apreq_env_t *mod)
   {
  +    apreq_parser_initialize();
       if (mod != NULL) {
           const apreq_env_t *old_mod = apreq_env;
           apreq_env = mod;
  @@ -142,7 +145,7 @@
   
   
   #define APREQ_MODULE_NAME         "CGI"
  -#define APREQ_MODULE_MAGIC_NUMBER 20040731
  +#define APREQ_MODULE_MAGIC_NUMBER 20040913
   
   static apr_pool_t *cgi_pool(void *env)
   {
  @@ -210,7 +213,7 @@
   static apreq_request_t *cgi_request(void *env,
                                       apreq_request_t *req)
   {
  -
  +    apreq_parser_initialize();
       if (req != NULL) {
           apreq_request_t *old_req = ctx.req;
           ctx.req = req;
  
  
  
  1.41      +23 -3     httpd-apreq-2/src/apreq_params.h
  
  Index: apreq_params.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.h,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- apreq_params.h	12 Sep 2004 19:21:32 -0000	1.40
  +++ apreq_params.h	13 Sep 2004 07:04:02 -0000	1.41
  @@ -273,6 +273,8 @@
   };
   
   
  +
  +
   /**
    * Parse the incoming brigade into a table.  Parsers normally
    * consume all the buckets of the brigade during parsing. However
  @@ -389,22 +391,40 @@
   APREQ_DECLARE(void) apreq_add_hook(apreq_parser_t *p, 
                                      apreq_hook_t *h);
   
  +
   /**
    * Create the default parser associated with the
    * current request's Content-Type (if possible).
    * @param env The current environment.
    * @param hook Hook(s) to add to the parser.
    * @return New parser, NULL if the Content-Type is
  - * unrecognized.  apreq_parser() currently recognizes
  - * APREQ_URL_ENCTYPE and APREQ_MFD_ENCTYPE.
  + * unrecognized.
    *
    * @param env The current environment.
    * @param hook Additional hooks to supply the parser with.
  - * @return The built-in parser; NULL if the environment's
  + * @return The parser; NULL if the environment's
    * Content-Type is unrecognized.
    */
   APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env,
                                               apreq_hook_t *hook);
  +
  +
  +/**
  + * Register a new parsing function with a MIME enctype.
  + * Registered parsers are added to apreq_parser()'s
  + * internal lookup table.
  + *
  + * @param enctype The MIME type.
  + * @param parser  The function to use during parsing. Setting
  + *                parser == NULL will remove an existing parser.
  + * @remark This is not a thread-safe operation, so applications 
  + * should only call this during process startup,
  + * or within a request-thread mutex.
  + */
  +
  +APREQ_DECLARE(void) apreq_register_parser(const char *enctype, 
  +                            apr_status_t (*parser) (APREQ_PARSER_ARGS));
  +
   
   /**
    * Returns APR_EGENERAL.  Effectively disables mfd parser
  
  
  
  1.66      +47 -11    httpd-apreq-2/src/apreq_parsers.c
  
  Index: apreq_parsers.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
  retrieving revision 1.65
  retrieving revision 1.66
  diff -u -r1.65 -r1.66
  --- apreq_parsers.c	12 Sep 2004 19:21:32 -0000	1.65
  +++ apreq_parsers.c	13 Sep 2004 07:04:02 -0000	1.66
  @@ -20,6 +20,9 @@
   #include "apr_strings.h"
   #include "apr_strmatch.h"
   #include "apr_xml.h"
  +#include "apr_hash.h"
  +
  +void apreq_parser_initialize(void);
   
   #ifndef MAX
   #define MAX(A,B)  ( (A) > (B) ? (A) : (B) )
  @@ -83,27 +86,60 @@
       p->hook = h;
   }
   
  +static apr_hash_t *default_parsers;
  +static apr_pool_t *default_parser_pool;
  +
  +void apreq_parser_initialize(void)
  +{
  +    if (default_parsers != NULL)
  +        return;
  +    apr_pool_create(&default_parser_pool, NULL);
  +    default_parsers = apr_hash_make(default_parser_pool);
  +
  +    apreq_register_parser("application/x-www-form-urlencoded",
  +                          apreq_parse_urlencoded);
  +    apreq_register_parser("multipart/form-data", apreq_parse_multipart);
  +    apreq_register_parser("multipart/related", apreq_parse_multipart);
  +}
  +
  +struct apreq_parser_fcn {
  +    apr_status_t (*parser) (APREQ_PARSER_ARGS);
  +};
  +
  +APREQ_DECLARE(void) apreq_register_parser(const char *enctype, 
  +                                    apr_status_t (*parser) (APREQ_PARSER_ARGS))
  +{
  +    struct apreq_parser_fcn *f = NULL;
  +    apreq_parser_initialize();
  +    if (parser != NULL) {
  +        f = apr_palloc(default_parser_pool, sizeof *f);
  +        f->parser = parser;
  +    }
  +    apr_hash_set(default_parsers, apr_pstrdup(default_parser_pool, enctype),
  +                 APR_HASH_KEY_STRING, f);
  +
  +}
  +
   APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env, apreq_hook_t *hook)
   {
       apr_pool_t *pool = apreq_env_pool(env);
       const char *type = apreq_env_content_type(env);
  +    apr_ssize_t tlen;
  +    struct apreq_parser_fcn *f;
   
  -    if (type == NULL)
  +    if (type == NULL || default_parsers == NULL)
           return NULL;
   
  -    if (!strncasecmp(type, APREQ_URL_ENCTYPE,strlen(APREQ_URL_ENCTYPE)))
  -        return apreq_make_parser(pool, type, 
  -                                 apreq_parse_urlencoded, hook, NULL);
  -
  -    else if (!strncasecmp(type,APREQ_MFD_ENCTYPE,strlen(APREQ_MFD_ENCTYPE))
  -             || strncasecmp(type,  "multipart/related", 
  -                            strlen("multipart/related")))
  -        return apreq_make_parser(pool, type, 
  -                                 apreq_parse_multipart, hook, NULL);
  +    tlen = 0;
  +    while(type[tlen] && type[tlen] != ';')
  +        ++tlen;
  +
  +    f = apr_hash_get(default_parsers, type, tlen);
   
  +    if (f != NULL)
  +        return apreq_make_parser(pool, type, f->parser, hook, NULL);
       else
           return NULL;
  -
   }
   
   
  
  
  
  1.26      +1 -1      httpd-apreq-2/src/apreq_version.h
  
  Index: apreq_version.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_version.h,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- apreq_version.h	12 Sep 2004 06:16:43 -0000	1.25
  +++ apreq_version.h	13 Sep 2004 07:04:02 -0000	1.26
  @@ -61,7 +61,7 @@
   #define APREQ_MINOR_VERSION       0
   
   /** patch level */
  -#define APREQ_PATCH_VERSION      21
  +#define APREQ_PATCH_VERSION      22
   
   /** 
    *  This symbol is defined for internal, "development" copies of libapreq.
  
  
  
  1.25      +31 -0     httpd-apreq-2/t/parsers.c
  
  Index: parsers.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/t/parsers.c,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- parsers.c	12 Sep 2004 19:21:33 -0000	1.24
  +++ parsers.c	13 Sep 2004 07:04:02 -0000	1.25
  @@ -102,6 +102,36 @@
   extern apr_bucket_brigade *bb;
   extern apr_table_t *table;
   
  +static void locate_default_parsers(CuTest *tc)
  +{
  +    apreq_request_t *req;
  +    apreq_parser_t *parser;
  +
  +    req = apreq_request("application/x-www-form-urlencoded", "");
  +    CuAssertPtrNotNull(tc, req);
  +    CuAssertStrEquals(tc, APREQ_URL_ENCTYPE, apreq_enctype(req->env));
  +    parser = apreq_parser(req->env, NULL);
  +    CuAssertPtrNotNull(tc, parser);
  +    CuAssertStrEquals(tc, APREQ_URL_ENCTYPE, parser->enctype);
  +
  +    req = apreq_request(APREQ_MFD_ENCTYPE
  +                        "; charset=\"iso-8859-1\"; boundary=\"AaB03x\"" ,"");
  +    CuAssertPtrNotNull(tc, req);
  +    parser = apreq_parser(req->env, NULL);
  +    CuAssertPtrNotNull(tc, parser);
  +    CuAssertStrNEquals(tc, APREQ_MFD_ENCTYPE, parser->enctype, 
  +                       strlen(APREQ_MFD_ENCTYPE));
  +
  +    req = apreq_request("multipart/related; boundary=f93dcbA3; "
  +        "type=application/xml; start=\"<980119.X53GGT@example.com>\"","");
  +    CuAssertPtrNotNull(tc, req);
  +    parser = apreq_parser(req->env, NULL);
  +    CuAssertPtrNotNull(tc, parser);
  +    CuAssertStrNEquals(tc, "multipart/related", parser->enctype, 
  +                       strlen("multipart/related"));
  +}
  +
  +
   static void parse_urlencoded(CuTest *tc)
   {
       const char *val;
  @@ -440,6 +470,7 @@
   CuSuite *testparser(void)
   {
       CuSuite *suite = CuSuiteNew("Parsers");
  +    SUITE_ADD_TEST(suite, locate_default_parsers);
       SUITE_ADD_TEST(suite, parse_urlencoded);
       SUITE_ADD_TEST(suite, parse_multipart);
       SUITE_ADD_TEST(suite, parse_disable_uploads);
  
  
  

Mime
View raw message