File Coverage

blib/lib/Catalyst/ActionRole/HTTPMethods.pm
Criterion Covered Total %
statement 9 9 100.0
branch 4 6 66.6
condition n/a
subroutine 3 3 100.0
pod 1 1 100.0
total 17 19 89.4


line stmt bran cond sub pod time code
1             package Catalyst::ActionRole::HTTPMethods;
2              
3 86     86   81805 use Moose::Role;
  86         288  
  86         1162  
4              
5             requires 'match', 'match_captures', 'list_extra_info';
6              
7 58 50   58 1 103 sub allowed_http_methods { @{shift->attributes->{Method}||[]} }
  58         1567  
8              
9             sub _has_expected_http_method {
10 58     58   156 my ($self, $expected) = @_;
11 58 50       180 return 1 unless scalar(my @allowed = $self->allowed_http_methods);
12 58 100       147 return scalar(grep { lc($_) eq lc($expected) } @allowed) ?
  69         503  
13             1 : 0;
14             }
15              
16             around ['match','match_captures'] => sub {
17             my ($orig, $self, $ctx, @args) = @_;
18             return 0 unless $self->$orig($ctx, @args);
19              
20             my $expected = $ctx->req->method;
21             return $self->_has_expected_http_method($expected);
22             };
23              
24             around 'list_extra_info' => sub {
25             my ($orig, $self, @args) = @_;
26             return {
27             %{ $self->$orig(@args) },
28             HTTP_METHODS => [sort $self->allowed_http_methods],
29             };
30             };
31              
32             1;
33              
34             =head1 NAME
35              
36             Catalyst::ActionRole::HTTPMethods - Match on HTTP Methods
37              
38             =head1 SYNOPSIS
39              
40             package MyApp::Web::Controller::MyController;
41              
42             use Moose;
43             use MooseX::MethodAttributes;
44              
45             extends 'Catalyst::Controller';
46              
47             sub user_base : Chained('/') CaptureArg(0) { ... }
48              
49             sub get_user : Chained('user_base') Args(1) GET { ... }
50             sub post_user : Chained('user_base') Args(1) POST { ... }
51             sub put_user : Chained('user_base') Args(1) PUT { ... }
52             sub delete_user : Chained('user_base') Args(1) DELETE { ... }
53             sub head_user : Chained('user_base') Args(1) HEAD { ... }
54             sub options_user : Chained('user_base') Args(1) OPTIONS { ... }
55             sub patch_user : Chained('user_base') Args(1) PATCH { ... }
56              
57              
58             sub post_and_put : Chained('user_base') POST PUT Args(1) { ... }
59             sub method_attr : Chained('user_base') Method('DELETE') Args(0) { ... }
60              
61             __PACKAGE__->meta->make_immutable;
62              
63             =head1 DESCRIPTION
64              
65             This is an action role that lets your L<Catalyst::Action> match on standard
66             HTTP methods, such as GET, POST, etc.
67              
68             Since most web browsers have limited support for rich HTTP Method vocabularies
69             we use L<Plack::Middleware::MethodOverride> which allows you to 'tunnel' your
70             request method over POST This works in two ways. You can set an extension
71             HTTP header C<X-HTTP-Method-Override> which will contain the value of the
72             desired request method, or you may set a search query parameter
73             C<x-tunneled-method>. Remember, these only work over HTTP Request type
74             POST. See L<Plack::Middleware::MethodOverride> for more.
75              
76             =head1 REQUIRES
77              
78             This role requires the following methods in the consuming class.
79              
80             =head2 match
81              
82             =head2 match_captures
83              
84             Returns 1 if the action matches the existing request and zero if not.
85              
86             =head1 METHODS
87              
88             This role defines the following methods
89              
90             =head2 match
91              
92             =head2 match_captures
93              
94             Around method modifier that return 1 if the request method matches one of the
95             allowed methods (see L</http_methods>) and zero otherwise.
96              
97             =head2 allowed_http_methods
98              
99             An array of strings that are the allowed http methods for matching this action
100             normalized as noted above (using X-Method* overrides).
101              
102             =head2 list_extra_info
103              
104             Adds a key => [@values] "HTTP_METHODS" whose value is an ArrayRef of sorted
105             allowed methods to the ->list_extra_info HashRef. This is used primarily for
106             debugging output.
107              
108             =head2 _has_expected_http_method ($expected)
109              
110             Private method which returns 1 if C<$expected> matches one of the allowed
111             in L</http_methods> and zero otherwise.
112              
113             =head1 AUTHORS
114              
115             Catalyst Contributors, see Catalyst.pm
116              
117             =head1 COPYRIGHT
118              
119             This library is free software. You can redistribute it and/or modify it under
120             the same terms as Perl itself.
121              
122             =cut