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 Sun, 27 Jun 2004 18:07:35 GMT
joes        2004/06/27 11:07:35

  Modified:    glue/perl/xsbuilder/Apache/Request Request_pm Request_pod
               glue/perl/xsbuilder/Apache/Upload Apache__Upload.h
               glue/perl/xsbuilder/maps apreq_functions.map
               src      apreq_params.h apreq_parsers.c
               t        parsers.c
  Log:
  Implement apreq_hook_disable_uploads, and start work (still unimplemented) on perl glue
implementation of DISABLE_UPLOADS, HOOK_DATA and UPLOAD_HOOK.
  
  Revision  Changes    Path
  1.13      +0 -2      httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Request_pm
  
  Index: Request_pm
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Request_pm,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Request_pm	26 Jun 2004 20:30:40 -0000	1.12
  +++ Request_pm	27 Jun 2004 18:07:35 -0000	1.13
  @@ -1,6 +1,4 @@
   use APR::Table;
  -use APR::Bucket;
  -use APR::Brigade;
   
   package Apache::Request::Table;
   push our(@ISA), "APR::Table";
  
  
  
  1.14      +33 -16    httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Request_pod
  
  Index: Request_pod
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Request_pod,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- Request_pod	26 Jun 2004 20:30:40 -0000	1.13
  +++ Request_pod	27 Jun 2004 18:07:35 -0000	1.14
  @@ -24,20 +24,20 @@
   object as (second) argument.  Newer versions of CGI.pm also accept
   this syntax within modperl.
   
  -=item * The query parameters are stored as Apache::Table objects,
  +=item * The query parameters are stored in APR::Table derived objects,
   and are therefore parsed using case-insensitive keys.
   
  -=item * The query string is always parsed, even for POST requests.
  +=item * The query string is always parsed first, even for POST requests.
   
   =back
   
   =head2 new  
   
  -creates a new I<Apache::Request> object with an environment object $r:
  +creates a new C<Apache::Request> object with an environment object $r:
   
       my $req = Apache::Request->new($r);
   
  -With mod_perl2, the environment object must be an I<Apache::RequestRec>
  +With mod_perl2, the environment object must be an C<Apache::RequestRec>
   object.  All methods from the environment class are inherited.
   
   The following attributes are optional:
  @@ -58,16 +58,19 @@
   that supports link(2), the TEMP_DIR should be located on the same
   file system as the final destination file:
   
  + use Apache::Upload;
    my $req = Apache::Request->new($r, TEMP_DIR => "/home/httpd/tmp");
    my $upload = $req->upload('file');
    $upload->link("/home/user/myfile") || warn "link failed: $!";
   
  -=item HOOK_DATA [TODO]
  +For more details on C<link>, see the L<Apache:Upload> manpage.
  +
  +=item HOOK_DATA (requires L<Apache::Upload>)
   
   Extra configuration info passed to an upload hook.
  -See the description for the next item, I<UPLOAD_HOOK>.
  +See the description for the next item, C<UPLOAD_HOOK>.
   
  -=item UPLOAD_HOOK (requires Apache::Upload) [TODO]
  +=item UPLOAD_HOOK (requires L<Apache::Upload>)
   
   Sets up a callback to run whenever file upload data is read. This
   can be used to provide an upload progress meter during file uploads.
  @@ -75,7 +78,7 @@
   $upload->fh after the hook exits.
   
    my $transparent_hook = sub {
  -   my ($upload, $bb, $hook_data, $next_hook) = @_;
  +   my ($upload, $data, $hook_data) = @_;
      warn "$hook_data: got $len bytes for " . $upload->name;
    };
   
  @@ -86,7 +89,7 @@
   
   =back
   
  -=head2 instance [DEPRECATED]
  +=head2 C<instance> [DEPRECATED]
   
   The default (and only) behavior of I<Apache::Request> is to intelligently
   cache B<POST> data for the duration of the request.  Thus there is no longer
  @@ -97,21 +100,35 @@
   However an C<instance()> method is aliased to C<new()> in this release
   to ease the pain of porting from 1.X to 2.X.
   
  -=head2 param
  +=head2 C<param>
   
  -Get or set (TODO) the request parameters (using case-insensitive keys) by
  -mimicing the OO interface of C<CGI::param>.  WIth a single
  +Get the request parameters (using case-insensitive keys) by
  +mimicing the OO interface of C<CGI::param>.
   
       # similar to CGI.pm
   
  -    my $value = $req->param('foo');
  -    my @values = $req->param('foo');
  -    my @params = $req->param;
  +    my $foo_value   = $req->param('foo');
  +    my @foo_values  = $req->param('foo');
  +    my @param_names = $req->param;
   
       # the following differ slightly from CGI.pm
   
  -    # returns ref to APR::Table object representing all (args + body) params
  +    # returns ref to Apache::Request::Table object representing 
  +    # all (args + body) params
       my $table = $req->param;
  +
  +In list context, or when invoked with a single argument, 
  +C<param> always induces libapreq2 to read and parse all 
  +remaining data in the request body.  However, C<scalar $req->param("foo")> 
  +is lazy: libapreq2 will only read=parse more data if
  +
  +    1) no "foo" param appears in the query string arguments, AND
  +    2) no "foo" param appears in the previously parsed POST data.
  +
  +In this circumstance libapreq2 will read and parse additional
  +blocks of the incoming request body until it has found the
  +the "foo" param.
  +
   
   =head2 parms, params [DEPRECATED]
   
  
  
  
  1.5       +114 -0    httpd-apreq-2/glue/perl/xsbuilder/Apache/Upload/Apache__Upload.h
  
  Index: Apache__Upload.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Upload/Apache__Upload.h,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Apache__Upload.h	26 Jun 2004 21:35:11 -0000	1.4
  +++ Apache__Upload.h	27 Jun 2004 18:07:35 -0000	1.5
  @@ -310,3 +310,117 @@
       ST(0) = f2g(aTHX_ file, bb->p, APR_PERLIO_HOOK_READ);
       XSRETURN(1);
   }
  +
  +struct hook_ctx {
  +    SV                  *hook_data;
  +    SV                  *hook;
  +    SV                  *upload;
  +    SV                  *bucket_data;
  +    PerlInterpreter     *perl;
  +};
  +
  +#ifdef IMPLEMENT_UPLOAD_HOOKS
  +
  +#define DEREF(slot) if (ctx->slot) SvREFCNT_dec(ctx->slot)
  +
  +static void upload_hook_cleanup(void *ctx_)
  +{
  +    struct hook_ctx *ctx = ctx_;
  +
  +#ifdef USE_ITHREADS
  +    dTHXa(ctx->perl);
  +#endif
  +
  +    DEREF(hook_data);
  +    DEREF(hook);
  +    DEREF(upload);
  +    DEREF(bucket_data);
  +}
  +
  +
  +APR_INLINE
  +static void eval_upload_hook(pTHX_ SV *hook, SV* upload, 
  +                             SV *bucket_data, SV* hook_data)
  +{
  +    dSP;
  +
  +    PUSHMARK(SP);
  +    EXTEND(SP, 3);
  +    ENTER;
  +    SAVETMPS;
  +
  +    PUSHs(upload);
  +    PUSHs(bucket_data);
  +    PUSHs(hook_data);
  +
  +    PUTBACK;
  +    perl_call_sv(hook, G_EVAL|G_DISCARD);
  +    FREETMPS;
  +    LEAVE;
  +}
  +
  +
  +static
  +APREQ_DECLARE_HOOK(apreq_xs_hook_wrapper)
  +{
  +    struct hook_ctx *ctx = hook->ctx; /* set ctx during config */
  +    apr_bucket *e;
  +    apr_status_t s = APR_SUCCESS;
  +
  +#ifdef USE_ITHREADS
  +    dTHXa(ctx->perl);
  +#endif
  +
  +    if (hook->next) {
  +        s = APREQ_RUN_HOOK(hook->next, env, param, bb);
  +        if (s != APR_SUCCESS)
  +            return s;
  +    }
  +
  +    for (e = APR_BRIGADE_FIRST(bb); e!= APR_BRIGADE_SENTINEL(bb);
  +         e = APR_BUCKET_NEXT(e))
  +    {
  +        apr_off_t len;
  +        const char *data;
  +
  +        if (APR_BUCKET_IS_EOS(e)) {
  +            /*last call */
  +            eval_upload_hook(aTHX_ ctx->hook, ctx->upload, 
  +                             &PL_sv_undef, ctx->hook_data);
  +
  +            if (SvTRUE(ERRSV)) {
  +                /*XXX: handle error */
  +                s = APR_EGENERAL;
  +            }
  +
  +            break;
  +        }
  +
  +        s = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
  +        if (s != APR_SUCCESS)
  +            break;
  +
  +        SvPVX(ctx->bucket_data) = (char *)data;
  +        SvCUR(ctx->bucket_data) = (STRLEN)len;
  +
  +        eval_upload_hook(aTHX_ ctx->hook, ctx->upload, ctx->bucket_data, 
  +                         ctx->hook_data);
  +
  +        if (SvTRUE(ERRSV)) {
  +            /*XXX: handle error */
  +            s = APR_EGENERAL;
  +            break;
  +        }
  +
  +    }
  +
  +    return s;
  +}
  +
  +static XS(apreq_xs_upload_hook)
  +{
  +    /*this needs to initialize hook_ctx (bucket_data must be CONSTANT with LEN=-1)*/
  +
  +}
  +
  +#endif
  
  
  
  1.21      +0 -2      httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_functions.map
  
  Index: apreq_functions.map
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_functions.map,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- apreq_functions.map	26 Jun 2004 21:35:11 -0000	1.20
  +++ apreq_functions.map	27 Jun 2004 18:07:35 -0000	1.21
  @@ -2,8 +2,6 @@
   
   MODULE=Apache::Request PACKAGE=Apache::Request PREFIX=apreq_
    apreq_request | apreq_xs_request | const char *:class, void *:env, const char *:qs=NULL
  -! apreq_parse_request
  -! apreq_params
    apreq_param | apreq_xs_request_get |
   
   MODULE=Apache::Request PACKAGE=Apache::Request
  
  
  
  1.33      +6 -0      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.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- apreq_params.h	23 Jun 2004 02:22:28 -0000	1.32
  +++ apreq_params.h	27 Jun 2004 18:07:35 -0000	1.33
  @@ -380,6 +380,12 @@
   APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env,
                                               apreq_hook_t *hook);
   
  +/**
  + * Returns APR_EGENERAL.  Effectively disables mfd parser
  + * if a file-upload field is present.
  + *
  + */
  +APREQ_DECLARE_HOOK(apreq_hook_disable_uploads);
   #ifdef __cplusplus
   }
   #endif
  
  
  
  1.51      +25 -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.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- apreq_parsers.c	26 Jun 2004 01:36:24 -0000	1.50
  +++ apreq_parsers.c	27 Jun 2004 18:07:35 -0000	1.51
  @@ -976,13 +976,19 @@
                   ctx->status = MFD_PARAM;
               } 
               else {
  +                apr_array_header_t *arr;
  +                apr_table_entry_t e = {NULL};
                   apreq_param_t *param = apreq_make_param(pool, name, nlen, 
                                                           filename, flen);
                   param->info = ctx->info;
                   param->bb = apr_brigade_create(pool, 
                                                  apr_bucket_alloc_create(pool));
                   param->v.status = APR_INCOMPLETE;
  -                apr_table_addn(t, param->v.name, param->v.data);
  +                arr = (apr_array_header_t *)apr_table_elts(t);
  +                e.key = (char *)param->v.name;
  +                e.val = param->v.data;
  +                *(apr_table_entry_t *)(apr_array_push(arr)) = e;
  +                arr->nelts--;
                   ctx->status = MFD_UPLOAD;
                   goto mfd_parse_brigade;
               }
  @@ -1045,21 +1051,23 @@
       case MFD_UPLOAD:
           {
               apreq_param_t *param;
  -            const apr_array_header_t *arr;
  +            apr_array_header_t *arr;
               apr_table_entry_t *e;
   
               s = split_on_bdry(ctx->bb, ctx->in, ctx->pattern, ctx->bdry);
  -            arr = apr_table_elts(t);
  +            arr = (apr_array_header_t *)apr_table_elts(t);
               e = (apr_table_entry_t *)arr->elts;
  -            param = apreq_value_to_param(apreq_strtoval(e[arr->nelts-1].val));
  +            param = apreq_value_to_param(apreq_strtoval(e[arr->nelts].val));
   
               switch (s) {
   
               case APR_INCOMPLETE:
                   if (parser->hook) {
                       s = APREQ_RUN_HOOK(parser->hook, env, param, ctx->bb);
  -                    if (s != APR_INCOMPLETE && s != APR_SUCCESS)
  +                    if (s != APR_INCOMPLETE && s != APR_SUCCESS) {
  +                        ctx->status = MFD_ERROR;
                           return s;
  +                    }
                   }
                   APREQ_BRIGADE_SETASIDE(ctx->bb, pool);
                   APREQ_BRIGADE_SETASIDE(ctx->in, pool);
  @@ -1072,16 +1080,17 @@
                       APR_BRIGADE_INSERT_TAIL(ctx->bb, eos);
                       s = APREQ_RUN_HOOK(parser->hook, env, param, ctx->bb);
                       apr_bucket_delete(eos);
  -                    if (s != APR_SUCCESS)
  +                    if (s != APR_SUCCESS) {
  +                        ctx->status = MFD_ERROR;
                           return s;
  +                    }
                   }
  -
  +                apr_table_addn(t, param->v.name, param->v.data);
                   APREQ_BRIGADE_SETASIDE(ctx->bb, pool);
  -                param->v.status = apreq_brigade_concat(env,
  -                                                       param->bb, ctx->bb);
  +                s = apreq_brigade_concat(env, param->bb, ctx->bb);
   
  -                if (param->v.status != APR_SUCCESS)
  -                    return param->v.status;
  +                if (s != APR_SUCCESS)
  +                    return s;
   
                   ctx->status = MFD_NEXTLINE;
                   goto mfd_parse_brigade;
  @@ -1099,4 +1108,9 @@
       }
   
       return APR_INCOMPLETE;
  +}
  +
  +APREQ_DECLARE_HOOK(apreq_hook_disable_uploads)
  +{
  +    return APR_EGENERAL;
   }
  
  
  
  1.16      +39 -1     httpd-apreq-2/t/parsers.c
  
  Index: parsers.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/t/parsers.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- parsers.c	26 Jun 2004 01:36:24 -0000	1.15
  +++ parsers.c	27 Jun 2004 18:07:35 -0000	1.16
  @@ -83,7 +83,7 @@
       CuAssertPtrNotNull(tc, req);
       CuAssertStrEquals(tc, req->env, apreq_env_content_type(req->env));
   
  -    /* strlen(form_data) == 317 */
  +    /* strlen(form_data) == 319 */
       for (j = 0; j <= strlen(form_data); ++j) {
           apr_bucket *e = apr_bucket_immortal_create(form_data,
                                                      strlen(form_data),
  @@ -126,6 +126,43 @@
           CuAssertStrEquals(tc, "text/plain", val);
       }
   }
  +static void parse_disable_uploads(CuTest *tc)
  +{
  +    const char *val;
  +    apr_table_t *t;
  +    apr_status_t rv;
  +    apreq_request_t *req = apreq_request(APREQ_MFD_ENCTYPE
  +                         "; charset=\"iso-8859-1\"; boundary=\"AaB03x\"" ,"");
  +    apr_bucket_brigade *bb = apr_brigade_create(p, 
  +                                   apr_bucket_alloc_create(p));
  +    apr_bucket *e = apr_bucket_immortal_create(form_data,
  +                                                   strlen(form_data),
  +                                                   bb->bucket_alloc);
  +
  +    CuAssertPtrNotNull(tc, req);
  +    CuAssertStrEquals(tc, req->env, apreq_env_content_type(req->env));
  +
  +    APR_BRIGADE_INSERT_HEAD(bb, e);
  +    APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_eos_create(bb->bucket_alloc));
  +
  +    req->body = NULL;
  +    req->parser = apreq_parser(req->env, apreq_make_hook(p, 
  +                                 apreq_hook_disable_uploads, NULL, NULL));
  +
  +    rv = apreq_parse_request(req,bb);
  +    CuAssertIntEquals(tc, APR_EGENERAL, rv);
  +    CuAssertPtrNotNull(tc, req->body);
  +    CuAssertIntEquals(tc, 1, apr_table_elts(req->body)->nelts);
  +
  +    val = apr_table_get(req->body,"field1");
  +    CuAssertStrEquals(tc, "Joe owes =80100.", val);
  +    t = apreq_value_to_param(apreq_strtoval(val))->info;
  +    val = apr_table_get(t, "content-transfer-encoding");
  +    CuAssertStrEquals(tc,"quoted-printable", val);
  +
  +    val = apr_table_get(req->body, "pics");
  +    CuAssertPtrEquals(tc, NULL, val);
  +}
   
   
   CuSuite *testparser(void)
  @@ -133,6 +170,7 @@
       CuSuite *suite = CuSuiteNew("Parsers");
       SUITE_ADD_TEST(suite, parse_urlencoded);
       SUITE_ADD_TEST(suite, parse_multipart);
  +    SUITE_ADD_TEST(suite, parse_disable_uploads);
       return suite;
   }
   
  
  
  

Mime
View raw message