Codebase list libcgi-application-dispatch-perl / 3156688
Imported Upstream version 3.12 Xavier Guimard 11 years ago
10 changed file(s) with 590 addition(s) and 337 deletion(s). Raw diff Collapse all Expand all
2727 'Plack' => 0.9956, # really, we just depend on Plack::Test, but Plack::Test has not declared a version.
2828 $have_apache_test ? ( 'Apache::Test' => 0 ) : (),
2929 },
30 meta_merge => {
31 resources => {
32 repository => 'https://github.com/markstos/CGI--Application--Dispatch',
33 },
34 },
3035 );
3136
3237 $build->create_build_script;
00 Revision history for Perl extension CGI::Application::Dispatch.
1
2 3.12 September 10th, 2012
3 [BUG FIXES]
4 - Further fix diagnostic message in some cases when exceptions are thrown. (Michael Lackhoff)
5
6 3.11 September 10th, 2012
7 (No code changes)
8
9 [INTERNALS]
10 - Fixed test for rethrowing HTTP::Exception objects (Graham TerMarsch)
11
12 3.10 September 2nd, 2012
13 [NEW FEATURES]
14 - CGI::Application::Dispatch::PSGI now allows exceptions thrown as HTTP::Exception objects
15 to bubble up in some cases. See the new documentation section on "Exception Handling"
16 for details. (Mark Stosberg, Graham TerMarsch, RT#79022)
17
18 [BUG FIXES]
19 - When auto_rest was enabled and no run mode was found, a 404 could have been returned
20 instead of defaulting to start mode. We now correctly default to the start_mode().
21 (James Q.L., Ron Savage, Mark Stosberg)
22
23 [DOCUMENTATION]
24 - Docs have been expanded to explain how /foo/:rm? resolves, and interaction
25 with start_mode() when no run mode is found. (Mark Stosberg)
26
27 [INTERNALS]
28 - Fix diagnostic message in some cases when exceptions are thrown (Michael Lackhoff)
29 - Added test coverage for auto_rest to CGI::Application::Dispatch::PSGI (Mark Stosberg)
30 - POD formatting fix in Dispatch.pm
31 - Fix Perl 5.14 compatibility warning (chorny, RENEEB@cpan.org, SILASMONK@cpan.org)
132
233 3.07 September 9th, 2011
334 Fix t/cgi.t test failures caused by Try::Tiny refactor in 3.05 (Yoshihiro Sasaki)
33 "Michael Peters <mpeters@plusthree.com>"
44 ],
55 "dynamic_config" : 1,
6 "generated_by" : "Module::Build version 0.38, CPAN::Meta::Converter version 2.110930",
6 "generated_by" : "Module::Build version 0.4003, CPAN::Meta::Converter version 2.112150",
77 "license" : [
88 "perl_5"
99 ],
4040 "provides" : {
4141 "CGI::Application::Dispatch" : {
4242 "file" : "lib/CGI/Application/Dispatch.pm",
43 "version" : "3.07"
43 "version" : "3.12"
4444 },
4545 "CGI::Application::Dispatch::PSGI" : {
4646 "file" : "lib/CGI/Application/Dispatch/PSGI.pm",
47 "version" : "3.04"
47 "version" : "3.12"
4848 },
4949 "CGI::Application::Dispatch::Regexp" : {
5050 "file" : "lib/CGI/Application/Dispatch/Regexp.pm",
5555 "resources" : {
5656 "license" : [
5757 "http://dev.perl.org/licenses/"
58 ]
58 ],
59 "repository" : {
60 "url" : "https://github.com/markstos/CGI--Application--Dispatch"
61 }
5962 },
60 "version" : "3.07"
63 "version" : "3.12"
6164 }
99 configure_requires:
1010 Module::Build: 0.38
1111 dynamic_config: 1
12 generated_by: 'Module::Build version 0.38, CPAN::Meta::Converter version 2.110930'
12 generated_by: 'Module::Build version 0.4003, CPAN::Meta::Converter version 2.112150'
1313 license: perl
1414 meta-spec:
1515 url: http://module-build.sourceforge.net/META-spec-v1.4.html
1818 provides:
1919 CGI::Application::Dispatch:
2020 file: lib/CGI/Application/Dispatch.pm
21 version: 3.07
21 version: 3.12
2222 CGI::Application::Dispatch::PSGI:
2323 file: lib/CGI/Application/Dispatch/PSGI.pm
24 version: 3.04
24 version: 3.12
2525 CGI::Application::Dispatch::Regexp:
2626 file: lib/CGI/Application/Dispatch/Regexp.pm
2727 version: 3.04
3434 version: 0.82
3535 resources:
3636 license: http://dev.perl.org/licenses/
37 version: 3.07
37 repository: https://github.com/markstos/CGI--Application--Dispatch
38 version: 3.12
00 package CGI::Application::Dispatch::PSGI;
11 use strict;
22 use warnings;
3 use Carp qw(carp cluck);
3 use Carp 'carp';
44 use HTTP::Exception;
5 use Try::Tiny;
6
7 our $VERSION = '3.04';
5
6 our $VERSION = '3.12';
87 our $DEBUG = 0;
98
109 =pod
1110
1211 =head1 NAME
1312
14 CGI::Application::Dispatch::PSGI - Dispatch requests to CGI::Application based objects using PSGI
13 CGI::Application::Dispatch::PSGI - Dispatch requests to
14 CGI::Application based objects using PSGI
1515
1616 =head1 SYNOPSIS
1717
6969
7070 =head2 With a custom query object
7171
72 If you want to supply your own PSGI object, something like this in your .psgi file will work:
72 If you want to supply your own PSGI object, something like this in
73 your .psgi file will work:
7374
7475 sub {
7576 my $env = shift;
8788
8889 =head1 DESCRIPTION
8990
90 This module provides a way to look at the path (as returned by
91 C<< $env->{PATH_INFO} >>) of the incoming request, parse off the desired module and
92 its run mode, create an instance of that module and run it.
91 This module provides a way to look at the path (as returned by C<<
92 $env->{PATH_INFO} >>) of the incoming request, parse off the desired
93 module and its run mode, create an instance of that module and run it.
9394
9495 It will translate a URI like this (in a persistent environment)
9596
190191 # use the 'default' if we need to
191192 $path_info = $args{default} || '' if(!$path_info || $path_info eq '/');
192193
193 # make sure they all start and end with a '/', to correspond with the RE we'll make
194 # make sure they all start and end with a '/', to correspond
195 # with the RE we'll make
194196 $path_info = "/$path_info" unless(index($path_info, '/') == 0);
195197 $path_info = "$path_info/" unless(substr($path_info, -1) eq '/');
196198
243245
244246 my $auto_rest =
245247 defined $named_args->{auto_rest} ? $named_args->{auto_rest} : $args{auto_rest};
246 if($auto_rest) {
248 if($auto_rest && defined $rm && length $rm) {
247249 my $method_lc =
248250 defined $named_args->{auto_rest_lc}
249251 ? $named_args->{auto_rest_lc}
258260 $psgi_app = $self->_run_app($module, $rm, $local_args_to_new,$env);
259261 };
260262 if (my $e = HTTP::Exception->caught) {
261 # XXX I think this is a bug, because http_error returns HTML, not a PSGI app.
262263 return $self->http_error($e);
263264 }
264265 elsif ($e = Exception::Class->caught) {
292293
293294 =item prefix
294295
295 This option will set the string that will be prepended to the name of the application
296 module before it is loaded and created. So to use our previous example request of
296 This option will set the string that will be prepended to the name of
297 the application module before it is loaded and created. So to use our
298 previous example request of
297299
298300 /app/index.cgi/module_name/run_mode
299301
300 This would by default load and create a module named 'Module::Name'. But let's say that you
301 have all of your application specific modules under the 'My' namespace. If you set this option
302 to 'My' then it would instead load the 'My::Module::Name' application module instead.
302 This would by default load and create a module named
303 'Module::Name'. But let's say that you have all of your application
304 specific modules under the 'My' namespace. If you set this option to
305 'My' then it would instead load the 'My::Module::Name' application
306 module instead.
303307
304308 =item args_to_new
305309
306 This is a hash of arguments that are passed into the C<new()> constructor of the application.
310 This is a hash of arguments that are passed into the C<new()>
311 constructor of the application.
307312
308313 =item table
309314
310 In most cases, simply using Dispatch with the C<default> and C<prefix> is enough
311 to simplify your application and your URLs, but there are many cases where you want
312 more power. Enter the dispatch table. Since this table can be slightly complicated,
313 a whole section exists on its use. Please see the L<DISPATCH TABLE> section.
315 In most cases, simply using Dispatch with the C<default> and C<prefix>
316 is enough to simplify your application and your URLs, but there are
317 many cases where you want more power. Enter the dispatch table. Since
318 this table can be slightly complicated, a whole section exists on its
319 use. Please see the L<DISPATCH TABLE> section.
314320
315321 =item debug
316322
317 Set to a true value to send debugging output for this module to STDERR. Off by default.
323 Set to a true value to send debugging output for this module to
324 STDERR. Off by default.
318325
319326 =item auto_rest
320327
321 This tells Dispatch that you are using REST by default and that you care about which HTTP method
322 is being used. Dispatch will append the HTTP method name (upper case by default) to
323 the run mode that is determined after finding the appropriate dispatch rule. So a GET request
324 that translates into C<< MyApp::Module->foo >> will become C<< MyApp::Module->foo_GET >>.
328 This tells Dispatch that you are using REST by default and that you
329 care about which HTTP method is being used. Dispatch will append the
330 HTTP method name (upper case by default) to the run mode that is
331 determined after finding the appropriate dispatch rule. So a GET
332 request that translates into C<< MyApp::Module->foo >> will become
333 C<< MyApp::Module->foo_GET >>.
325334
326335 This can be overridden on a per-rule basis in a custom dispatch table.
327336
328337 =item auto_rest_lc
329338
330 In combinaion with L<auto_rest> this tells Dispatch that you prefer lower cased HTTP method names.
331 So instead of C<foo_POST> and C<foo_GET> you'll have C<foo_post> and C<foo_get>.
339 In combinaion with L<auto_rest> this tells Dispatch that you prefer
340 lower cased HTTP method names. So instead of C<foo_POST> and
341 C<foo_GET> you'll have C<foo_post> and C<foo_get>.
332342
333343 =back
334344
344354 my $errno = $e->isa('HTTP::Exception::Base') ? $e->code : 500;
345355 my $output = $e->isa('HTTP::Exception::Base') ? $e->status_message : "Internal Server Error";
346356
347 # The custom status message was most useful for logging. Return generic messages to the user.
357 # The custom status message was most useful for logging. Return
358 # generic messages to the user.
348359 $output = 'Not Found' if ($e->code == 404);
349360 $output = 'Internal Server Error' if ($e->code == 500);
350361
381392 $rule =~ s/$http_method_regex//;
382393 }
383394
384 # make sure they start and end with a '/' to match how PATH_INFO is formatted
395 # make sure they start and end with a '/' to match how
396 # PATH_INFO is formatted
385397 $rule = "/$rule" unless(index($rule, '/') == 0);
386398 $rule = "$rule/" if(substr($rule, -1) ne '/');
387399
388400 my @names = ();
389401
390 # translate the rule into a regular expression, but remember where the named args are
402 # translate the rule into a regular expression, but remember
403 # where the named args are
391404 # '/:foo' will become '/([^\/]*)'
392405 # and
393406 # '/:bar?' will become '/?([^\/]*)?'
446459 # now create and run then application object
447460 warn "[Dispatch] creating instance of $module\n" if($DEBUG);
448461
449 try {
462 my $psgi;
463 eval {
450464 my $app = do {
451465 if (ref($args) eq 'HASH' and not defined $args->{QUERY}) {
452466 require CGI::PSGI;
461475 }
462476 };
463477 $app->mode_param(sub { return $rm }) if($rm);
464 return $app->run_as_psgi;
465 }
466 catch {
467 # catch invalid run-mode stuff
468 if(not ref $_ and $_ =~ /No such run mode/) {
469 HTTP::Exception->throw(404, status_message => "RM '$rm' not found");
470 }
471 # otherwise, just pass it up the chain
472 else {
473 HTTP::Exception->throw(500, status_message => "Unknown error: $_");
474 }
478 $psgi = $app->run_as_psgi;
475479 };
480
481 # App threw an HTTP::Exception? Cool. Bubble it up.
482 my $e;
483 if ($e = HTTP::Exception->caught) {
484 $e->rethrow;
485 }
486 else {
487 $e = Exception::Class->caught();
488
489 # catch invalid run-mode stuff
490 if (not ref $e and $e =~ /No such run mode/) {
491 HTTP::Exception->throw(404, status_message => "RM '$rm' not found");
492 }
493 # otherwise, it's an internal server error.
494 elsif (defined $e and length $e) {
495 HTTP::Exception->throw(500, status_message => "Unknown error: $e");
496 #return $psgi;
497 }
498 else {
499 # no exception
500 return $psgi;
501 }
502 }
476503 }
477504
478505 =head2 dispatch_args()
479506
480 Returns a hashref of args that will be passed to L<dispatch>(). It will return the following
481 structure by default.
507 Returns a hashref of args that will be passed to L<dispatch>(). It
508 will return the following structure by default.
482509
483510 {
484511 prefix => '',
489516 ],
490517 }
491518
492 This is the perfect place to override when creating a subclass to provide a richer dispatch
493 L<table>.
494
495 When called, it receives 1 argument, which is a reference to the hash of args passed into
496 L<dispatch>.
519 This is the perfect place to override when creating a subclass to
520 provide a richer dispatch L<table>.
521
522 When called, it receives 1 argument, which is a reference to the hash
523 of args passed into L<dispatch>.
497524
498525 =cut
499526
513540 =head2 translate_module_name($input)
514541
515542 This method is used to control how the module name is translated from
516 the matching section of the path (see L<"Path Parsing">.
517 The main reason that this method exists is so that it can be overridden if it doesn't do
518 exactly what you want.
543 the matching section of the path (see L<"Path Parsing">. The main
544 reason that this method exists is so that it can be overridden if it
545 doesn't do exactly what you want.
519546
520547 The following transformations are performed on the input:
521548
551578
552579 =head2 require_module($module_name)
553580
554 This class method is used internally to take a module
555 name (supplied by L<get_module_name>) and require it in a secure fashion. It
556 is provided as a public class method so that if you override other functionality of
557 this module, you can still safely require user specified modules. If there are
558 any problems requiring the named module, then we will C<croak>.
581 This class method is used internally to take a module name (supplied
582 by L<get_module_name>) and require it in a secure fashion. It is
583 provided as a public class method so that if you override other
584 functionality of this module, you can still safely require user
585 specified modules. If there are any problems requiring the named
586 module, then we will C<croak>.
559587
560588 CGI::Application::Dispatch::PSGI->require_module('MyApp::Module::Name');
561589
621649
622650 Just so we all understand what we're talking about....
623651
624 A table is an array where the elements are gouped as pairs (similar to a hash's
625 key-value pairs, but as an array to preserve order). The first element of each pair
626 is called a C<rule>. The second element in the pair is called the rule's C<arg list>.
627 Inside a rule there are slashes C</>. Anything set of characters between slashes
628 is called a C<token>.
652 A table is an array where the elements are gouped as pairs (similar to
653 a hash's key-value pairs, but as an array to preserve order). The
654 first element of each pair is called a C<rule>. The second element in
655 the pair is called the rule's C<arg list>. Inside a rule there are
656 slashes C</>. Anything set of characters between slashes is called a
657 C<token>.
629658
630659 =head2 URL MATCHING
631660
632 When a URL comes in, Dispatch tries to match it against each rule in the table in
633 the order in which the rules are given. The first one to match wins.
661 When a URL comes in, Dispatch tries to match it against each rule in
662 the table in the order in which the rules are given. The first one to
663 match wins.
634664
635665 A rule consists of slashes and tokens. A token can one of the following types:
636666
647677
648678 =item variable
649679
650 Any token which begins with a colon (C<:>) is a variable token. These are simply
651 wild-card place holders in the rule that will match anything in the URL that isn't
652 a slash. These variables can later be referred to by using the C<< $self->param >>
653 mechanism. In the rule
680 Any token which begins with a colon (C<:>) is a variable token. These
681 are simply wild-card place holders in the rule that will match
682 anything in the URL that isn't a slash. These variables can later be
683 referred to by using the C<< $self->param >> mechanism. In the rule
654684
655685 'posts/:category'
656686
657 C<:category> is a variable token. If the URL matched this rule, then you could retrieve
658 the value of that token from whithin your application like so:
687 C<:category> is a variable token. If the URL matched this rule, then
688 you could the value of that token from whithin your application like
689 so:
659690
660691 my $category = $self->param('category');
661692
662 There are some variable tokens which are special. These can be used to further customize
663 the dispatching.
693 There are some variable tokens which are special. These can be used to
694 further customize the dispatching.
664695
665696 =over
666697
667698 =item :app
668699
669 This is the module name of the application. The value of this token will be sent to the
670 L<translate_module_name> method and then prefixed with the L<prefix> if there is one.
700 This is the module name of the application. The value of this token
701 will be sent to the L<translate_module_name> method and then prefixed
702 with the L<prefix> if there is one.
671703
672704 =item :rm
673705
674 This is the run mode of the application. The value of this token will be the actual name
675 of the run mode used.
706 This is the run mode of the application. The value of this token will be the
707 actual name of the run mode used. The run mode can be optional, as
708 noted below. Example:
709
710 /foo/:rm?
711
712 If no run mode is found, it will default to using the C<< start_mode() >>, just like
713 invoking CGI::Application directly. Both of these URLs would end up dispatching
714 to the start mode associated with /foo:
715
716 /foo/
717 /foo
676718
677719 =back
678720
679721 =item optional-variable
680722
681 Any token which begins with a colon (C<:>) and ends with a question mark (<?>) is considered
682 optional. If the rest of the URL matches the rest of the rule, then it doesn't matter whether
683 it contains this token or not. It's best to only include optional-variable tokens at the end
684 of your rule. In the rule
723 Any token which begins with a colon (C<:>) and ends with a question
724 mark (<?>) is considered optional. If the rest of the URL matches the
725 rest of the rule, then it doesn't matter whether it contains this
726 token or not. It's best to only include optional-variable tokens at
727 the end of your rule. In the rule
685728
686729 'date/:year/:month?/:day?'
687730
688731 C<:month?> and C<:day?> are optional-variable tokens.
689732
690 Just like with L<variable> tokens, optional-variable tokens' values can also be retrieved by
691 the application, if they existed in the URL.
733 Just like with L<variable> tokens, optional-variable tokens' values
734 can also be retrieved by the application, if they existed in the URL.
692735
693736 if( defined $self->param('month') ) {
694737 ...
696739
697740 =item wildcard
698741
699 The wildcard token "*" allows for partial matches. The token MUST appear at the end of the
700 rule.
742 The wildcard token "*" allows for partial matches. The token MUST
743 appear at the end of the rule.
701744
702745 'posts/list/*'
703746
704 By default, the C<dispatch_url_remainder> param is set to the remainder of the URL
705 matched by the *. The name of the param can be changed by setting "*" argument in the
706 L<ARG LIST>.
747 By default, the C<dispatch_url_remainder> param is set to the
748 remainder of the URL matched by the *. The name of the param can be
749 changed by setting "*" argument in the L<ARG LIST>.
707750
708751 'posts/list/*' => { '*' => 'post_list_filter' }
709752
710753 =item method
711754
712 You can also dispatch based on HTTP method. This is similar to using L<auto_rest> but
713 offers more fine grained control. You include the method (case insensitive) at the end of
714 the rule and enclose it in square brackets.
755 You can also dispatch based on HTTP method. This is similar to using
756 L<auto_rest> but offers more fine grained control. You include the
757 method (case insensitive) at the end of the rule and enclose it in
758 square brackets.
715759
716760 ':app/news[post]' => { rm => 'add_news' },
717761 ':app/news[get]' => { rm => 'news' },
719763
720764 =back
721765
722 The main reason that we don't use regular expressions for dispatch rules is that regular
723 expressions provide no mechanism for named back references, like variable tokens do.
766 The main reason that we don't use regular expressions for dispatch
767 rules is that regular expressions provide no mechanism for named back
768 references, like variable tokens do.
724769
725770 =head2 ARG LIST
726771
727 Each rule can have an accompanying arg-list. This arg list can contain special arguments
728 that override something set higher up in L<dispatch> for this particular URL, or just
729 have additional args passed available in C<< $self->param() >>
730
731 For instance, if you want to override L<prefix> for a specific rule, then you can do so.
772 Each rule can have an accompanying arg-list. This arg list can contain
773 special arguments that override something set higher up in L<dispatch>
774 for this particular URL, or just have additional args passed available
775 in C<< $self->param() >>
776
777 For instance, if you want to override L<prefix> for a specific rule,
778 then you can do so.
732779
733780 'admin/:app/:rm' => { prefix => 'MyApp::Admin' },
734781
735782 =head1 Path Parsing
736783
737 This section will describe how the application module and run mode are determined from
738 the path if no L<DISPATCH TABLE> is present, and what options you have to
739 customize the process. The value for the path to be parsed is retrieved from
740 C<< $env->{PATH_INFO} >>.
784 This section will describe how the application module and run mode are
785 determined from the path if no L<DISPATCH TABLE> is present, and what
786 options you have to customize the process. The value for the path to
787 be parsed is retrieved from C<< $env->{PATH_INFO} >>.
741788
742789 =head2 Getting the module name
743790
744 To get the name of the application module the path is split on backslahes (C</>).
745 The second element of the returned list (the first is empty) is used to create the application module. So if we
746 have a path of
791 To get the name of the application module the path is split on
792 backslahes (C</>). The second element of the returned list (the first
793 is empty) is used to create the application module. So if we have a
794 path of
747795
748796 /module_name/mode1
749797
750 then the string 'module_name' is used. This is passed through the L<translate_module_name>
751 method. Then if there is a C<prefix> (and there should always be a L<prefix>) it is added
752 to the beginning of this new module name with a double colon C<::> separating the two.
753
754 If you don't like the exact way that this is done, don't fret you do have a couple of options.
755 First, you can specify a L<DISPATCH TABLE> which is much more powerful and flexible (in fact
756 this default behavior is actually implemented internally with a dispatch table).
757 Or if you want something a little simpler, you can simply subclass and extend the
758 L<translate_module_name> method.
798 then the string 'module_name' is used. This is passed through the
799 L<translate_module_name> method. Then if there is a C<prefix> (and
800 there should always be a L<prefix>) it is added to the beginning of
801 this new module name with a double colon C<::> separating the two.
802
803 If you don't like the exact way that this is done, don't fret you do
804 have a couple of options. First, you can specify a L<DISPATCH TABLE>
805 which is much more powerful and flexible (in fact this default
806 behavior is actually implemented internally with a dispatch table).
807 Or if you want something a little simpler, you can simply subclass and
808 extend the L<translate_module_name> method.
759809
760810 =head2 Getting the run mode
761811
762 Just like the module name is retrieved from splitting the path on slashes, so is the
763 run mode. Only instead of using the second element of the resulting list, we use the third
764 as the run mode. So, using the same example, if we have a path of
812 Just like the module name is retrieved from splitting the path on
813 slashes, so is the run mode. Only instead of using the second element
814 of the resulting list, we use the third as the run mode. So, using the
815 same example, if we have a path of
765816
766817 /module_name/mode2
767818
768819 Then the string 'mode2' is used as the run mode.
769820
821 =head1 Exception Handling
822
823 A CGI::Application object can throw an exception up to C<<
824 CGI::Application::Dispatch::PSGI >> if no C<error_mode()> is implemented or if
825 the error_mode itself throws an exception. In these cases we generally return a
826 generic "500" response, and log some details for the developer with a warning.
827
828 However, we will check to see if the exception thrown is an HTTP::Exception
829 object. If that's the case, we will rethrow it, and you can handle it yourself using
830 something like L<Plack::Middleware::HTTPExceptions>.
831
770832 =head1 MISC NOTES
771833
772834 =over 8
773835
774836 =item * CGI query strings
775837
776 CGI query strings are unaffected by the use of C<PATH_INFO> to obtain the module name and run mode.
777 This means that any other modules you use to get access to you query argument (ie, L<CGI>,
778 L<Apache::Request>) should not be affected. But, since the run mode may be determined by
779 CGI::Application::Dispatch::PSGI having a query argument named 'rm' will be ignored by your application
780 module.
838 CGI query strings are unaffected by the use of C<PATH_INFO> to obtain
839 the module name and run mode. This means that any other modules you
840 use to get access to you query argument (ie, L<CGI>,
841 L<Apache::Request>) should not be affected. But, since the run mode
842 may be determined by CGI::Application::Dispatch::PSGI having a query
843 argument named 'rm' will be ignored by your application module.
781844
782845 =back
783846
787850
788851 /cgi-bin/dispatch.cgi/module_name/run_mode
789852
790 However, including "/cgi-bin/dispatch.cgi" in ever URL doesn't add any value to the URL,
791 so it's nice to remove it. This is easily done if you are using the Apache web server with
792 C<mod_rewrite> available. Adding the following to a C<.htaccess> file would allow you to
793 simply use:
853 However, including "/cgi-bin/dispatch.cgi" in ever URL doesn't add any
854 value to the URL, so it's nice to remove it. This is easily done if
855 you are using the Apache web server with C<mod_rewrite>
856 available. Adding the following to a C<.htaccess> file would allow you
857 to simply use:
794858
795859 /module_name/run_mode
796860
797 If you have problems with mod_rewrite, turn on debugging to see exactly what's happening:
861 If you have problems with mod_rewrite, turn on debugging to see
862 exactly what's happening:
798863
799864 RewriteLog /home/project/logs/alpha-rewrite.log
800865 RewriteLogLevel 9
829894 be treated as a directory, and also supports multiple developer directories,
830895 so C</~mark> has its own separate dispatching system beneath it.
831896
832 Note that order matters here! The Location block for "/" needs to come before the
833 user blocks.
897 Note that order matters here! The Location block for "/" needs to come
898 before the user blocks.
834899
835900 <Location />
836901 RewriteEngine On
855920 # Run "/" through the dispatcher
856921 RewriteRule ^/home/mark/www/$ /~mark/cgi-bin/dispatch.cgi [L,QSA]
857922
858 # Otherwise, if an actual file or directory is requested, serve directly
923 # Otherwise, if an actual file or directory is requested, serve directly
859924 RewriteCond %{REQUEST_FILENAME} !-f
860925 RewriteCond %{REQUEST_FILENAME} !-d
861926
862 # Otherwise, pass everything through to the dispatcher
927 # Otherwise, pass everything through to the dispatcher
863928 RewriteRule ^(.*)$ /~mark/cgi-bin/dispatch.cgi/$1 [L,QSA]
864929
865930 # These examples may also be helpful, but are unrelated to dispatching.
871936
872937 =head1 SUBCLASSING
873938
874 While Dispatch tries to be flexible, it won't be able to do everything that people want. Hopefully
875 we've made it flexible enough so that if it doesn't do I<The Right Thing> you can easily subclass
876 it.
939 While Dispatch tries to be flexible, it won't be able to do everything
940 that people want. Hopefully we've made it flexible enough so that if
941 it doesn't do I<The Right Thing> you can easily subclass it.
877942
878943 =cut
879944
880945 #=head2 PROTECTED METHODS
881946 #
882 #The following methods are intended to be overridden by subclasses if necessary. They are not
883 #part of the public API since end users will never touch them. However, to ensure that your
884 #subclass of Dispatch does not break with a new release, they are documented here and are considered
885 #to be part of the API and will not be changed without very good reasons.
947 #The following methods are intended to be overridden by subclasses if
948 #necessary. They are not part of the public API since end users will
949 #never touch them. However, to ensure that your subclass of Dispatch
950 #does not break with a new release, they are documented here and are
951 #considered to be part of the API and will not be changed without very
952 #good reasons.
886953
887954 =head1 AUTHORS
888955
889956 Mark Stosberg <mark@summersault.com>
890957
891 Heavily based on CGI::Application::Dispatch, written by Michael Peters <mpeters@plusthree.com> and others
958 Heavily based on CGI::Application::Dispatch, written by Michael Peters
959 <mpeters@plusthree.com> and others
892960
893961 =head1 COMMUNITY
894962
895 This module is a part of the larger L<CGI::Application> community. If you have questions or
896 comments about this module then please join us on the cgiapp mailing list by sending a blank
897 message to "cgiapp-subscribe@lists.erlbaum.net". There is also a community wiki located at
898 L<http://www.cgi-app.org/>
963 This module is a part of the larger L<CGI::Application> community. If
964 you have questions or comments about this module then please join us
965 on the cgiapp mailing list by sending a blank message to
966 "cgiapp-subscribe@lists.erlbaum.net". There is also a community wiki
967 located at L<http://www.cgi-app.org/>
899968
900969 =head1 SOURCE CODE REPOSITORY
901970
9501019
9511020 =item dispatch_path()
9521021
953 The dispatch_path() method is not supported. The alternative is to reference C<< $env->{PATH_INFO} >> which is
954 available per the PSGI spec.
1022 The dispatch_path() method is not supported. The alternative is to
1023 reference C<< $env->{PATH_INFO} >> which is available per the PSGI
1024 spec.
9551025
9561026 =item handler()
9571027
958 This provided an Apache-specific handler. Other PSGI components like L<Plack::Handler::Apache2> provide
959 Apache handlers now instead.
1028 This provided an Apache-specific handler. Other PSGI components like
1029 L<Plack::Handler::Apache2> provide Apache handlers now instead.
9601030
9611031 =item _http_method()
9621032
963 This method has been eliminated. Check C<< $env->{REQUEST_METHOD} >> directly instead.
1033 This method has been eliminated. Check C<< $env->{REQUEST_METHOD} >>
1034 directly instead.
9641035
9651036 =item _parse_path()
9661037
967 The private _parse_path() method now accepts an additional argument, the PSGI C<< $env >> hash.
1038 The private _parse_path() method now accepts an additional argument,
1039 the PSGI C<< $env >> hash.
9681040
9691041 =item _run_app()
9701042
971 The private _run_app() method now accepts an additional argument, the PSGI C<< $env >> hash.
1043 The private _run_app() method now accepts an additional argument, the
1044 PSGI C<< $env >> hash.
9721045
9731046 =item _r()
9741047
77
88 =head1 NAME
99
10 CGI::Application::Dispatch::Regexp - Dispatch requests to CGI::Application based objects using regular expressions
10 CGI::Application::Dispatch::Regexp - Dispatch requests to
11 CGI::Application based objects using regular expressions
1112
1213 =head1 SYNOPSIS
1314
1415 use CGI::Application::Dispatch::Regexp;
1516
1617 CGI::Application::Dispatch::Regexp->dispatch(
17 prefix => 'MyApp',
18 table => [
19 '' => { app => 'Welcome', rm => 'start' },
20 qr|/([^/]+)/?| => { names => ['app'] },
21 qr|/([^/]+)/([^/]+)/?| => { names => [qw(app rm)] },
22 qr|/([^/]+)/([^/]+)/page(\d+)\.html?| => { names => [qw(app rm page)] },
23 ],
18 prefix => 'MyApp',
19 table => [
20 '' => { app => 'Welcome',
21 rm => 'start',
22 },
23 qr|/([^/]+)/?| => { names => ['app'],
24 },
25 qr|/([^/]+)/([^/]+)/?| => { names =>
26 [qw(app rm)]
27 },
28 qr|/([^/]+)/([^/]+)/page(\d+)\.html?| => { names =>
29 [qw(app rm page)]
30 },
31 ],
2432 );
2533
2634
2735 =head1 DESCRIPTION
2836
2937 L<CGI::Application::Dispatch> uses its own syntax dispatch table.
30 C<CGI::Application::Dispatch::Regexp> allows one to use flexible and powerful Perl
31 regular expressions to transform a path into argument list.
38 C<CGI::Application::Dispatch::Regexp> allows one to use flexible and
39 powerful Perl regular expressions to transform a path into argument
40 list.
3241
3342 =head1 DISPATCH TABLE
3443
4352
4453 Here's an example of defining a custom 'page' parameter:
4554
46 qr|/([^/]+)/([^/]+)/page(\d+)\.html/?| => { names => [qw(app rm page)] },
55 qr|/([^/]+)/([^/]+)/page(\d+)\.html/?| => {
56 names => [qw(app rm page)],
57 },
4758
4859
4960 =head1 COPYRIGHT & LICENSE
7182
7283 for(my $i = 0 ; $i < scalar(@$table) ; $i += 2) {
7384
74 # translate the rule into a regular expression, but remember where the named args are
85 # translate the rule into a regular expression, but remember
86 # where the named args are
7587 my $rule = $table->[$i];
7688
7789 warn
00 package CGI::Application::Dispatch;
11 use strict;
22 use warnings;
3 use Carp qw(carp cluck);
3 use Carp 'carp';
44 use Try::Tiny;
55
6 our $VERSION = '3.07';
6 our $VERSION = '3.12';
77 our $DEBUG = 0;
88
99 BEGIN {
107107
108108 =head1 DESCRIPTION
109109
110 This module provides a way (as a mod_perl handler or running under vanilla CGI) to look at
111 the path (as returned by L<dispatch_path>) of the incoming request, parse
112 off the desired module and its run mode, create an instance of that module and run it.
113
114 It currently supports both generations of mod_perl (1.x and 2.x). Although, for simplicity,
115 all examples involving Apache configuration and mod_perl code will be shown using mod_perl 1.x.
110 This module provides a way (as a mod_perl handler or running under
111 vanilla CGI) to look at the path (as returned by L<dispatch_path>) of
112 the incoming request, parse off the desired module and its run mode,
113 create an instance of that module and run it.
114
115 It currently supports both generations of mod_perl (1.x and
116 2.x). Although, for simplicity, all examples involving Apache
117 configuration and mod_perl code will be shown using mod_perl 1.x.
116118 This may change as mp2 usage increases.
117119
118120 It will translate a URI like this (under mod_perl):
132134
133135 =head2 dispatch(%args)
134136
135 This is the primary method used during dispatch. Even under mod_perl, the L<handler>
136 method uses this under the hood.
137 This is the primary method used during dispatch. Even under mod_perl,
138 the L<handler> method uses this under the hood.
137139
138140 #!/usr/bin/perl
139141 use strict;
155157
156158 =item prefix
157159
158 This option will set the string that will be prepended to the name of the application
159 module before it is loaded and created. So to use our previous example request of
160 This option will set the string that will be prepended to the name of
161 the application module before it is loaded and created. So to use our
162 previous example request of
160163
161164 /app/index.cgi/module_name/run_mode
162165
163 This would by default load and create a module named 'Module::Name'. But let's say that you
164 have all of your application specific modules under the 'My' namespace. If you set this option
165 to 'My' then it would instead load the 'My::Module::Name' application module instead.
166 This would by default load and create a module named
167 'Module::Name'. But let's say that you have all of your application
168 specific modules under the 'My' namespace. If you set this option to
169 'My' then it would instead load the 'My::Module::Name' application
170 module instead.
166171
167172 =item args_to_new
168173
169 This is a hash of arguments that are passed into the C<new()> constructor of the application.
174 This is a hash of arguments that are passed into the C<new()>
175 constructor of the application.
170176
171177 =item table
172178
173 In most cases, simply using Dispatch with the C<default> and C<prefix> is enough
174 to simplify your application and your URLs, but there are many cases where you want
175 more power. Enter the dispatch table. Since this table can be slightly complicated,
176 a whole section exists on its use. Please see the L<DISPATCH TABLE> section.
179 In most cases, simply using Dispatch with the C<default> and C<prefix>
180 is enough to simplify your application and your URLs, but there are
181 many cases where you want more power. Enter the dispatch table. Since
182 this table can be slightly complicated, a whole section exists on its
183 use. Please see the L<DISPATCH TABLE> section.
177184
178185 =item debug
179186
180 Set to a true value to send debugging output for this module to STDERR. Off by default.
187 Set to a true value to send debugging output for this module to
188 STDERR. Off by default.
181189
182190 =item error_document
183191
192200 character will be trimmed from final output.
193201
194202 B<A file with content of error document>
195 - if it starts with greater-than sign (C<<>). First character will be excluded
203 - if it starts with less-than sign (C<<>). First character will be excluded
196204 as well. Path of this file should be relative to server DOCUMENT_ROOT.
197205
198206 B<A URI to which the application will be redirected> - if no leading C<"> or
226234 # internal redirect to /errors/error404.html
227235 error_document => '/errors/error%s.html'
228236
229 # external redirect to http://host.domain/cgi-bin/errors.cgi?error=404
237 # external redirect to
238 # http://host.domain/cgi-bin/errors.cgi?error=404
230239 error_document => 'http://host.domain/cgi-bin/errors.cgi?error=%s'
231240
232241 =item auto_rest
233242
234 This tells Dispatch that you are using REST by default and that you care about which HTTP method
235 is being used. Dispatch will append the HTTP method name (upper case by default) to
236 the run mode that is determined after finding the appropriate dispatch rule. So a GET request
237 that translates into C<MyApp::Module->foo> will become C<MyApp::Module->foo_GET>.
243 This tells Dispatch that you are using REST by default and that you
244 care about which HTTP method is being used. Dispatch will append the
245 HTTP method name (upper case by default) to the run mode that is
246 determined after finding the appropriate dispatch rule. So a GET
247 request that translates into C<< MyApp::Module->foo >> will become
248 C<< MyApp::Module->foo_GET >>.
238249
239250 This can be overridden on a per-rule basis in a custom dispatch table.
240251
241252 =item auto_rest_lc
242253
243 In combinaion with L<auto_rest> this tells Dispatch that you prefer lower cased HTTP method names.
244 So instead of C<foo_POST> and C<foo_GET> you'll have C<foo_post> and C<foo_get>.
254 In combinaion with L<auto_rest> this tells Dispatch that you prefer
255 lower cased HTTP method names. So instead of C<foo_POST> and
256 C<foo_GET> you'll have C<foo_post> and C<foo_get>.
245257
246258 =back
247259
329341 unless exists($args{error_document});
330342 }
331343
332 %args = map { lc $_ => $args{$_} } keys %args; # lc for backwards compatability
344 %args = map { lc $_ => $args{$_} } keys %args; # lc for backwards
345 # compatability
333346
334347 # get the PATH_INFO
335348 my $path_info = $self->dispatch_path();
337350 # use the 'default' if we need to
338351 $path_info = $args{default} || '' if(!$path_info || $path_info eq '/');
339352
340 # make sure they all start and end with a '/', to correspond with the RE we'll make
353 # make sure they all start and end with a '/', to correspond with
354 # the RE we'll make
341355 $path_info = "/$path_info" unless(index($path_info, '/') == 0);
342356 $path_info = "$path_info/" unless(substr($path_info, -1) eq '/');
343357
389403
390404 my $auto_rest =
391405 defined $named_args->{auto_rest} ? $named_args->{auto_rest} : $args{auto_rest};
392 if($auto_rest) {
406 if($auto_rest && defined $rm && length $rm) {
393407 my $method_lc =
394408 defined $named_args->{auto_rest_lc}
395409 ? $named_args->{auto_rest_lc}
404418 $output = $self->_run_app($module, $rm, $local_args_to_new);
405419 } catch {
406420 my $e = $_;
407 unless ( ref $e ) {
408 local $@ = $e;
409 $e = Exception::Class->caught();
421 unless ( ref $e && $e->isa('Exception::Class::Base') ) {
422 $e = Exception::Class::Base->new($e);
410423 }
411424 $output = $self->http_error($e, $args{error_document});
412425 };
557570
558571 unless($output) {
559572
560 # TODO: possibly provide more feedback in a way that is XSS safe.
561 # (I'm not sure that passing through the raw ENV variable directly is safe.)
573 # TODO: possibly provide more feedback in a way that
574 # is XSS safe. (I'm not sure that passing through the
575 # raw ENV variable directly is safe.)
562576 # <P>We tried: $ENV{REQUEST_URI}</P></BODY></HTML>";
563577 $output = qq(
564578 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
629643 $rule =~ s/$http_method_regex//;
630644 }
631645
632 # make sure they start and end with a '/' to match how PATH_INFO is formatted
646 # make sure they start and end with a '/' to match how
647 # PATH_INFO is formatted
633648 $rule = "/$rule" unless(index($rule, '/') == 0);
634649 $rule = "$rule/" if(substr($rule, -1) ne '/');
635650
636651 my @names = ();
637652
638 # translate the rule into a regular expression, but remember where the named args are
653 # translate the rule into a regular expression, but remember
654 # where the named args are
639655 # '/:foo' will become '/([^\/]*)'
640656 # and
641657 # '/:bar?' will become '/?([^\/]*)?'
734750 PerlSetVar CGIAPP_DISPATCH_DEFAULT /module_name
735751 </Location>
736752
737 The above example would tell apache that any url beginning with /app will be handled by
738 CGI::Application::Dispatch. It also sets the prefix used to create the application module
739 to 'MyApp' and it tells CGI::Application::Dispatch that it shouldn't set the run mode
740 but that it will be determined by the application module as usual (through the query
741 string). It also sets a default application module to be used if there is no path.
742 So, a url of C</app/module_name> would create an instance of C<MyApp::Module::Name>.
743
744 Using this method will add the C<Apache->request> object to your application's C<PARAMS>
745 as 'r'.
753 The above example would tell apache that any url beginning with /app
754 will be handled by CGI::Application::Dispatch. It also sets the prefix
755 used to create the application module to 'MyApp' and it tells
756 CGI::Application::Dispatch that it shouldn't set the run mode but that
757 it will be determined by the application module as usual (through the
758 query string). It also sets a default application module to be used if
759 there is no path. So, a url of C</app/module_name> would create an
760 instance of C<MyApp::Module::Name>.
761
762 Using this method will add the C<Apache->request> object to your
763 application's C<PARAMS> as 'r'.
746764
747765 # inside your app
748766 my $request = $self->param('r');
749767
750 If you need more customization than can be accomplished with just L<prefix>
751 and L<default>, then it would be best to just subclass CGI::Application::Dispatch
752 and override L<dispatch_args> since C<handler()> uses L<dispatch> to do the heavy lifting.
768 If you need more customization than can be accomplished with just
769 L<prefix> and L<default>, then it would be best to just subclass
770 CGI::Application::Dispatch and override L<dispatch_args> since
771 C<handler()> uses L<dispatch> to do the heavy lifting.
753772
754773 package MyApp::Dispatch;
755774 use base 'CGI::Application::Dispatch';
791810 # setup our args to dispatch()
792811 my %args;
793812 my $config_args = $r->dir_config();
794 for my $var qw(DEFAULT PREFIX ERROR_DOCUMENT) {
813 for my $var (qw(DEFAULT PREFIX ERROR_DOCUMENT)) {
795814 my $dir_var = "CGIAPP_DISPATCH_$var";
796815 $args{lc($var)} = $config_args->{$dir_var}
797816 if($config_args->{$dir_var});
823842
824843 =head2 dispatch_args()
825844
826 Returns a hashref of args that will be passed to L<dispatch>(). It will return the following
827 structure by default.
845 Returns a hashref of args that will be passed to L<dispatch>(). It
846 will return the following structure by default.
828847
829848 {
830849 prefix => '',
835854 ],
836855 }
837856
838 This is the perfect place to override when creating a subclass to provide a richer dispatch
839 L<table>.
840
841 When called, it receives 1 argument, which is a reference to the hash of args passed into
842 L<dispatch>.
857 This is the perfect place to override when creating a subclass to
858 provide a richer dispatch L<table>.
859
860 When called, it receives 1 argument, which is a reference to the hash
861 of args passed into L<dispatch>.
843862
844863 =cut
845864
859878 =head2 translate_module_name($input)
860879
861880 This method is used to control how the module name is translated from
862 the matching section of the path (see L<"Path Parsing">.
863 The main reason that this method exists is so that it can be overridden if it doesn't do
864 exactly what you want.
881 the matching section of the path (see L<"Path Parsing">).
882 The main
883 reason that this method exists is so that it can be overridden if it
884 doesn't do exactly what you want.
865885
866886 The following transformations are performed on the input:
867887
897917
898918 =head2 require_module($module_name)
899919
900 This class method is used internally by CGI::Application::Dispatch to take a module
901 name (supplied by L<get_module_name>) and require it in a secure fashion. It
902 is provided as a public class method so that if you override other functionality of
903 this module, you can still safely require user specified modules. If there are
904 any problems requiring the named module, then we will C<croak>.
920 This class method is used internally by CGI::Application::Dispatch to
921 take a module name (supplied by L<get_module_name>) and require it in
922 a secure fashion. It is provided as a public class method so that if
923 you override other functionality of this module, you can still safely
924 require user specified modules. If there are any problems requiring
925 the named module, then we will C<croak>.
905926
906927 CGI::Application::Dispatch->require_module('MyApp::Module::Name');
907928
958979 ]
959980 );
960981
961 So first, this call to L<dispatch> sets the L<prefix> and passes a C<TMPL_PATH>
962 into L<args_to_new>. Next it sets the L<table>.
982 So first, this call to L<dispatch> sets the L<prefix> and passes a
983 C<TMPL_PATH> into L<args_to_new>. Next it sets the L<table>.
963984
964985
965986 =head2 VOCABULARY
966987
967988 Just so we all understand what we're talking about....
968989
969 A table is an array where the elements are gouped as pairs (similar to a hash's
970 key-value pairs, but as an array to preserve order). The first element of each pair
971 is called a C<rule>. The second element in the pair is called the rule's C<arg list>.
972 Inside a rule there are slashes C</>. Anything set of characters between slashes
973 is called a C<token>.
990 A table is an array where the elements are gouped as pairs (similar to
991 a hash's key-value pairs, but as an array to preserve order). The
992 first element of each pair is called a C<rule>. The second element in
993 the pair is called the rule's C<arg list>. Inside a rule there are
994 slashes C</>. Anything set of characters between slashes is called a
995 C<token>.
974996
975997 =head2 URL MATCHING
976998
977 When a URL comes in, Dispatch tries to match it against each rule in the table in
978 the order in which the rules are given. The first one to match wins.
999 When a URL comes in, Dispatch tries to match it against each rule in
1000 the table in the order in which the rules are given. The first one to
1001 match wins.
9791002
9801003 A rule consists of slashes and tokens. A token can one of the following types:
9811004
9921015
9931016 =item variable
9941017
995 Any token which begins with a colon (C<:>) is a variable token. These are simply
996 wild-card place holders in the rule that will match anything in the URL that isn't
997 a slash. These variables can later be referred to by using the C<< $self->param >>
998 mechanism. In the rule
1018 Any token which begins with a colon (C<:>) is a variable token. These
1019 are simply wild-card place holders in the rule that will match
1020 anything in the URL that isn't a slash. These variables can later be
1021 referred to by using the C<< $self->param >> mechanism. In the rule
9991022
10001023 'posts/:category'
10011024
1002 C<:category> is a variable token. If the URL matched this rule, then you could retrieve
1003 the value of that token from whithin your application like so:
1025 C<:category> is a variable token. If the URL matched this rule, then
1026 you could retrieve the value of that token from whithin your
1027 application like so:
10041028
10051029 my $category = $self->param('category');
10061030
1007 There are some variable tokens which are special. These can be used to further customize
1008 the dispatching.
1031 There are some variable tokens which are special. These can be used to
1032 further customize the dispatching.
10091033
10101034 =over
10111035
10121036 =item :app
10131037
1014 This is the module name of the application. The value of this token will be sent to the
1015 L<translate_module_name> method and then prefixed with the L<prefix> if there is one.
1038 This is the module name of the application. The value of this token
1039 will be sent to the L<translate_module_name> method and then prefixed
1040 with the L<prefix> if there is one.
10161041
10171042 =item :rm
10181043
1019 This is the run mode of the application. The value of this token will be the actual name
1020 of the run mode used.
1044 This is the run mode of the application. The value of this token will be the
1045 actual name of the run mode used. The run mode can be optional, as
1046 noted below. Example:
1047
1048 /foo/:rm?
1049
1050 If no run mode is found, it will default to using the C<< start_mode() >>, just like
1051 invoking CGI::Application directly. Both of these URLs would end up dispatching
1052 to the start mode associated with /foo:
1053
1054 /foo/
1055 /foo
10211056
10221057 =back
10231058
10241059 =item optional-variable
10251060
1026 Any token which begins with a colon (C<:>) and ends with a question mark (<?>) is considered
1027 optional. If the rest of the URL matches the rest of the rule, then it doesn't matter whether
1028 it contains this token or not. It's best to only include optional-variable tokens at the end
1029 of your rule. In the rule
1061 Any token which begins with a colon (C<:>) and ends with a question
1062 mark (<?>) is considered optional. If the rest of the URL matches the
1063 rest of the rule, then it doesn't matter whether it contains this
1064 token or not. It's best to only include optional-variable tokens at
1065 the end of your rule. In the rule
10301066
10311067 'date/:year/:month?/:day?'
10321068
10331069 C<:month?> and C<:day?> are optional-variable tokens.
10341070
1035 Just like with L<variable> tokens, optional-variable tokens' values can also be retrieved by
1036 the application, if they existed in the URL.
1071 Just like with L<variable> tokens, optional-variable tokens' values
1072 can also be retrieved by the application, if they existed in the URL.
10371073
10381074 if( defined $self->param('month') ) {
10391075 ...
10411077
10421078 =item wildcard
10431079
1044 The wildcard token "*" allows for partial matches. The token MUST appear at the end of the
1045 rule.
1080 The wildcard token "*" allows for partial matches. The token MUST
1081 appear at the end of the rule.
10461082
10471083 'posts/list/*'
10481084
1049 By default, the C<dispatch_url_remainder> param is set to the remainder of the URL
1050 matched by the *. The name of the param can be changed by setting "*" argument in the
1051 L<ARG LIST>.
1085 By default, the C<dispatch_url_remainder> param is set to the
1086 remainder of the URL matched by the *. The name of the param can be
1087 changed by setting "*" argument in the L<ARG LIST>.
10521088
10531089 'posts/list/*' => { '*' => 'post_list_filter' }
10541090
10551091 =item method
10561092
1057 You can also dispatch based on HTTP method. This is similar to using L<auto_rest> but
1058 offers more fine grained control. You include the method (case insensitive) at the end of
1059 the rule and enclose it in square brackets.
1093 You can also dispatch based on HTTP method. This is similar to using
1094 L<auto_rest> but offers more fine grained control. You include the
1095 method (case insensitive) at the end of the rule and enclose it in
1096 square brackets.
10601097
10611098 ':app/news[post]' => { rm => 'add_news' },
10621099 ':app/news[get]' => { rm => 'news' },
10641101
10651102 =back
10661103
1067 The main reason that we don't use regular expressions for dispatch rules is that regular
1068 expressions provide no mechanism for named back references, like variable tokens do.
1104 The main reason that we don't use regular expressions for dispatch
1105 rules is that regular expressions provide no mechanism for named back
1106 references, like variable tokens do.
10691107
10701108 =head2 ARG LIST
10711109
1072 Each rule can have an accompanying arg-list. This arg list can contain special arguments
1073 that override something set higher up in L<dispatch> for this particular URL, or just
1074 have additional args passed available in C<< $self->param() >>
1075
1076 For instance, if you want to override L<prefix> for a specific rule, then you can do so.
1110 Each rule can have an accompanying arg-list. This arg list can contain
1111 special arguments that override something set higher up in L<dispatch>
1112 for this particular URL, or just have additional args passed available
1113 in C<< $self->param() >>
1114
1115 For instance, if you want to override L<prefix> for a specific rule,
1116 then you can do so.
10771117
10781118 'admin/:app/:rm' => { prefix => 'MyApp::Admin' },
10791119
10801120 =head1 Path Parsing
10811121
1082 This section will describe how the application module and run mode are determined from
1083 the path if no L<DISPATCH TABLE> is present, and what options you have to
1084 customize the process. The value for the path to be parsed is retrieved from
1085 the L<dispatch_path> method, which by default uses the C<PATH_INFO> environment
1086 variable.
1122 This section will describe how the application module and run mode are
1123 determined from the path if no L<DISPATCH TABLE> is present, and what
1124 options you have to customize the process. The value for the path to
1125 be parsed is retrieved from the L<dispatch_path> method, which by
1126 default uses the C<PATH_INFO> environment variable.
10871127
10881128 =head2 Getting the module name
10891129
1090 To get the name of the application module the path is split on backslahes (C</>).
1091 The second element of the returned list (the first is empty) is used to create the application module. So if we
1092 have a path of
1130 To get the name of the application module the path is split on
1131 backslahes (C</>). The second element of the returned list (the first
1132 is empty) is used to create the application module. So if we have a
1133 path of
10931134
10941135 /module_name/mode1
10951136
1096 then the string 'module_name' is used. This is passed through the L<translate_module_name>
1097 method. Then if there is a C<prefix> (and there should always be a L<prefix>) it is added
1098 to the beginning of this new module name with a double colon C<::> separating the two.
1099
1100 If you don't like the exact way that this is done, don't fret you do have a couple of options.
1101 First, you can specify a L<DISPATCH TABLE> which is much more powerful and flexible (in fact
1102 this default behavior is actually implemented internally with a dispatch table).
1103 Or if you want something a little simpler, you can simply subclass and extend the
1104 L<translate_module_name> method.
1137 then the string 'module_name' is used. This is passed through the
1138 L<translate_module_name> method. Then if there is a C<prefix> (and
1139 there should always be a L<prefix>) it is added to the beginning of
1140 this new module name with a double colon C<::> separating the two.
1141
1142 If you don't like the exact way that this is done, don't fret you do
1143 have a couple of options. First, you can specify a L<DISPATCH TABLE>
1144 which is much more powerful and flexible (in fact this default
1145 behavior is actually implemented internally with a dispatch table).
1146 Or if you want something a little simpler, you can simply subclass and
1147 extend the L<translate_module_name> method.
11051148
11061149 =head2 Getting the run mode
11071150
1108 Just like the module name is retrieved from splitting the path on slashes, so is the
1109 run mode. Only instead of using the second element of the resulting list, we use the third
1110 as the run mode. So, using the same example, if we have a path of
1151 Just like the module name is retrieved from splitting the path on
1152 slashes, so is the run mode. Only instead of using the second element
1153 of the resulting list, we use the third as the run mode. So, using the
1154 same example, if we have a path of
11111155
11121156 /module_name/mode2
11131157
11191163
11201164 =item * CGI query strings
11211165
1122 CGI query strings are unaffected by the use of C<PATH_INFO> to obtain the module name and run mode.
1123 This means that any other modules you use to get access to you query argument (ie, L<CGI>,
1124 L<Apache::Request>) should not be affected. But, since the run mode may be determined by
1125 CGI::Application::Dispatch having a query argument named 'rm' will be ignored by your application
1126 module.
1166 CGI query strings are unaffected by the use of C<PATH_INFO> to obtain
1167 the module name and run mode. This means that any other modules you
1168 use to get access to you query argument (ie, L<CGI>,
1169 L<Apache::Request>) should not be affected. But, since the run mode
1170 may be determined by CGI::Application::Dispatch having a query
1171 argument named 'rm' will be ignored by your application module.
11271172
11281173 =back
11291174
11331178
11341179 /cgi-bin/dispatch.cgi/module_name/run_mode
11351180
1136 However, including "/cgi-bin/dispatch.cgi" in ever URL doesn't add any value to the URL,
1137 so it's nice to remove it. This is easily done if you are using the Apache web server with
1138 C<mod_rewrite> available. Adding the following to a C<.htaccess> file would allow you to
1139 simply use:
1181 However, including "/cgi-bin/dispatch.cgi" in ever URL doesn't add any
1182 value to the URL, so it's nice to remove it. This is easily done if
1183 you are using the Apache web server with C<mod_rewrite>
1184 available. Adding the following to a C<.htaccess> file would allow you
1185 to simply use:
11401186
11411187 /module_name/run_mode
11421188
1143 If you have problems with mod_rewrite, turn on debugging to see exactly what's happening:
1189 If you have problems with mod_rewrite, turn on debugging to see
1190 exactly what's happening:
11441191
11451192 RewriteLog /home/project/logs/alpha-rewrite.log
11461193 RewriteLogLevel 9
11751222 be treated as a directory, and also supports multiple developer directories,
11761223 so C</~mark> has its own separate dispatching system beneath it.
11771224
1178 Note that order matters here! The Location block for "/" needs to come before the
1179 user blocks.
1225 Note that order matters here! The Location block for "/" needs to come
1226 before the user blocks.
11801227
11811228 <Location />
11821229 RewriteEngine On
12011248 # Run "/" through the dispatcher
12021249 RewriteRule ^/home/mark/www/$ /~mark/cgi-bin/dispatch.cgi [L,QSA]
12031250
1204 # Otherwise, if an actual file or directory is requested, serve directly
1251 # Otherwise, if an actual file or directory is requested,
1252 # serve directly
12051253 RewriteCond %{REQUEST_FILENAME} !-f
12061254 RewriteCond %{REQUEST_FILENAME} !-d
12071255
1208 # Otherwise, pass everything through to the dispatcher
1256 # Otherwise, pass everything through to the dispatcher
12091257 RewriteRule ^(.*)$ /~mark/cgi-bin/dispatch.cgi/$1 [L,QSA]
12101258
12111259 # These examples may also be helpful, but are unrelated to dispatching.
12171265
12181266 =head1 SUBCLASSING
12191267
1220 While Dispatch tries to be flexible, it won't be able to do everything that people want. Hopefully
1221 we've made it flexible enough so that if it doesn't do I<The Right Thing> you can easily subclass
1222 it.
1268 While Dispatch tries to be flexible, it won't be able to do everything
1269 that people want. Hopefully we've made it flexible enough so that if
1270 it doesn't do I<The Right Thing> you can easily subclass it.
12231271
12241272 =cut
12251273
12261274 #=head2 PROTECTED METHODS
12271275 #
1228 #The following methods are intended to be overridden by subclasses if necessary. They are not
1229 #part of the public API since end users will never touch them. However, to ensure that your
1230 #subclass of Dispatch does not break with a new release, they are documented here and are considered
1231 #to be part of the API and will not be changed without very good reasons.
1276 #The following methods are intended to be overridden by subclasses if
1277 #necessary. They are not part of the public API since end users will
1278 #never touch them. However, to ensure that your subclass of Dispatch
1279 #does not break with a new release, they are documented here and are
1280 #considered to be part of the API and will not be changed without very
1281 #good reasons.
12321282
12331283 =head1 AUTHOR
12341284
12351285 Michael Peters <mpeters@plusthree.com>
12361286
1237 Thanks to Plus Three, LP (http://www.plusthree.com) for sponsoring my work on this module
1287 Thanks to Plus Three, LP (http://www.plusthree.com) for sponsoring my
1288 work on this module
12381289
12391290 =head1 COMMUNITY
12401291
1241 This module is a part of the larger L<CGI::Application> community. If you have questions or
1242 comments about this module then please join us on the cgiapp mailing list by sending a blank
1243 message to "cgiapp-subscribe@lists.erlbaum.net". There is also a community wiki located at
1244 L<http://www.cgi-app.org/>
1292 This module is a part of the larger L<CGI::Application> community. If
1293 you have questions or comments about this module then please join us
1294 on the cgiapp mailing list by sending a blank message to
1295 "cgiapp-subscribe@lists.erlbaum.net". There is also a community wiki
1296 located at L<http://www.cgi-app.org/>
12451297
12461298 =head1 SOURCE CODE REPOSITORY
12471299
12801332
12811333 =head1 SECURITY
12821334
1283 Since C::A::Dispatch will dynamically choose which modules to use as the content generators,
1284 it may give someone the ability to execute random modules on your system if those modules can
1285 be found in you path. Of course those modules would have to behave like L<CGI::Application> based
1286 modules, but that still opens up the door more than most want. This should only be a problem
1287 if you don't use a L<prefix>. By using this option you are only allowing Dispatch to pick from
1288 a namespace of modules to run.
1335 Since C::A::Dispatch will dynamically choose which modules to use as
1336 the content generators, it may give someone the ability to execute
1337 random modules on your system if those modules can be found in you
1338 path. Of course those modules would have to behave like
1339 L<CGI::Application> based modules, but that still opens up the door
1340 more than most want. This should only be a problem if you don't use a
1341 L<prefix>. By using this option you are only allowing Dispatch to pick
1342 from a namespace of modules to run.
12891343
12901344 =head1 SEE ALSO
12911345
00 package MyApp::Module::Name;
11 use base 'CGI::Application';
2 use HTTP::Exception;
23
34 sub setup {
45 my $self = shift;
1011 rm4
1112 rm5
1213 local_args_to_new
14 throw_http_exception
1315 /]);
16 $self->error_mode('rethrow_http_exceptions');
1417 }
1518
1619 sub rm1 {
5760 return $self->tmpl_path;
5861 }
5962
63 sub throw_http_exception {
64 HTTP::Exception->throw(405, status_message => 'my 405 exception!');
65 }
66
67 sub rethrow_http_exceptions {
68 my $self = shift;
69 my $e = shift;
70
71 # Duck-type to see if we have an HTTP::Exception
72 if (defined $e && $e->can('status_method')) {
73 die $e;
74 }
75 # In this case, just die then, too...
76 else {
77 die $e;
78 }
79
80 }
6081
6182 1;
22
33 sub setup {
44 my $self = shift;
5 $self->start_mode('rm1');
5 $self->start_mode('rm1_GET');
66 $self->run_modes([qw/
77 rm1_GET
88 rm1_POST
168168 'named url remainder';
169169 };
170170
171 # args_to_new
171 # args_to_new, throwing HTTP::Exceptions
172172 test_psgi
173173 app => CGI::Application::Dispatch::PSGI->as_psgi(
174174 prefix => 'MyApp',
177177 ),
178178 client => sub {
179179 my $cb = shift;
180 like
181 $cb->(GET '/module_name/local_args_to_new')->content,
180
181 # args_to_new
182 like $cb->(GET '/module_name/local_args_to_new')->content,
182183 qr/events/,
183184 'args_to_new works';
185
186 # When an HTTP::Exception is thrown from error_mode, it is passed through.
187 my $res = $cb->(GET '/module_name/throw_http_exception');
188 is($res->code,405,"a thrown HTTP::Exception is bubbled up");
189 like($res->as_string, qr/my 405 exception/, "HTTP::Exception content is passed along");
184190 };
185191
186192 # 404
196202 qr/404 not found/i,
197203 };
198204
205 # auto_rest
206 test_psgi
207 app => CGI::Application::Dispatch::PSGI->as_psgi(
208 auto_rest => 1,
209 prefix => 'MyApp',
210 table => [
211 ':app/rm3[get]' => { rm => 'get_rm3', auto_rest => 0 },
212 ':app/rm4' => { auto_rest => 0, rm => 'rm4' },
213 ':app/rm2' => { auto_rest_lc => 1, rm => 'rm2' },
214 ':app/:rm?' => { },
215 ],
216 ),
217 client => sub {
218 my $cb = shift;
219 my $res = $cb->(GET '/module_rest/rm1');
220 ok($res->is_success);
221 like($res->content, qr{MyApp::Module::Rest->rm1_GET}, 'auto_rest GET');
222
223 $res = $cb->(POST '/module_rest/rm1');
224 ok($res->is_success);
225 like($res->content, qr{MyApp::Module::Rest->rm1_POST}, 'auto_rest POST');
226
227 $res = $cb->(POST '/module_rest/rm2');
228 ok($res->is_success);
229 $content = $res->content;
230 like($res->content, qr{App::Module::Rest->rm2_post}, 'auto_rest_lc POST');
231
232 $res = $cb->(GET '/module_rest/rm3');
233 ok($res->is_success);
234 $content = $res->content;
235 like($res->content, qr{App::Module::Rest->get_rm3}, 'HTTP method in rule');
236
237 $res = $cb->(GET '/module_rest/rm4');
238 ok($res->is_success);
239 like($res->content, qr{App::Module::Rest->rm4}, 'non-auto_rest GET');
240 unlike($res->content, qr{App::Module::Rest->rm4_GET}, 'non-auto_rest GET');
241
242 $res = $cb->(POST '/module_rest/rm4');
243 ok($res->is_success);
244 like($res->content, qr{App::Module::Rest->rm4}, 'non-auto_rest POST');
245 unlike($res->content, qr{App::Module::Rest->rm4_POST}, 'non-auto_rest POST');
246
247 $res = $cb->(GET '/module_rest');
248 ok($res->is_success);
249 like($res->content, qr{MyApp::Module::Rest->rm1_GET}, 'auto_rest check of /:rm? and start_mode');
250 };
251
199252 # restore STDERR
200253 {
201254 close STDERR;