NAME

CGI::Application::Dispatch - Class used to dispatch request to CGI::Application based objects

SYNOPSIS

Under mod_perl

<Location /app>
    SetHandler perl-script
    PerlHandler CGI::Application::Dispatch
</Location>

Under normal cgi

#!/usr/bin/perl
use strict;
use CGI::Application::Dispatch;

CGI::Application::Dispatch->dispatch();

DESCRIPTION

This module provides a way (as a mod_perl handler or running under vanilla CGI) to look at the path ($r->path_info or $ENV{PATH_INFO}) of the incoming request, parse off the desired module and it's run mode, create an instance of that module and run it.

It will translate a URI like this (under mod_perl):

/app/module_name/run_mode

or this (vanilla cgi)

/app/index.cgi/module_name/run_mode

into something that will be functionally similar to this

my $app = Module::Name->new(..);
$app->mode_param(sub {'run_mode'}); #this will set the run mode

MOTIVATION

To be honest I got tired of writing lots of individual instance scripts, one for each application module, under the traditional style of CGI::Application programming. Then when I switched to running my CGI::Application modules as straight mod_perl handlers I got tired of having to change my httpd.conf file for every module I introduced and having my configuration file full of Location sections. Since I had moved all of my configuration variables into config files and was not passing any values into the PARAMS hash upon module creation I decided not to write the same code over and over.

I guess it comes down to me just being lazy. :)

OPTIONS

This section describes the different options that are available to customize how you dispatch your requests. All of these options can either be set using 'PerlSetVar' (if you're running under mod_perl) or passed directly as name-value pairs to the "dispatch()" method. When passing them directly as name-value pairs to the "dispatch()" method you may omit the 'CGIAPP_DISPATCH_' prefix on the name of each option. So, CGIAPP_DISPATCH_PREFIX can become simply PREFIX. You can't however use both. We we have examples so don't worry too much.

CGIAPP_DISPATCH_PREFIX

This option will set the string that will be prepended to the name of the application module before it is loaded and created. So to use our previous example request of

/app/index.cgi/module_name/run_mode

This would by default load and create a module named 'Module::Name'. But let's say that you have all of your application specific modules under the 'My' namespace. If you set this option to 'My' then it would instead load the 'My::Module::Name' application module instead.

CGIAPP_DISPATCH_RM

This option, if false, will tell C::A::Dispatch to not set the run mode for the application. By default it is true.

METHODS

handler()

This method is used so that this module can be run as a mod_perl handler. When it creates the application module it passes the $r argument into the PARAMS hash of new()

<Location /app>
    SetHandler perl-script
    PerlHandler CGI::Application::Dispatch
    PerlSetVar  CGIAPP_DISPATCH_PREFIX MyApp
    PerlSetVar  CGIAPP_DISPATCH_RM Off 
</Location>

The above example would tell apache that any url beginning with /app will be handled by CGI::Application::Dispatch. It also sets the prefix used to create the application module to 'MyApp' and it tells CGI::Application::Dispatch that it shouldn't set the run mode but that it will be determined by the application module as usual (through the query string).

dispatch()

This method is primarily used in a non mod_perl setting in an small cgi script to dispatch requests. You can pass this method the same name value pairs that you would set for the "handler()" method using the same options mentioned above.

#!/usr/bin/perl
use strict;
use CGI::Application::Dispatch;

CGI::Application::Dispatch->dispatch(
        PREFIX => 'MyApp',
        RM => 0,
    );

This example would do the same thing that the previous example of how to use the "handler()" method would do. The only difference is that it is done in a script and not in the apache configuration file.

The benefit to using CGI::Application::Dispatch in a non mod_perl environment instead of the traditional instance scripts would only be seen in an application that has many instance scripts. It would mean your application would only need one script and many application modules. Since the dispatch script is so simple you just write it once and forget about it and turn your attention to your modules and templates.

get_module_name($path_info, $prefix)

This method is used to control how the module name is generated from the PATH_INFO. Please see "PATH_INFO Parsing" for more details on how this method performs it's job. The main reason that this method exists is so that it is overridden if it doesn't do exactly what you want.

You shouldn't actually call this method yourself, just override it if necessary.

get_runmode($path_info)

This method is used to control how the run mode is generated from the PATH_INFO. Please see "PATH_INFO Parsing" for more details on how this method performs it's job. The main reason that this method exists is so that it is overridden if it doesn't do exactly what you want.

You shouldn't actually call this method yourself, just override it if necessary.

PATH_INFO Parsing

This section will describe how the application module and run mode are determined from the PATH_INFO and what options you have to customize the process.

Getting the module name

To put it simply, the PATH_INFO is split on backslahes (/). The second element of the returned list is used to create the application module. So if we have a path info of

/module_name/mode1

Then the string 'module_name' is used. Underscores (_) are turned into double colons (::) and each word is passed through ucfirst so that the first letter of each word is captialized.

Then the CGIAPP_DISPATCH_PREFIX is added to the beginning of this new module name with a double colon :: separating the two.

If you don't like the exact way that this is done, don't fret you do have an option. Just override the get_module_name() method by writing your own dispatch class that inherits from CGI::Application::Dispatch.

Getting the run mode

Just like the module name is retrieved from splitting the PATH_INFO on backslashes, so is the run mode. Only instead of using the second element of the resulting list, we use the third as the run mode. So, using the same example, if we have a path info of

/module_name/mode1

Then the string 'mode1' is used as the run mode unless the CGIAPP_DISPATCH_RM is set to false. As with the module name this behavior can be changed by overriding the get_runmode() sub.

MISC NOTES

  • CGI query strings

    CGI query strings are unaffected by the use of PATH_INFO to obtain the module name and run mode. This means that any other modules you use to get access to you query argument (ie, CGI, Apache::Request) should not be affected. But, since the run mode may be determined by CGI::Application::Dispatch having a query argument named 'rm' will be ignored by your application module (unless your CGIAPP_DISPATCH_RM is false).

  • ALPHA software

    This module is still alpha software so please use it with that in mind. It is still possible that the API will change (and may even become unrecognizable) so please remeber to keep up to date.

AUTHOR

Michael Peters <michael@petersfamily.org>

COMMUNITY

This module is a part of the larger CGI::Application community. If you have questions or comments about this module then please join us on the cgiapp mailing list by sending a blank message to "cgiapp-subscribe@lists.erlbaum.net". There is also a community wiki located at http://www.cgi-app.org/

SECURITY

Since C::A::Dispatch will dynamically choose which modules to use as the content generators, it may give someone the ability to execute random modules on your system if those modules can be found in you path. Of course those modules would have to behave like CGI::Application based modules, but that still opens up the door more than most want. This should only be a problem if you don't use the CGIAPP_DISPATCH_PREFIX (or simple PREFIX in "dispatch()") option. By using this option you are only allowing the url to pick from a certain directory (namespace) of applications to run.

SEE ALSO

CGI::Application, Apache::Dispatch

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.