File Coverage

blib/lib/Apache2/Controller/Funk.pm
Criterion Covered Total %
statement 28 30 93.3
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 38 40 95.0


line stmt bran cond sub pod time code
1             package Apache2::Controller::Funk;
2              
3             =head1 NAME
4              
5             Apache2::Controller::Funk
6              
7             =head1 VERSION
8              
9             Version 1.001.001
10              
11             =cut
12              
13 1     1   2502 use version;
  1         3  
  1         10  
14             our $VERSION = version->new('1.001.001');
15              
16             =head1 SYNOPSIS
17              
18             $bool = controller_allows_method($class, $method);
19              
20             check_allowed_method($class, $method); # throws NOT_FOUND exception
21              
22             =head1 DESCRPTION
23              
24             Useful routines for both Apache2::Controller and Apache2::Controller::Dispatch
25             objects to run. Results and whether to 'require' are cached in this package's
26             namespace across requests, optimizing efficiency per mod_perl2 child, and are
27             queried futher using 'exists', which is very fast.
28              
29             =cut
30              
31 1     1   92 use strict;
  1         2  
  1         42  
32 1     1   6 use warnings FATAL => 'all';
  1         3  
  1         55  
33 1     1   5 use English '-no_match_vars';
  1         2  
  1         20  
34              
35 1     1   449 use base 'Exporter';
  1         2  
  1         63  
36              
37 1     1   1339 use Log::Log4perl qw( :easy );
  1         61959  
  1         7  
38 1     1   1601 use Readonly;
  1         3177  
  1         49  
39 1     1   7 use YAML::Syck;
  1         2  
  1         49  
40              
41 1     1   5 use Apache2::Controller::X;
  1         1  
  1         38  
42 1     1   425 use Apache2::Const -compile => qw( NOT_FOUND );
  0            
  0            
43              
44             our @EXPORT_OK = qw(
45             controller_allows_method
46             check_allowed_method
47             log_bad_request_reason
48             default_consumer_secret
49             );
50              
51             # this was dumb... this should really be a directive.
52             # or it should let whatever pipe downstream do whatever it needs to.
53             Readonly my $ACCESS_LOG_REASON_LENGTH => 512;
54              
55             =head1 IMPORTABLE FUNCTIONS
56              
57             =head2 controller_allows_method
58              
59             $bool = controller_allows_method($class, $method); # controller_allows_method()
60              
61             Ask if method name is returned by C<< allowed_methods() >>
62             in the given controller package.
63              
64             Only two 'exists' calls are required for each query after caching the
65             first result for this child.
66              
67             =cut
68              
69             my %allowed_methods = ( );
70             sub controller_allows_method {
71             my ($class, $method) = @_;
72              
73             a2cx "class undefined" if !defined $class;
74             a2cx "method undefined" if !defined $method;
75             DEBUG(sub{
76             "checking class '$class', method '$method', allowed is:\n"
77             .Dump(\%allowed_methods)
78             });
79              
80             # check that the method is allowed.
81             # make sure the selected method is allowed in the controller class
82              
83             if (!exists $allowed_methods{$class}) {
84              
85             eval "require $class;";
86             a2cx "cannot require $class: $EVAL_ERROR" if $EVAL_ERROR;
87              
88             my $isa_a2c;
89             eval "\$isa_a2c = $class->isa('Apache2::Controller');";
90             a2cx "$class is not an Apache2::Controller" unless $isa_a2c;
91              
92             a2cx "$class knows no allowed_methods()"
93             unless $class->can('allowed_methods');
94              
95             my @allowed_methods = $class->allowed_methods();
96              
97             DEBUG("allowed_methods: (@allowed_methods)");
98             $allowed_methods{$class} = { map {($_=>1)} @allowed_methods };
99             DEBUG(sub{Dump(\%allowed_methods)});
100             }
101             return exists $allowed_methods{$class}{$method};
102             }
103              
104             =head2 check_allowed_method
105              
106             check_allowed_method($method, $class); # check_allowed_method()
107              
108             Throw a NOT_FOUND exception if the method is not an allowed method
109             in the C<< allowed_methods() >> list in the controller package.
110              
111             =cut
112              
113             sub check_allowed_method {
114             my ($class, $method) = @_;
115             a2cx "class undefined" if !defined $class;
116             a2cx "method undefined" if !defined $method;
117             DEBUG("checking class '$class', method '$method'");
118              
119             if (!controller_allows_method($class, $method)) {
120             DEBUG("Method $method not allowed in $class.");
121             a2cx message => "Method $method not allowed from $class.",
122             status => Apache2::Const::NOT_FOUND;
123             }
124             return;
125             }
126              
127             =head2 log_bad_request_reason( )
128              
129             log_bad_request_reason( $r, $X );
130              
131             Call $r->log_reason( $msg, $r->uri() ) where $msg is a truncated
132             version of $X in case $X is too long.
133              
134             =cut
135              
136             sub log_bad_request_reason {
137             my ($r, $X) = @_;
138             a2cx 'usage: log_bad_request_reason($r, $X)'
139             if !$r || !ref($r) || !$r->can('log_reason') || !$X;
140            
141             my $x_text = "$X";
142             my $reason = $ACCESS_LOG_REASON_LENGTH < length $x_text
143             ? substr($x_text, 0, $ACCESS_LOG_REASON_LENGTH)
144             : $x_text;
145             $r->log_reason( $reason, $r->uri() );
146             return;
147             }
148              
149             1;