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);