You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-cvs@httpd.apache.org by jo...@apache.org on 2004/08/08 20:42:06 UTC

cvs commit: httpd-apreq-2/src apreq_params.c apreq_version.h

joes        2004/08/08 11:42:06

  Modified:    env      mod_apreq.c
               env/t    request.t
               glue/perl/docs Table.pod
               glue/perl/xsbuilder apreq_xs_tables.h
               glue/perl/xsbuilder/Apache/Cookie Apache__Cookie.h
               glue/perl/xsbuilder/Apache/Request Apache__Request.h
               src      apreq_params.c apreq_version.h
  Log:
  Move context-stealing code from apreq_filter into apreq_filter_make_context.  For it to work optimally on subrequests, we need to go back to setting req->parser as late as possible.  More debugging logs added to ensure the tests exercise the context stealing code, and two new tests added to env/t/request.t (which may have line-ending problems on win32?) to fully exercise the context-stealing code.  Unrelated to any of the above, this patch also drops USE_ITHREADS conditional from apreq_xs_tables.h, since
  that logic is already in ppport.h.
  
  Revision  Changes    Path
  1.59      +70 -61    httpd-apreq-2/env/mod_apreq.c
  
  Index: mod_apreq.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/env/mod_apreq.c,v
  retrieving revision 1.58
  retrieving revision 1.59
  diff -u -r1.58 -r1.59
  --- mod_apreq.c	3 Aug 2004 05:06:04 -0000	1.58
  +++ mod_apreq.c	8 Aug 2004 18:42:05 -0000	1.59
  @@ -157,7 +157,7 @@
   
   
   #define APREQ_MODULE_NAME               "APACHE2"
  -#define APREQ_MODULE_MAGIC_NUMBER       20040802
  +#define APREQ_MODULE_MAGIC_NUMBER       20040808
   
   static void apache2_log(const char *file, int line, int level, 
                           apr_status_t status, void *env, const char *fmt,
  @@ -291,9 +291,72 @@
   static void apreq_filter_make_context(ap_filter_t *f)
   {
       request_rec *r = f->r;
  -    apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(r->pool);
  -    struct filter_ctx *ctx = apr_palloc(r->pool, sizeof *ctx);
       struct env_config *cfg = get_cfg(r);
  +    apreq_request_t *req = cfg->req;
  +    struct filter_ctx *ctx;
  +    apr_bucket_alloc_t *alloc;
  +
  +    if (f == r->input_filters 
  +        && r->proto_input_filters == f->next
  +        && strcasecmp(f->next->frec->name, filter_name) == 0) 
  +    {
  +        /* Try to steal the context and parse data of the 
  +           upstream apreq filter. */
  +        ctx = f->next->ctx;
  +
  +        switch (ctx->status) {
  +        case APR_SUCCESS:
  +        case APR_INCOMPLETE:
  +            break;
  +        default:
  +            /* bad filter state, don't steal anything */
  +            apreq_log(APREQ_DEBUG ctx->status, r, "cannot steal context: bad filter status");
  +            goto make_new_context;
  +        }
  +
  +        if (ctx->r != r) {
  +            /* r is a new request (subrequest or internal redirect) */
  +            apreq_request_t *old_req;
  +
  +            if (req != NULL) {
  +                if (req->parser != NULL) {
  +                    /* new parser on this request: cannot steal context */
  +                    apreq_log(APREQ_DEBUG ctx->status, r, "cannot steal context: new parser detected");
  +                    goto make_new_context;
  +                }
  +            }
  +            else {
  +                req = apreq_request(r, NULL);
  +            }
  +
  +            /* steal the parser output */
  +            apreq_log(APREQ_DEBUG 0, r, "stealing parser output");
  +            old_req = apreq_request(ctx->r, NULL);
  +            req->parser = old_req->parser;
  +            req->body = old_req->body;
  +            req->body_status = old_req->body_status;
  +            ctx->r = r;
  +        }
  +
  +        /* steal the filter context */
  +        apreq_log(APREQ_DEBUG 0, r, "stealing filter context");
  +        f->ctx = f->next->ctx;
  +        r->proto_input_filters = f;
  +        ap_remove_input_filter(f->next);
  +        return;
  +    }
  +
  + make_new_context:
  +    if (req != NULL && f == r->input_filters) {
  +        if (req->body_status != APR_EINIT) {
  +            req->body = NULL;
  +            req->parser = NULL;
  +            req->body_status = APR_EINIT;
  +        }
  +    }
  +
  +    alloc = apr_bucket_alloc_create(r->pool);
  +    ctx = apr_palloc(r->pool, sizeof *ctx);
   
       f->ctx       = ctx;
       ctx->r       = r;
  @@ -456,9 +519,10 @@
       /* else this is a protocol filter which may still be active.
        * if it is, we must deregister it now.
        */
  -    if (cfg->f == f)
  +    if (cfg->f == f) {
  +        apreq_log(APREQ_DEBUG 0, r, "disabling stale protocol filter");
           cfg->f = NULL;
  -
  +    }
       return APR_SUCCESS;
   }
   
  @@ -486,64 +550,9 @@
       cfg = get_cfg(r);
       req = cfg->req;
   
  -    if (f->ctx == NULL) {
  -        if (f == r->input_filters 
  -            && r->proto_input_filters == f->next
  -            && strcmp(f->next->frec->name, filter_name) == 0) 
  -        {
  -            /* Try to steal the context and parse data of the 
  -               upstream apreq filter. */
  -            ctx = f->next->ctx;
  -
  -            switch (ctx->status) {
  -            case APR_SUCCESS:
  -            case APR_INCOMPLETE:
  -                break;
  -            default:
  -                /* bad filter state, don't steal anything */
  -                goto make_new_context;
  -            }
  -
  -            if (ctx->r != r) {
  -                /* r is a new request (subrequest or internal redirect) */
  -                apreq_request_t *old_req;
  -
  -                if (req != NULL) {
  -                    if (req->parser != NULL)
  -                        /* new parser on this request: cannot steal context */
  -                        goto make_new_context;
  -                }
  -                else {
  -                    req = apreq_request(r, NULL);
  -                }
  -
  -                /* steal the parser output */
  -                old_req = apreq_request(ctx->r, NULL);
  -                req->parser = old_req->parser;
  -                req->body = old_req->body;
  -                req->body_status = old_req->body_status;
  -                ctx->r = r;
  -            }
  -
  -            /* steal the filter context */
  -            f->ctx = f->next->ctx;
  -            r->proto_input_filters = f;
  -            ap_remove_input_filter(f->next);
  -            goto context_initialized;
  -        }
  -
  -    make_new_context:
  +    if (f->ctx == NULL)
           apreq_filter_make_context(f);
  -        if (req != NULL && f == r->input_filters) {
  -            if (req->body_status != APR_EINIT) {
  -                req->body = NULL;
  -                req->parser = NULL;
  -                req->body_status = APR_EINIT;
  -            }
  -        }
  -    }
   
  - context_initialized:
       ctx = f->ctx;
   
       if (cfg->f != f)
  
  
  
  1.14      +25 -2     httpd-apreq-2/env/t/request.t
  
  Index: request.t
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/env/t/request.t,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- request.t	6 Aug 2004 15:26:46 -0000	1.13
  +++ request.t	8 Aug 2004 18:42:06 -0000	1.14
  @@ -6,7 +6,7 @@
   use Apache::TestRequest qw(GET_BODY UPLOAD_BODY POST_BODY GET_RC);
   require File::Copy;
   
  -my $num_tests = 16;
  +my $num_tests = 18;
   $num_tests *= 2 if Apache::Test::have_ssl();
   plan tests => $num_tests, have_lwp;
   my $scheme = "http";
  @@ -59,7 +59,6 @@
   EOT
   }
   
  -
   # internal redirect to plain text files (which are non-apreq requests)
   
   my $index_html = do {local (@ARGV,$/) = "t/htdocs/index.html"; <> };
  @@ -102,6 +101,30 @@
   \ttest => output filter POST
   EOT
             "output filter POST");
  +
  +# internal redirect to html files which are filtered as above
  +
  +$body = GET_BODY("/apreq_redirect_test?test=redirect_index_html_GET&location=/index.html?foo=bar");
  +$body =~ s{\r}{}g;
  +ok t_cmp($body, $index_html . <<EOT, "redirect /index.html (GET)");
  +
  +--APREQ OUTPUT FILTER--
  +ARGS:
  +\tfoo => bar
  +EOT
  +$body = POST_BODY("/apreq_redirect_test?test=redirect_index_html_POST",
  +        content => "quux=$filler;location=/index.html?foo=quux;foo=$filler");
  +$body =~ s{\r}{}g;
  +ok t_cmp($body, $index_html . <<EOT, "redirect /index.txt (POST)");
  +
  +--APREQ OUTPUT FILTER--
  +ARGS:
  +\tfoo => quux
  +BODY:
  +\tquux => $filler
  +\tlocation => /index.html?foo=quux
  +\tfoo => $filler
  +EOT
   
   if (Apache::Test::have_ssl() and $scheme ne 'https') {    
       $scheme = 'https';
  
  
  
  1.8       +6 -0      httpd-apreq-2/glue/perl/docs/Table.pod
  
  Index: Table.pod
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/docs/Table.pod,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Table.pod	31 Jul 2004 23:56:40 -0000	1.7
  +++ Table.pod	8 Aug 2004 18:42:06 -0000	1.8
  @@ -44,6 +44,8 @@
   and C<overlap> methods from APR::Table are not implemented.
   
   
  +
  +
   =head1 Apache::Request::Table
   
   These tables arise as parameter tables generated by the C<args>, C<body>, and 
  @@ -65,6 +67,7 @@
   
   
   
  +
   =head1 Apache::Upload::Table
   
   These tables arise from the C<Apache::Request::upload> method (which is
  @@ -85,6 +88,7 @@
   
   
   
  +
   =head1 Apache::Cookie::Table
   
   These tables arise from the C<cookies> method of Apache::Cookie::Jar, and
  @@ -102,6 +106,8 @@
       ok $cookie->isa("Apache::Cookie");
   
   =for example_testing
  +
  +
   
   
   =head1 SEE ALSO
  
  
  
  1.36      +0 -2      httpd-apreq-2/glue/perl/xsbuilder/apreq_xs_tables.h
  
  Index: apreq_xs_tables.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/apreq_xs_tables.h,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- apreq_xs_tables.h	5 Aug 2004 21:01:14 -0000	1.35
  +++ apreq_xs_tables.h	8 Aug 2004 18:42:06 -0000	1.36
  @@ -182,9 +182,7 @@
                                  const char *val)
   {
       struct apreq_xs_do_arg *d = (struct apreq_xs_do_arg *)data;
  -#ifdef USE_ITHREADS
       dTHXa(d->perl);
  -#endif
   
       dSP;
       SV *sv = newSVpv(key,0);
  
  
  
  1.35      +2 -1      httpd-apreq-2/glue/perl/xsbuilder/Apache/Cookie/Apache__Cookie.h
  
  Index: Apache__Cookie.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Cookie/Apache__Cookie.h,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- Apache__Cookie.h	3 Aug 2004 18:07:58 -0000	1.34
  +++ Apache__Cookie.h	8 Aug 2004 18:42:06 -0000	1.35
  @@ -46,7 +46,8 @@
       jar = apreq_jar(env, data);
   
       sv = apreq_xs_2sv(jar, SvPV_nolen(ST(0)), SvRV(ST(1)));
  -    SvTAINTED_on(SvRV(sv));
  +    if (items == 2 || SvTAINTED(ST(2)))
  +        SvTAINTED_on(SvRV(sv));
       ST(0) = sv_2mortal(sv);
       XSRETURN(1);
   }
  
  
  
  1.56      +9 -1      httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h
  
  Index: Apache__Request.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- Apache__Request.h	5 Aug 2004 18:11:46 -0000	1.55
  +++ Apache__Request.h	8 Aug 2004 18:42:06 -0000	1.56
  @@ -107,7 +107,8 @@
   
       /*FIXME: mg_mg->ptr */
       sv = apreq_xs_2sv(req, SvPV_nolen(ST(0)), SvRV(ST(1)));
  -    SvTAINTED_on(SvRV(sv));
  +    if (items == 2 || SvTAINTED(ST(2)))
  +        SvTAINTED_on(SvRV(sv));
       ST(0) = sv_2mortal(sv);
       XSRETURN(1);
   }
  @@ -378,6 +379,13 @@
   #ifdef USE_ITHREADS
               ctx->perl = aTHX;
   #endif
  +            if (req->parser == NULL)
  +                req->parser = apreq_parser(req->env, NULL);
  +            if (req->parser == NULL)
  +                Perl_croak(aTHX_ "Apache::Request::config: cannot install "
  +                           "UPLOAD_HOOK: no parser available for enctype=%s", 
  +                           apreq_enctype(req->env));
  +
               upload_hook = apreq_make_hook(pool, apreq_xs_upload_hook,
                                             NULL, ctx);
               apreq_add_hook(req->parser, upload_hook);
  
  
  
  1.47      +2 -2      httpd-apreq-2/src/apreq_params.c
  
  Index: apreq_params.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.c,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- apreq_params.c	4 Aug 2004 17:40:54 -0000	1.46
  +++ apreq_params.c	8 Aug 2004 18:42:06 -0000	1.47
  @@ -63,7 +63,7 @@
           req->env      = env;
           req->args     = apr_table_make(p, APREQ_NELTS);
           req->body     = NULL;
  -        req->parser   = apreq_parser(env, NULL);
  +        req->parser   = NULL;
   
           /* XXX get/set race condition here wrt apreq_env_request? */
           old_req = apreq_env_request(env, req);
  @@ -83,7 +83,7 @@
           req->env      = env;
           req->args     = apr_table_make(p, APREQ_NELTS);
           req->body     = NULL;
  -        req->parser   = apreq_parser(env, NULL);
  +        req->parser   = NULL;
   
       }
   
  
  
  
  1.24      +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.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- apreq_version.h	31 Jul 2004 23:56:40 -0000	1.23
  +++ apreq_version.h	8 Aug 2004 18:42:06 -0000	1.24
  @@ -61,7 +61,7 @@
   #define APREQ_MINOR_VERSION       0
   
   /** patch level */
  -#define APREQ_PATCH_VERSION      19
  +#define APREQ_PATCH_VERSION      20
   
   /** 
    *  This symbol is defined for internal, "development" copies of libapreq.