NAME
   Apache::Dispatch - call PerlHandlers with the ease of Registry scripts

SYNOPSIS
   Makefile.PL:

       # require util since it can be used outside an apache process
       PREREQ_PM    => {
           'Apache::Dispatch::Util'    => 0.11,
       }

   httpd.conf:

     PerlModule Apache::Dispatch
     PerlModule Bar

     DispatchExtras Pre Post Error
     DispatchStat On
     DispatchISA "My::Utils"
     DispatchAUTOLOAD Off

     <Location /Foo>
       SetHandler perl-script
       PerlHandler Apache::Dispatch

       DispatchPrefix Bar
       DispatchFilter Off
     </Location>

DESCRIPTION
   Apache::Dispatch translates $r->uri into a class and method and runs it
   as a PerlHandler. Basically, this allows you to call PerlHandlers as you
   would Regsitry scripts without having to load your httpd.conf with a
   slurry of <Location> tags.

EXAMPLE
     in httpd.conf

       PerlModule Apache::Dispatch
       PerlModule Bar

       <Location /Foo>
         SetHandler perl-script
         PerlHandler Apache::Dispatch

         DispatchPrefix Bar
       </Location>

     in browser:
       http://localhost/Foo/baz

     the results are the same as if your httpd.conf looked like:
       <Location /Foo>
         SetHandler perl-script
         PerlHandler Bar->dispatch_baz
       </Location>

   but with the additional security of protecting the class name from the
   browser and keeping the method name from being called directly. Because
   any class under the Bar:: hierarchy can be called, one <Location>
   directive is able to handle all the methods of Bar, Bar::Baz, etc...

CONFIGURATION DIRECTIVES
     DispatchPrefix
       The base class to be substituted for the $r->location part of the
       uri.

     DispatchLocation
       Using Apache::Dispatch from a <Directory> directive, either
       directly or from a .htaccess file, will _require_ the use of
       DispatchLocation, which defines the location from which
       Apache::Dispatch will start class->method() translation.
       For example:

         httpd.conf
           DocumentRoot /usr/local/apache/htdocs
           <Directory /usr/local/apache/htdocs/>
             ...
           <Directory>

        .htaccess (in /usr/local/apache/htdocs/Foo)
           SetHandler perl-script
           PerlHandler Apache::Dispatch
           DispatchPrefix Baz
           DispatchLocation /Foo

       This allows a request to /Foo/Bar/biff to properly map to
       Baz::Bar->biff().

       While intended specifically for <Directory> configurations, one
       could use DispatchLocation to further obscure uri translations
       within <Location> sections as well by changing the part of
       the uri that is substitued with your module.

     DispatchExtras
       An optional list of extra processing to enable per-request.  If
       the main handler is not a valid method call, the request is
       declined prior to the execution of any of the extra methods.

         Pre   - eval()s Foo->pre_dispatch($r) prior to dispatching the
                 uri.  The $@ of the eval is not checked in any way.

         Post  - eval()s Foo->post_dispatch($r) after dispatching the
                 uri.  The $@ of the eval is not checked in any way.

         Error - If the main handler returns other than OK then
                 Foo->error_dispatch($r, $@) is called and return status
                 of it is returned instead.  Unlike the pre and post
                 processing routines above, error_dispatch is not wrapped
                 in an eval, so if it dies, the Apache::Dispatch dies,
                 and Apache will process the error using ErrorDocument,
                 custom_response(), etc.
                 With error_dispatch() disabled, the return status of the
                 the main handler is returned to the client.

     DispatchRequire
       An optional directive that enables require()ing of the module that
       is the result of the uri to class->method translation.  This allows
       your configuration to be a bit more dynamic, but also decreases
       security somewhat.  And don't forget that you really should be
       pre-loading frequently used modules in the parent process to reduce
       overhead - DispatchRequire is a directive of conveinence.

         On    - require() the module

         Off   - Do not require() the module (Default)

     DispatchStat
       An optional directive that enables reloading of the module that is
       the result of the uri to class->method translation, similar to
       Apache::Registry, Apache::Reload, or Apache::StatINC.

         On    - Test the called package for modification and reload on
                 change

         Off   - Do not test or reload the package (Default)

         ISA   - Test the called package, and all other packages in the
                 called package's @ISA, and reload on change

     DispatchAUTOLOAD
       An optional directive that enables unknown methods to use
       AutoLoader.  It may be applied on a per-server or per-location
       basis and defaults to Off.  Please see the special section on
       AUTOLOAD below.

         On    - Allow for methods to be defined in AUTOLOAD method

         Off   - Turn off search for AUTOLOAD method (Default)

     DispatchISA
       An optional list of parent classes you want your dispatched class
       to inherit from.

     DispatchFilter
       If you have Apache::Filter 1.013 or above installed, you can take
       advantage of other Apache::Filter aware modules.  Please see the
       section on FILTERING below.  In keeping with Apache::Filter
       standards, PerlSetVar Filter has the same effect as DispatchFilter
       but with lower precedence.

         On    - make the output of your module Apache::Filter aware

         Off   - do not use Apache::Filter (Default)

     DispatchDebug
       Set DispatchDebug to 1 or 2 to control the verbosity of
       debug statements.

