dougm       01/03/25 17:08:30

  Modified:    lib/ModPerl Code.pm
               src/modules/perl modperl_config.c modperl_handler.c
                        modperl_handler.h modperl_mgv.c modperl_mgv.h
  Log:
  add support for proper merge of handlers
  example:
  
  PerlFixupHandler One::fixup
  
  <Location /foo>
     PerlFixupHandler Another::fixup
  </Location>
  
  default request for /foo only runs Another::fixup (1.x behavior)
  PerlOptions +MergeHandlers (inside Location /foo)
  will run both One::fixup and Another::fixup
  
  Revision  Changes    Path
  1.53      +3 -2      modperl-2.0/lib/ModPerl/Code.pm
  
  Index: Code.pm
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/lib/ModPerl/Code.pm,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -r1.52 -r1.53
  --- Code.pm   2001/03/25 17:42:26     1.52
  +++ Code.pm   2001/03/26 01:08:28     1.53
  @@ -89,8 +89,9 @@
   #XXX: allow disabling of PerDir hooks on a PerDir basis
   my @hook_flags = (map { canon_uc($_) } keys %hooks);
   my %flags = (
  -    Srv => [qw(NONE CLONE PARENT ENABLED AUTOLOAD), @hook_flags, 'UNSET'],
  -    Dir => [qw(NONE SEND_HEADER SETUP_ENV UNSET)],
  +    Srv => [qw(NONE CLONE PARENT ENABLED AUTOLOAD MERGE_HANDLERS),
  +            @hook_flags, 'UNSET'],
  +    Dir => [qw(NONE SEND_HEADER SETUP_ENV MERGE_HANDLERS UNSET)],
       Interp => [qw(NONE IN_USE PUTBACK CLONED BASE)],
       Handler => [qw(NONE PARSED METHOD OBJECT ANON AUTOLOAD DYNAMIC)],
   );
  
  
  
  1.29      +31 -25    modperl-2.0/src/modules/perl/modperl_config.c
  
  Index: modperl_config.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_config.c,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- modperl_config.c  2001/03/25 17:42:26     1.28
  +++ modperl_config.c  2001/03/26 01:08:29     1.29
  @@ -15,8 +15,19 @@
   #define merge_item(item) \
   mrg->item = add->item ? add->item : base->item
   
  +#define merge_handlers(merge_flag, array) \
  +    if (merge_flag(mrg)) { \
  +        mrg->array = modperl_handler_array_merge(p, \
  +                                                 base->array, \
  +                                                 add->array); \
  +    } \
  +    else { \
  +        merge_item(array); \
  +    }
  +
   void *modperl_config_dir_merge(apr_pool_t *p, void *basev, void *addv)
   {
  +    int i;
       modperl_config_dir_t
           *base = (modperl_config_dir_t *)basev,
           *add  = (modperl_config_dir_t *)addv,
  @@ -29,16 +40,13 @@
       merge_item(interp_lifetime);
   #endif
   
  -    { /* XXX: should do a proper merge of the arrays */
  -      /* XXX: and check if Perl*Handler is disabled */
  -        int i;
  -        for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) {
  -            merge_item(handlers_per_dir[i]);
  -        }
  -    }
  -
       mrg->flags = modperl_options_merge(p, base->flags, add->flags);
   
  +    /* XXX: check if Perl*Handler is disabled */
  +    for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) {
  +        merge_handlers(MpDirMERGE_HANDLERS, handlers_per_dir[i]);
  +    }
  +
       return mrg;
   }
   
  @@ -132,6 +140,7 @@
   /* XXX: this is not complete */
   void *modperl_config_srv_merge(apr_pool_t *p, void *basev, void *addv)
   {
  +    int i;
       modperl_config_srv_t
           *base = (modperl_config_srv_t *)basev,
           *add  = (modperl_config_srv_t *)addv,
  @@ -151,24 +160,21 @@
   
       merge_item(argv);
   
  -    { /* XXX: should do a proper merge of the arrays */
  -      /* XXX: and check if Perl*Handler is disabled */
  -        int i;
  -        for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) {
  -            merge_item(handlers_per_srv[i]);
  -        }
  -        for (i=0; i < MP_HANDLER_NUM_FILES; i++) {
  -            merge_item(handlers_files[i]);
  -        }
  -        for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) {
  -            merge_item(handlers_process[i]);
  -        }
  -        for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) {
  -            merge_item(handlers_connection[i]);
  -        }
  -    }
  -
       mrg->flags = modperl_options_merge(p, base->flags, add->flags);
  +
  +    /* XXX: check if Perl*Handler is disabled */
  +    for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) {
  +        merge_handlers(MpSrvMERGE_HANDLERS, handlers_per_srv[i]);
  +    }
  +    for (i=0; i < MP_HANDLER_NUM_FILES; i++) {
  +        merge_handlers(MpSrvMERGE_HANDLERS, handlers_files[i]);
  +    }
  +    for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) {
  +        merge_handlers(MpSrvMERGE_HANDLERS, handlers_process[i]);
  +    }
  +    for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) {
  +        merge_handlers(MpSrvMERGE_HANDLERS, handlers_connection[i]);
  +    }
   
       return mrg;
   }
  
  
  
  1.7       +45 -0     modperl-2.0/src/modules/perl/modperl_handler.c
  
  Index: modperl_handler.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_handler.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- modperl_handler.c 2001/03/17 06:03:37     1.6
  +++ modperl_handler.c 2001/03/26 01:08:29     1.7
  @@ -18,6 +18,51 @@
       return modperl_handler_new(p, h->name);
   }
   
  +int modperl_handler_equal(modperl_handler_t *h1, modperl_handler_t *h2)
  +{
  +    if (h1->mgv_cv && h2->mgv_cv) {
  +        return modperl_mgv_equal(h1->mgv_cv, h2->mgv_cv);
  +    }
  +    return strEQ(h1->name, h2->name);
  +}
  +
  +MpAV *modperl_handler_array_merge(apr_pool_t *p, MpAV *base_a, MpAV *add_a)
  +{
  +    int i, j;
  +    modperl_handler_t **base_h, **add_h, **mrg_h;
  +    MpAV *mrg_a;
  +
  +    if (!add_a) {
  +        return base_a;
  +    }
  +
  +    if (!base_a) {
  +        return add_a;
  +    }
  +
  +    mrg_a = apr_array_copy(p, base_a);
  +
  +    mrg_h  = (modperl_handler_t **)mrg_a->elts;
  +    base_h = (modperl_handler_t **)base_a->elts;
  +    add_h  = (modperl_handler_t **)add_a->elts;
  +
  +    for (i=0; i<base_a->nelts; i++) {
  +        for (j=0; j<add_a->nelts; j++) {
  +            if (modperl_handler_equal(base_h[i], add_h[j])) {
  +                MP_TRACE_d(MP_FUNC, "both base and new config contain %s\n",
  +                           add_h[j]->name);
  +            }
  +            else {
  +                modperl_handler_array_push(mrg_a, add_h[j]);
  +                MP_TRACE_d(MP_FUNC, "base does not contain %s\n",
  +                           add_h[j]->name);
  +            }
  +        }
  +    }
  +
  +    return mrg_a;
  +}
  +
   void modperl_handler_make_args(pTHX_ AV **avp, ...)
   {
       va_list args;
  
  
  
  1.6       +4 -0      modperl-2.0/src/modules/perl/modperl_handler.h
  
  Index: modperl_handler.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_handler.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- modperl_handler.h 2001/03/17 06:03:37     1.5
  +++ modperl_handler.h 2001/03/26 01:08:29     1.6
  @@ -24,6 +24,10 @@
   modperl_handler_t *modperl_handler_dup(apr_pool_t *p,
                                          modperl_handler_t *h);
   
  +int modperl_handler_equal(modperl_handler_t *h1, modperl_handler_t *h2);
  +
  +MpAV *modperl_handler_array_merge(apr_pool_t *p, MpAV *base_a, MpAV *add_a);
  +
   void modperl_handler_make_args(pTHX_ AV **avp, ...);
   
   MpAV **modperl_handler_lookup_handlers(modperl_config_dir_t *dcfg,
  
  
  
  1.11      +18 -0     modperl-2.0/src/modules/perl/modperl_mgv.c
  
  Index: modperl_mgv.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_mgv.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- modperl_mgv.c     2001/03/25 21:26:47     1.10
  +++ modperl_mgv.c     2001/03/26 01:08:29     1.11
  @@ -50,6 +50,24 @@
   
   #define hv_fetch_he(hv,k,l,h) S_hv_fetch_he(aTHX_ hv,k,l,h)
   
  +int modperl_mgv_equal(modperl_mgv_t *mgv1,
  +                      modperl_mgv_t *mgv2)
  +{
  +    for (; mgv1 && mgv2; mgv1=mgv1->next, mgv2=mgv2->next) {
  +        if (mgv1->hash != mgv2->hash) {
  +            return FALSE;
  +        }
  +        if (mgv1->len != mgv2->len) {
  +            return FALSE;
  +        }
  +        if (memNE(mgv1->name, mgv2->name, mgv1->len)) {
  +            return FALSE;
  +        }
  +    }
  +
  +    return TRUE;
  +}
  +
   modperl_mgv_t *modperl_mgv_new(apr_pool_t *p)
   {
       return (modperl_mgv_t *)apr_pcalloc(p, sizeof(modperl_mgv_t));
  
  
  
  1.4       +3 -0      modperl-2.0/src/modules/perl/modperl_mgv.h
  
  Index: modperl_mgv.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_mgv.h,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- modperl_mgv.h     2001/03/17 06:03:37     1.3
  +++ modperl_mgv.h     2001/03/26 01:08:29     1.4
  @@ -3,6 +3,9 @@
   
   modperl_mgv_t *modperl_mgv_new(apr_pool_t *p);
   
  +int modperl_mgv_equal(modperl_mgv_t *mgv1,
  +                      modperl_mgv_t *mgv2);
  +
   modperl_mgv_t *modperl_mgv_compile(pTHX_ apr_pool_t *p, const char *name);
   
   char *modperl_mgv_name_from_sv(pTHX_ apr_pool_t *p, SV *sv);
  
  
  

Reply via email to