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.