stas        2003/04/02 22:23:54

  Modified:    src/modules/perl mod_perl.c modperl_cmd.c modperl_cmd.h
                        modperl_filter.h modperl_filter.c
               .        Changes
  Added:       t/htdocs/includes clear.shtml
               t/filter out_str_req_mix.t
               t/filter/TestFilter out_str_req_mix.pm
  Log:
  new directives PerlSetInputFilter and PerlSetOutputFilter, which are
  the same as SetInputFilter and SetOutputFilter respectively, but allow
  to insert non-mod_perl filters before, between or after mod_perl
  filters. + tests
  
  Revision  Changes    Path
  1.163     +6 -1      modperl-2.0/src/modules/perl/mod_perl.c
  
  Index: mod_perl.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v
  retrieving revision 1.162
  retrieving revision 1.163
  diff -u -r1.162 -r1.163
  --- mod_perl.c        25 Mar 2003 07:52:22 -0000      1.162
  +++ mod_perl.c        3 Apr 2003 06:23:52 -0000       1.163
  @@ -699,7 +699,12 @@
       MP_CMD_SRV_TAKE1("PerlPassEnv", pass_env, "PerlPassEnv"),
       MP_CMD_SRV_RAW_ARGS_ON_READ("<Perl", perl, "Perl Code"),
       MP_CMD_SRV_RAW_ARGS("Perl", perldo, "Perl Code"),
  -     
  +
  +    MP_CMD_DIR_TAKE1("PerlSetInputFilter", set_input_filter,
  +                     "filter[;filter]"),
  +    MP_CMD_DIR_TAKE1("PerlSetOutputFilter", set_output_filter,
  +                     "filter[;filter]"),
  +    
       MP_CMD_DIR_RAW_ARGS_ON_READ("=pod", pod, "Start of POD"),
       MP_CMD_DIR_RAW_ARGS_ON_READ("=back", pod, "End of =over"),
       MP_CMD_DIR_RAW_ARGS_ON_READ("=cut", pod_cut, "End of POD"),
  
  
  
  1.44      +76 -0     modperl-2.0/src/modules/perl/modperl_cmd.c
  
  Index: modperl_cmd.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_cmd.c,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -r1.43 -r1.44
  --- modperl_cmd.c     25 Mar 2003 22:58:49 -0000      1.43
  +++ modperl_cmd.c     3 Apr 2003 06:23:52 -0000       1.44
  @@ -30,6 +30,27 @@
       return NULL;
   }
   
  +char *modperl_cmd_push_httpd_filter_handlers(MpAV **handlers,
  +                                             const char *name,
  +                                             apr_pool_t *p)
  +{
  +    modperl_handler_t *h = modperl_handler_new(p, name);
  +
  +    /* we don't want this special handler to be parsed */
  +    MpHandlerPARSED_On(h);
  +    h->attrs = MP_FILTER_HTTPD_HANDLER;
  +        
  +    if (!*handlers) {
  +        *handlers = modperl_handler_array_new(p);
  +        MP_TRACE_d(MP_FUNC, "created handler stack\n");
  +    }
  +
  +    modperl_handler_array_push(*handlers, h);
  +    MP_TRACE_d(MP_FUNC, "pushed httpd filter handler: %s\n", h->name);
  +
  +    return NULL;
  +}
  +
   
   #define MP_CMD_SRV_TRACE \
       MP_TRACE_d(MP_FUNC, "%s %s\n", parms->cmd->name, arg)
  @@ -475,6 +496,61 @@
   
       return modperl_module_add(p, s, arg);
   }
  +
  +/* propogate filters insertion ala SetInputFilter */
  +MP_CMD_SRV_DECLARE(set_input_filter)
  +{
  +    MP_dSCFG(parms->server);
  +    modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
  +    char *filter;
  +    
  +    if (!MpSrvENABLE(scfg)) {
  +        return apr_pstrcat(parms->pool,
  +                           "Perl is disabled for server ",
  +                           parms->server->server_hostname, NULL);
  +    }
  +    if (!MpSrvINPUT_FILTER(scfg)) {
  +        return apr_pstrcat(parms->pool,
  +                           "PerlSetInputFilter is disabled for server ",
  +                           parms->server->server_hostname, NULL);
  +    }
  +
  +    while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) {
  +        modperl_cmd_push_httpd_filter_handlers(
  +            &(dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER]),
  +            filter, parms->pool);
  +    }
  +
  +    return NULL;
  +}
  +
  +/* propogate filters insertion ala SetOutputFilter */
  +MP_CMD_SRV_DECLARE(set_output_filter)
  +{
  +    MP_dSCFG(parms->server);
  +    modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
  +    char *filter;
  +    
  +    if (!MpSrvENABLE(scfg)) {
  +        return apr_pstrcat(parms->pool,
  +                           "Perl is disabled for server ",
  +                           parms->server->server_hostname, NULL);
  +    }
  +    if (!MpSrvINPUT_FILTER(scfg)) {
  +        return apr_pstrcat(parms->pool,
  +                           "PerlSetOutputFilter is disabled for server ",
  +                           parms->server->server_hostname, NULL);
  +    }
  +
  +    while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) {
  +        modperl_cmd_push_httpd_filter_handlers(
  +            &(dcfg->handlers_per_dir[MP_OUTPUT_FILTER_HANDLER]),
  +            filter, parms->pool);
  +    }
  +
  +    return NULL;
  +}
  +
   
   #ifdef MP_COMPAT_1X
   
  
  
  
  1.21      +6 -0      modperl-2.0/src/modules/perl/modperl_cmd.h
  
  Index: modperl_cmd.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_cmd.h,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- modperl_cmd.h     7 Oct 2002 02:35:18 -0000       1.20
  +++ modperl_cmd.h     3 Apr 2003 06:23:53 -0000       1.21
  @@ -4,6 +4,10 @@
   char *modperl_cmd_push_handlers(MpAV **handlers, const char *name,
                                   apr_pool_t *p);
   
  +char *modperl_cmd_push_httpd_filter_handlers(MpAV **handlers,
  +                                             const char *name,
  +                                             apr_pool_t *p);
  +
   #define MP_CMD_SRV_DECLARE(item) \
   const char *modperl_cmd_##item(cmd_parms *parms, void *mconfig, \
                                  const char *arg)
  @@ -32,6 +36,8 @@
   MP_CMD_SRV_DECLARE(pod_cut);
   MP_CMD_SRV_DECLARE(END);
   MP_CMD_SRV_DECLARE(load_module);
  +MP_CMD_SRV_DECLARE(set_input_filter);
  +MP_CMD_SRV_DECLARE(set_output_filter);
   
   #ifdef MP_COMPAT_1X
   
  
  
  
  1.22      +1 -0      modperl-2.0/src/modules/perl/modperl_filter.h
  
  Index: modperl_filter.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.h,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- modperl_filter.h  3 Mar 2003 03:39:06 -0000       1.21
  +++ modperl_filter.h  3 Apr 2003 06:23:53 -0000       1.22
  @@ -9,6 +9,7 @@
   
   #define MP_FILTER_CONNECTION_HANDLER 0x01
   #define MP_FILTER_REQUEST_HANDLER    0x02
  +#define MP_FILTER_HTTPD_HANDLER      0x04 
   
   typedef ap_filter_t * MP_FUNC_T(modperl_filter_add_t) (const char *, void *,
                                                          request_rec *,
  
  
  
  1.58      +18 -1     modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.57
  retrieving revision 1.58
  diff -u -r1.57 -r1.58
  --- modperl_filter.c  3 Apr 2003 06:21:43 -0000       1.57
  +++ modperl_filter.c  3 Apr 2003 06:23:53 -0000       1.58
  @@ -707,6 +707,14 @@
           for (i=0; i<av->nelts; i++) {
               modperl_filter_ctx_t *ctx;
   
  +            if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) {
  +                addfunc(handlers[i]->name, NULL, NULL, c);
  +                MP_TRACE_f(MP_FUNC,
  +                           "a non-mod_perl %s handler %s configured (connection)\n",
  +                           type, handlers[i]->name);
  +                continue;
  +            }
  +            
               if (!(handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) {
                   MP_TRACE_f(MP_FUNC,
                              "%s is not a FilterConnection handler\n",
  @@ -747,8 +755,17 @@
           for (i=0; i<av->nelts; i++) {
               modperl_filter_ctx_t *ctx;
               int registered = 0;
  -            ap_filter_t *f = filters;
  +            ap_filter_t *f;
  +
  +            if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) {
  +                addfunc(handlers[i]->name, NULL, r, r->connection);
  +                MP_TRACE_f(MP_FUNC,
  +                           "a non-mod_perl %s handler %s configured (%s)\n",
  +                           type, handlers[i]->name, r->uri);
  +                continue;
  +            }
   
  +            f = filters;
               while (f) {
                   const char *fname = f->frec->name;
   
  
  
  
  1.1                  modperl-2.0/t/htdocs/includes/clear.shtml
  
  Index: clear.shtml
  ===================================================================
  This is a REMOVEclear text
  
  
  1.1                  modperl-2.0/t/filter/out_str_req_mix.t
  
  Index: out_str_req_mix.t
  ===================================================================
  use strict;
  use warnings FATAL => 'all';
  
  use Apache::Test;
  use Apache::TestRequest;
  use Apache::TestUtil;
  
  plan tests => 1, ['include'];
  
  my $location = '/TestFilter::out_str_req_mix';
  
  my $content = '<!--#include virtual="/includes/REMOVEclear.shtml" -->';
  
  my $body   = 'This is a clear text';
  
  my $expected = 'This is a clear text';
  my $received = POST_BODY $location, content => $content;
  
  ok t_cmp($expected, $received, 
      "mixing output httpd and mod_perl filters, while preserving order");
  
  
  
  1.1                  modperl-2.0/t/filter/TestFilter/out_str_req_mix.pm
  
  Index: out_str_req_mix.pm
  ===================================================================
  package TestFilter::out_str_req_mix;
  
  # in this test we verify that we can preserve the mixed order of
  # modperl and non-modperl filters using the PerlSetOutputFilter
  # directive, instead of SetOutputFilter for non-modperl filters.
  #
  # response handler prints a mangled SSI directive:
  #     <!--#include virtual="/includes/REMOVEclear.shtml" -->
  # (which it receives via POST from the client)
  #
  # adjust() filter is configured to be called first and it removes the
  # string 'REMOVE' from the response handler's output, so that SSI will
  # find the fixed resource specification:
  #     <!--#include virtual="/includes/clear.shtml" -->
  #
  # the INCLUDES filter, which is configured to be next on the stack
  # (mod_include) processes the directive and returns the contents of
  # file "/includes/clear.shtml", which is:
  #    This is a REMOVEclear text
  #
  # finally the second mod_perl filter (which happens to be the same
  # adjust() filter, but to all purposes it's a separate filter)
  # configured to run after the INCLUDES filter fixes the data sent by
  # the INCLUDES filter to be:
  #    This is a clear text
  #
  # and this is what the client is expecting to receive
  #
  # WARNING: notice that the adjust() filter assumes that it'll receive
  # the word REMOVE in a single bucket, which is good enough for the
  # test because we control all the used filters and normally Apache
  # core filters won't split short data into several buckets.  However
  # filter developers shouldn't make any assumptions, since any data can
  # be split by any of the upstream filters.
  
  use strict;
  use warnings FATAL => 'all';
  
  use Apache::Filter ();
  
  use Apache::Const -compile => qw(OK M_POST);
  
  sub adjust {
      my $filter = shift;
  
      warn "add_prefix called\n";
  
      while ($filter->read(my $buffer, 1024)){
          $buffer =~ s/REMOVE//;
          $filter->print($buffer);
      }
  
      Apache::OK;
  }
  
  sub handler {
      my $r = shift;
  
      $r->content_type('text/plain');
  
      if ($r->method_number == Apache::M_POST) {
          $r->print(ModPerl::Test::read_post($r));
      }
  
      return Apache::OK;
  }
  
  1;
  __DATA__
  <NoAutoConfig>
      PerlModule TestFilter::out_str_req_mix
      <Location /TestFilter::out_str_req_mix> 
          Options +Includes
          PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust
          PerlSetOutputFilter INCLUDES
          PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust
          SetHandler modperl
          PerlResponseHandler     TestFilter::out_str_req_mix
      </Location>
  </NoAutoConfig>
  
  
  
  
  
  
  
  1.162     +7 -0      modperl-2.0/Changes
  
  Index: Changes
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/Changes,v
  retrieving revision 1.161
  retrieving revision 1.162
  diff -u -r1.161 -r1.162
  --- Changes   1 Apr 2003 05:20:51 -0000       1.161
  +++ Changes   3 Apr 2003 06:23:53 -0000       1.162
  @@ -10,6 +10,13 @@
   
   =item 1.99_09-dev
   
  +new directives PerlSetInputFilter and PerlSetOutputFilter, which are
  +the same as SetInputFilter and SetOutputFilter respectively, but allow
  +to insert non-mod_perl filters before, between or after mod_perl
  +filters. + tests [Stas]
  +
  +improved filters debug tracing [Stas]
  +
   implement $filter->remove (filter self-removal) + tests [Stas]
   
   remove the second-guessing code that was trying to guess the package
  
  
  

Reply via email to