File Coverage

blib/lib/Dancer/Plugin/BeforeRoute.pm
Criterion Covered Total %
statement 43 43 100.0
branch 28 28 100.0
condition n/a
subroutine 8 8 100.0
pod n/a
total 79 79 100.0


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3            
4             Dancer::Plugin::BeforeRoute - A before hook for a specify route or routes
5            
6             =head1 USAGE
7              
8             use Dancer::Plugin::BeforeRoute;
9              
10             before_route get => "/", sub {
11             var before_run => "homepage";
12             };
13              
14             before_route ["get", "post"] => "/", sub {
15             var before_run => "homepage";
16             };
17              
18             get "/" => sub {
19             ## Return "homepage"
20             return var "before_run";
21             };
22              
23             before_route get => "/foo", sub {
24             var before_run => "foo"
25             };
26              
27             get "/foo" => sub {
28             ## Return "foo"
29             return var "before_run";
30             };
31              
32             before_template_route
33              
34             =head1 DESCRIPTION
35              
36             Dancer provides hook before to do everythings before going any route.
37              
38             This plugin is to provide a little bit more specifically hook before route or route(s) executed.
39              
40             =head1 AUTHOR
41            
42             Michael Vu, C<< >>
43            
44             =head1 BUGS
45            
46             Please report any bugs or feature requests to C, or through
47             the web interface at L. I will be notified, and then you'll
48             automatically be notified of progress on your bug as I make changes.
49            
50             =head1 SUPPORT
51            
52             You can find documentation for this module with the perldoc command.
53            
54             perldoc Dancer::Plugin::BeforeRoute
55            
56             You can also look for information at:
57            
58             =over 4
59            
60             =item * RT: CPAN's request tracker
61            
62             L
63            
64             =item * AnnoCPAN: Annotated CPAN documentation
65            
66             L
67            
68             =item * CPAN Ratings
69            
70             L
71            
72             =item * Search CPAN
73            
74             L
75            
76             =item * GIT Respority
77            
78             L
79            
80             =back
81            
82             =head1 ACKNOWLEDGEMENTS
83            
84             This program is free software; you can redistribute it and/or modify it
85             under the same terms as Perl itself.
86              
87             =cut
88              
89             package Dancer::Plugin::BeforeRoute;
90             $Dancer::Plugin::BeforeRoute::VERSION = '1.1';
91 5     5   568132 use Carp "confess";
  5         7  
  5         232  
92 5     5   967 use Dancer ":syntax";
  5         298726  
  5         22  
93 5     5   3534 use Dancer::Plugin;
  5         4653  
  5         2252  
94              
95             my @ROUTES = ();
96              
97             hook before => sub {
98             ROUTE:
99             foreach my $route (@ROUTES) {
100             next ROUTE
101             if !request_for( $route->{path}, @{ $route->{methods} } );
102             $route->{subref}->(@_);
103             }
104             };
105              
106             register before_route => sub {
107 6     6   957 my ( $path, $subref, @methods ) = _args(@_);
108 6         24 push @ROUTES,
109             {
110             methods => \@methods,
111             path => $path,
112             subref => $subref,
113             };
114             };
115              
116             register request_for => sub {
117 32     32   36 my ( $path, @methods ) = @_;
118              
119 32         58 my $request_method = request->method;
120 32         210 my $request_path = request->path_info;
121              
122             # Shared portion of the log message,
123             # for both when the request matches and when it does not.
124 32         175 my $match_message = q{};
125              
126 32         59 grep {
127 32         30 $match_message = "'$request_method $request_path' against '$_ $path'";
128             # Mismatches only logged at debug to remove excessive log volume.
129 32         60 debug "Trying to match $match_message"
130             } @methods;
131              
132 32 100       842 if ( !_is_the_right_method( $request_method, @methods ) ) {
133 9         25 return;
134             }
135              
136 23 100       40 if ( !_is_the_right_path( $request_path, $path ) ) {
137 12         41 return;
138             }
139              
140 11         42 info "Matched $match_message --> got 1";
141              
142 11         289 return 1;
143             };
144              
145             sub _args {
146 11 100   11   2788 my $methods = shift
147             or confess "dev: missing method\n";
148              
149 10 100       29 my @methods = ref $methods ? @$methods : ($methods);
150              
151 10 100       114 my $path = shift
152             or confess "dev: missing path\n";
153 9 100       152 my $subref = shift
154             or confess "dev: missing a subref -> [[ @methods: $path ]]\n";
155              
156 8         20 return ( $path, $subref, @methods );
157             }
158              
159             sub _is_the_right_method {
160 32     32   30 my $method = shift;
161 32 100       57 if ( $method eq "HEAD" ) {
162 3         5 $method = "get";
163             }
164 32         39 my @methods = @_;
165 32 100       24 return ( grep { ( lc($_) eq "any" ) || /^\Q$method\E$/i } @methods )
  32 100       247  
166             ? 1
167             : 0;
168             }
169              
170             sub _is_the_right_path {
171 23     23   21 my $got_path = shift;
172 23         15 my $expected_path = shift;
173 23 100       33 if ( ref $expected_path ) {
174 2 100       10 return $got_path =~ /$expected_path/ ? 1 : 0;
175             }
176 21 100       50 if ( $expected_path =~ /\:/ ) {
177 3         10 $expected_path =~ s/\:[^\/]+/[^\/]+/g;
178 3 100       32 return $got_path =~ /^$expected_path$/ ? 1 : 0;
179             }
180 18 100       43 return $got_path eq $expected_path ? 1 : 0;
181             }
182              
183             register_plugin;