SPECIAL CODING GUIDELINES
   Migrating to Apache::Dispatch is relatively painless - it requires only
   a few minor code changes. The good news is that once you adapt code to
   work with Dispatch, it can be used as a conventional mod_perl method
   handler, requiring only a few considerations. Below are a few things
   that require attention.

   In the interests of security, all handler methods must be prefixed with
   'dispatch_', which is added to the uri behind the scenes. Unlike
   ordinary mod_perl handlers, for Apache::Dispatch there is no default
   method (with a tiny exception - see NOTES below).

   Apache::Dispatch uses object oriented calls behind the scenes. This
   means that you either need to account for your handler to be called as a
   method handler, such as

     sub dispatch_bar {
       my $self  = shift;  # your class
       my $r     = shift;
     }

   or get the Apache request object directly via

     sub dispatch_bar {
       my $r     = Apache->request;
     }

   If you want to use the handler unmodified outside of Apache::Dispatch,
   you must do three things:

     prototype your handler:

       sub dispatch_baz ($$) {
         my $self  = shift;
         my $r     = shift;
       }

     change your httpd.conf entry:

       <Location /Foo>
         SetHandler perl-script
         PerlHandler Bar->dispatch_baz
       </Location>

     pre-load your module:
       PerlModule Bar
         or
       PerlRequire startup.pl
       # where startup.pl contains
       # use Bar;

   That's it - now the handler can be swapped in and out of Dispatch
   without further modification. See the Eagle book on method handlers for
   more details.

FILTERING
   Apache::Dispatch provides for output filtering using Apache::Filter
   1.013 and above.

     <Location /Foo>
       SetHandler perl-script
       PerlHandler Apache::Dispatch Apache::Compress

       DispatchPrefix Bar
       DispatchFilter On
     </Location>

   Your handler need do nothing special to make its output the start of the
   chain - Apache::Dispatch registers itself with Apache::Filter and hides
   the task from your handler. Thus, any dispatched handler is
   automatically Apache::Filter ready without the need for additional code.

   The only caveat is that you must use the request object that is passed
   to the handler and not get it directly using Apache->request.

AUTOLOAD
   Support for AUTOLOAD has been made optional, but requires special care.
   Please take the time to read the camel book on using AUTOLOAD with can()
   and subroutine declarations (3rd ed pp326-329).

   Basically, you declare the methods you want AUTOLOAD to capture by name
   at the top of your script. This is necessary because can() will return
   true if your class (or any parent class) contains an AUTOLOAD method,
   but $AUTOLOAD will only be populated for declared method calls. Hence,
   without a declaration you won't be able to get at the name of the method
   you want to AUTOLOAD.

   DispatchISA introduced some convenience, but some headaches as well - if
   you inherit from a class that uses AutoLoader then ALL method calls are
   true. And as just explained, AUTOLOAD() will not know what the called
   method was. This may represent a problem if you aren't aware that, say,
   CGI.pm uses AutoLoader and spend a few hours trying to figure out why
   all of a sudden every URL under Dispatch is bombing. You may want to
   check out NEXT.pm (available from CPAN) for use in your AUTOLOAD
   routines to help circumvent this partucular feature.

   If you decide to use DispatchISA it is HIGHLY SUGGESTED that you do so
   with DispatchAUTOLOAD Off (which is the default behavior).

NOTES
   If you define a dispatch_index() method calls to /Foo will default to
   it. Unfortunately, this implicit translation only happens at the highest
   level - calls to /Foo/Bar will translate to Foo->Bar() (that is, unless
   Foo::Bar is your DispatchPrefix, in which case it will work but
   /Foo/Bar/Baz will not, etc). Explicit calls to /Foo/index follow the
   normal dispatch rules.

   If the uri can be dispatched but contains anything other than
   [a-zA-Z0-9_/-] Apache::Dispatch declines to handle the request.

   Like everything in perl, the package names are case sensitive.

   Warnings have been left on, so if you set an invalid class with
   DispatchISA you will see a message like: Can't locate package Foo::Bar
   for @Bar::Baz::ISA at .../Apache/Dispatch.pm line 277.

   This is alpha software, and as such has not been tested on multiple
   platforms or environments for security, stability or other concerns. It
   requires PERL_DIRECTIVE_HANDLERS=1, PERL_LOG_API=1, PERL_HANDLER=1, and
   maybe other hooks to function properly.

FEATURES/BUGS
   If a module fails reload under DispatchStat, Apache::Dispatch declines
   the request. This might change to SERVER_ERROR in the future...

SEE ALSO
   perl(1), mod_perl(1), Apache(3), Apache::Filter(3), Apache::Reload(3),
   Apache::StatINC(3)

MAINTAINER
   Fred Moyer <[email protected]>

AUTHOR
   Geoffrey Young <[email protected]>

COPYRIGHT
   Copyright 2001-2006 Geoffrey Young - all rights reserved.

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