Doug,

I didn't see in the announcement that the below fix is included in
1.25_01. Can you please confirm?

Regards,
Christian

> -----Original Message-----
> From: Doug MacEachern [mailto:[EMAIL PROTECTED]]
> Sent: Tuesday, August 15, 2000 7:59 PM
> To: [EMAIL PROTECTED]
> Cc: 'Modperl Mailing List (E-mail)'
> Subject: Re: Yet more on set_handlers() and new-found problems with
> lookup_uri()
>
>
>
> i think the jist of the problem(s), is that set_handlers()
> modifies the
> configuration structure (the one created at startup from
> httpd.conf), so
> any subrequests will end up with the modified structure (which is not
> reset until the end of the request).  this patch implements
> {get,set}_handlers in terms of r->per_request_config, which is
> unique to each (sub-)request.  if this doesn't fix the
> problem, it would
> really help to have a small test case that i can drop in to
> see the bug in
> action.
>
> Index: src/modules/perl/Apache.xs
> ===================================================================
> RCS file: /home/cvs/modperl/src/modules/perl/Apache.xs,v
> retrieving revision 1.103
> diff -u -r1.103 Apache.xs
> --- src/modules/perl/Apache.xs     2000/08/15 19:36:32  1.103
> +++ src/modules/perl/Apache.xs     2000/08/16 00:46:44
> @@ -73,12 +73,6 @@
>      void (*set_func) (void *, void *, SV *);
>  } perl_handler_table;
>
> -typedef struct {
> -    I32 fill;
> -    AV *av;
> -    AV **ptr;
> -} perl_save_av;
> -
>  static void set_handler_dir (perl_handler_table *tab,
> request_rec *r, SV
> *sv);
>  static void set_handler_srv (perl_handler_table *tab,
> request_rec *r, SV
> *sv);
>
> @@ -101,28 +95,17 @@
>      {HandlerDirEntry("PerlFixupHandler", PerlFixupHandler)},
>      {HandlerDirEntry("PerlHandler", PerlHandler)},
>      {HandlerDirEntry("PerlLogHandler", PerlLogHandler)},
> +    {HandlerDirEntry("PerlCleanupHandler", PerlCleanupHandler)},
>      { FALSE, NULL }
>  };
>
> -static void perl_restore_av(void *data)
> -{
> -    perl_save_av *save_av = (perl_save_av *)data;
> -
> -    if(save_av->fill != DONE) {
> -    AvFILLp(*save_av->ptr) = save_av->fill;
> -    }
> -    else if(save_av->av != Nullav) {
> -    *save_av->ptr = save_av->av;
> -    }
> -}
> -
>  static void perl_handler_merge_avs(char *hook, AV **dest)
>  {
>      int i = 0;
>      HV *hv = perl_get_hv("Apache::PerlStackedHandlers", FALSE);
>      SV **svp = hv_fetch(hv, hook, strlen(hook), FALSE);
>      AV *base;
> -
> +
>      if(!(svp && SvROK(*svp)))
>      return;
>
> @@ -133,45 +116,53 @@
>      }
>  }
>
> +#define avptr_from_offset(ptr, tab) \
> +(AV **)((char *)ptr + (int)(long)tab->offset)
> +
>  static void set_handler_base(void *ptr, perl_handler_table
> *tab, pool *p,
> SV *sv)
>  {
> -    AV **av = (AV **)((char *)ptr + (int)(long)tab->offset);
> +    int do_register_cleanup = 0;
> +    AV **av = avptr_from_offset(ptr, tab);
>
> -    perl_save_av *save_av =
> -    (perl_save_av *)palloc(p, sizeof(perl_save_av));
> -
> -    save_av->fill = DONE;
> -    save_av->av = Nullav;
> -
> -    if((sv == &sv_undef) || (SvIOK(sv) && SvIV(sv) == DONE)) {
> -    if(AvTRUE(*av)) {
> -        save_av->fill = AvFILL(*av);
> -        AvFILLp(*av) = -1;
> -    }
> -    }
> -    else if(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVAV) {
> -    if(AvTRUE(*av))
> -        save_av->av = av_copy_array(*av);
> -    *av = (AV*)SvRV(sv);
> -    ++SvREFCNT(*av);
> +    if ((sv == &sv_undef) || (SvIOK(sv) && SvIV(sv) == DONE)) {
> +        if (!*av) {
> +            do_register_cleanup = 1;
> +        }
> +        if (*av && SvREFCNT(*av)) {
> +            SvREFCNT_dec(*av);
> +        }
> +        *av = newAV();
> +    }
> +    else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVAV) {
> +        *av = (AV*)SvRV(sv);
> +        ++SvREFCNT(*av);
> +        do_register_cleanup = 1;
>      }
>      else {
> -    croak("Can't set_handler with that value");
> +        croak("Can't set_handler with that value");
> +    }
> +
> +    if (do_register_cleanup) {
> +        register_cleanup(p, (void*)*av, mod_perl_cleanup_av,
> mod_perl_noop);
>      }
> -    save_av->ptr = av;
> -    register_cleanup(p, save_av, perl_restore_av, mod_perl_noop);
>  }
>
> -static void set_handler_dir(perl_handler_table *tab,
> request_rec *r, SV
> *sv)
> +void set_handler_dir(perl_handler_table *tab, request_rec *r, SV *sv)
>  {
> -    dPPDIR;
> -    set_handler_base((void*)cld, tab, r->pool, sv);
> +    dPPREQ;
> +    if (!cfg->dir_cfg) {
> +        cfg->dir_cfg = perl_create_dir_config(r->pool, r->uri);
> +    }
> +    set_handler_base((void*)cfg->dir_cfg, tab, r->pool, sv);
>  }
>
>  static void set_handler_srv(perl_handler_table *tab,
> request_rec *r, SV
> *sv)
>  {
> -    dPSRV(r->server);
> -    set_handler_base((void*)cls, tab, r->pool, sv);
> +    dPPREQ;
> +    if (!cfg->srv_cfg) {
> +        cfg->srv_cfg = perl_create_server_config(r->pool, NULL);
> +    }
> +    set_handler_base((void*)cfg->srv_cfg, tab, r->pool, sv);
>  }
>
>  static perl_handler_table *perl_handler_lookup(char *name)
> @@ -185,29 +176,45 @@
>      return NULL;
>  }
>
> -
>  static SV *get_handlers(request_rec *r, char *hook)
>  {
>      AV *avcopy;
>      AV **av;
> +    dPPREQ;
>      dPPDIR;
>      dPSRV(r->server);
>      void *ptr;
>      perl_handler_table *tab = perl_handler_lookup(hook);
>
> -    if(!tab) return Nullsv;
> +    if (!tab) {
> +        return Nullsv;
> +    }
>
> -    if(tab->type == PER_DIR_CONFIG)
> -    ptr = (void*)cld;
> -    else
> -    ptr = (void*)cls;
> +    if (tab->type == PER_DIR_CONFIG) {
> +        if (cfg->dir_cfg && *avptr_from_offset(cfg->dir_cfg, tab)) {
> +            ptr = (void*)cfg->dir_cfg;
> +        }
> +        else {
> +            ptr = (void*)cld;
> +        }
> +    }
> +    else {
> +        if (cfg->srv_cfg && *avptr_from_offset(cfg->srv_cfg, tab)) {
> +            ptr = (void*)cfg->srv_cfg;
> +        }
> +        else {
> +            ptr = (void*)cls;
> +        }
> +    }
>
> -    av = (AV **)((char *)ptr + (int)(long)tab->offset);
> +    av = avptr_from_offset(ptr, tab);
>
> -    if(*av)
> +    if (*av) {
>      avcopy = av_copy_array(*av);
> -    else
> -    avcopy = newAV();
> +    }
> +    else {
> +        avcopy = newAV();
> +    }
>
>      perl_handler_merge_avs(hook, &avcopy);
>
> Index: src/modules/perl/mod_perl.c
> ===================================================================
> RCS file: /home/cvs/modperl/src/modules/perl/mod_perl.c,v
> retrieving revision 1.124
> diff -u -r1.124 mod_perl.c
> --- src/modules/perl/mod_perl.c    2000/08/15 19:36:33  1.124
> +++ src/modules/perl/mod_perl.c    2000/08/16 00:46:44
> @@ -891,7 +891,8 @@
>      }
>
>      cfg->setup_env = 1;
> -    PERL_CALLBACK("PerlHandler", cld->PerlHandler);
> +    PERL_CALLBACK("PerlHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlHandler));
>      cfg->setup_env = 0;
>
>      FREETMPS;
> @@ -965,16 +966,26 @@
>  {
>      dSTATUS;
>      dPSRV(r->server);
> +    dPPREQ;
> +
> +    if (!cfg) {
> +    cfg = perl_create_request_config(r->pool, r->server);
> +    set_module_config(r->request_config, &perl_module, cfg);
> +    }
> +
>  #if MODULE_MAGIC_NUMBER > 19980270
>      if(r->parsed_uri.scheme && r->parsed_uri.hostname &&
> do_proxy(r)) {
>      r->proxyreq = 1;
>      r->uri = r->unparsed_uri;
>      }
>  #endif
> +
>  #ifdef PERL_INIT
> -    PERL_CALLBACK("PerlInitHandler", cls->PerlInitHandler);
> +    PERL_CALLBACK("PerlInitHandler",
> +                  PERL_REQ_SRV_HANDLER(cfg, cls, PerlInitHandler));
>  #endif
> -    PERL_CALLBACK("PerlPostReadRequestHandler",
> cls->PerlPostReadRequestHandler);
> +    PERL_CALLBACK("PerlPostReadRequestHandler",
> +                  PERL_REQ_SRV_HANDLER(cfg, cls,
> PerlPostReadRequestHandler));
>      return status;
>  }
>  #endif
> @@ -984,7 +995,9 @@
>  {
>      dSTATUS;
>      dPSRV(r->server);
> -    PERL_CALLBACK("PerlTransHandler", cls->PerlTransHandler);
> +    dPPREQ;
> +    PERL_CALLBACK("PerlTransHandler",
> +                  PERL_REQ_SRV_HANDLER(cfg, cls, PerlTransHandler));
>      return status;
>  }
>  #endif
> @@ -994,12 +1007,13 @@
>  {
>      dSTATUS;
>      dPPDIR;
> +    dPPREQ;
>  #ifdef PERL_INIT
>      PERL_CALLBACK("PerlInitHandler",
> -               cld->PerlInitHandler);
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlInitHandler));
>  #endif
>      PERL_CALLBACK("PerlHeaderParserHandler",
> -               cld->PerlHeaderParserHandler);
> +                  PERL_REQ_DIR_HANDLER(cfg, cld,
> PerlHeaderParserHandler));
>      return status;
>  }
>  #endif
> @@ -1009,7 +1023,9 @@
>  {
>      dSTATUS;
>      dPPDIR;
> -    PERL_CALLBACK("PerlAuthenHandler", cld->PerlAuthenHandler);
> +    dPPREQ;
> +    PERL_CALLBACK("PerlAuthenHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlAuthenHandler));
>      return status;
>  }
>  #endif
> @@ -1019,7 +1035,9 @@
>  {
>      dSTATUS;
>      dPPDIR;
> -    PERL_CALLBACK("PerlAuthzHandler", cld->PerlAuthzHandler);
> +    dPPREQ;
> +    PERL_CALLBACK("PerlAuthzHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlAuthzHandler));
>      return status;
>  }
>  #endif
> @@ -1029,7 +1047,9 @@
>  {
>      dSTATUS;
>      dPPDIR;
> -    PERL_CALLBACK("PerlAccessHandler", cld->PerlAccessHandler);
> +    dPPREQ;
> +    PERL_CALLBACK("PerlAccessHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlAccessHandler));
>      return status;
>  }
>  #endif
> @@ -1039,7 +1059,9 @@
>  {
>      dSTATUS;
>      dPPDIR;
> -    PERL_CALLBACK("PerlTypeHandler", cld->PerlTypeHandler);
> +    dPPREQ;
> +    PERL_CALLBACK("PerlTypeHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlTypeHandler));
>      return status;
>  }
>  #endif
> @@ -1049,7 +1071,9 @@
>  {
>      dSTATUS;
>      dPPDIR;
> -    PERL_CALLBACK("PerlFixupHandler", cld->PerlFixupHandler);
> +    dPPREQ;
> +    PERL_CALLBACK("PerlFixupHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlFixupHandler));
>      return status;
>  }
>  #endif
> @@ -1059,7 +1083,9 @@
>  {
>      dSTATUS;
>      dPPDIR;
> -    PERL_CALLBACK("PerlLogHandler", cld->PerlLogHandler);
> +    dPPREQ;
> +    PERL_CALLBACK("PerlLogHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld, PerlLogHandler));
>      return status;
>  }
>  #endif
> @@ -1117,9 +1143,11 @@
>      request_rec *r = (request_rec *)data;
>      dSTATUS;
>      dPPDIR;
> +    dPPREQ;
>
>  #ifdef PERL_CLEANUP
> -    PERL_CALLBACK("PerlCleanupHandler", CleanupHandler);
> +    PERL_CALLBACK("PerlCleanupHandler",
> +                  PERL_REQ_DIR_HANDLER(cfg, cld,
> PerlCleanupHandler));
>  #endif
>
>      MP_TRACE_g(fprintf(stderr, "perl_end_cleanup..."));
> Index: src/modules/perl/mod_perl.h
> ===================================================================
> RCS file: /home/cvs/modperl/src/modules/perl/mod_perl.h,v
> retrieving revision 1.102
> diff -u -r1.102 mod_perl.h
> --- src/modules/perl/mod_perl.h    2000/08/15 19:36:33  1.102
> +++ src/modules/perl/mod_perl.h    2000/08/16 00:46:46
> @@ -1058,7 +1058,15 @@
>      HV *pnotes;
>      int setup_env;
>      array_header *sigsave;
> +    perl_dir_config *dir_cfg;
> +    perl_server_config *srv_cfg;
>  } perl_request_config;
> +
> +#define PERL_REQ_DIR_HANDLER(cfg, cld, h) \
> +((cfg && cfg->dir_cfg && cfg->dir_cfg->h) ? cfg->dir_cfg->h : cld->h)
> +
> +#define PERL_REQ_SRV_HANDLER(cfg, cls, h) \
> +((cfg && cfg->srv_cfg && cfg->srv_cfg->h) ? cfg->srv_cfg->h : cls->h)
>
>  typedef struct {
>      int is_method;
>

Reply via email to