Thursday, March 31, 2011

Can I make a single Perl module act as multiple kinds of mod_perl handlers?

I'm writing a series of related mod_perl handlers for various login-related functions in Apache, so my Apache config file looks like this (for example)

PerlAccessHandler MyApache::MyAccess    
PerlAuthenHandler MyApache::MyAuthen
PerlAuthzHandler MyApache::MyAuthz

Each of the modules (MyAccess, MyAuthen, MyAuthz) defines a

sub handler() {}

Which mod_perl calls at the relevant point in the processing of the request.

What I'd like to know is whether there is a way of doing this with one Perl module rather than three (it's just tidier and less work for users to install one module instead of 3)?

Is there some way to define the name of the handler method, perhaps. Or is there a way of detecting from within the handler() code which sort of handling I'm supposed to be doing?

From stackoverflow
  • Looks like one possibility might be using the push_handlers() call and setting up the handlers in code rather than in the apache conf file

    See here: http://tinyurl.com/bwdeew

  • It appears from the mod_perl 2.0 docs that you can use the "method" syntax to do what you're wanting (I've not tested this):

    PerlAccessHandler MyApache::MyLoginModule->access_handler
    PerlAuthenHandler  MyApache::MyLoginModule->authen_handler
    PerlAuthzHandler MyApache::MyLoginModule->authz_handler
    

    I believe this will cause mod_perl to call each of the named methods in a static way on your MyApache::MyLoginModule class.

    You can also create an object to be used when calling a handler method if you want to:

    <Perl>
      use MyApache::MyLoginModule;
      $MyApache::MyLoginModule::access = MyApache::MyLoginModule->new(phase => 'access');
      $MyApache::MyLoginModule::authen = MyApache::MyLoginModule->new(phase => 'authen');
      $MyApache::MyLoginModule::authz = MyApache::MyLoginModule->new(phase => 'authz');
    </Perl>
    
    PerlAccessHandler $MyApache::MyLoginModule::access->handler
    PerlAuthenHandler $MyApache::MyLoginModule::authen->handler
    PerlAuthzHandler $MyApache::MyLoginModule::authz->handler
    

    This approach would allow you to have a single handler method that could have different behavior based on the properties of the object set up upon object creation.

    *Disclaimer: It's been a while since I've worked with this part of mod_perl configuration so your results may vary!*

    AndrewR : Using the "...>access_handler" syntax works. Interestingly the handler gets passed two arguments (the second of which is the request object), unlike the handler() function, which only gets passed the request.
    Brian Phillips : The two-arg behavior is documented in the link at the top of my answer.

0 comments:

Post a Comment