use actionrole instead of core for the new http method support
[catagits/Catalyst-Runtime.git] / lib / Catalyst / ActionRole / HTTPMethods.pm
CommitLineData
60034b8c 1package Catalyst::ActionRole::HTTPMethods;
2
3use Moose::Role;
4
5requires 'match', 'match_captures';
6
7around ['match','match_captures'], sub {
8 my ($orig, $self, $ctx, @args) = @_;
9 my $expected = $self->_normalize_expected_http_method($ctx->req);
10 return $self->_has_expected_http_method($expected) ?
11 $self->$orig($ctx, @args) :
12 0;
13};
14
15sub _normalize_expected_http_method {
16 my ($self, $req) = @_;
17 return $req->header('X-HTTP-Method') ||
18 $req->header('X-HTTP-Method-Override') ||
19 $req->header('X-METHOD-OVERRIDE') ||
20 $req->method;
21}
22
23sub _has_expected_http_method {
24 my ($self, $expected) = @_;
25 return 1 unless scalar(my @allowed = $self->allowed_http_methods);
26 return scalar(grep { lc($_) eq lc($expected) } @allowed) ?
27 1 : 0;
28}
29
30sub allowed_http_methods { @{shift->attributes->{Method}||[]} }
31
321;
33
34=head1 NAME
35
36Catalyst::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 option_user : Chained('user_base') Args(1) OPTION { ... }
55 sub option_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
65This is an action role that lets your L<Catalyst::Action> match on standard
66HTTP methods, such as GET, POST, etc.
67
68Since most web browsers have limited support for rich HTTP Method vocabularies
69we also support setting the expected match method via the follow non standard
70but widely used http extensions. Our support for these should not be taken as
71an endorsement of the technique. Rt is merely a reflection of our desire to
72work well with existing systems and common client side tools.
73
74=over 4
75
76=item X-HTTP-Method (Microsoft)
77
78=item X-HTTP-Method-Override (Google/GData)
79
80=item X-METHOD-OVERRIDE (IBM)
81
82=back
83
84Please note the insanity of overriding a GET request with a DELETE override...
85Rational practices suggest that using POST with overrides to emulate PUT and
86DELETE can be an acceptable way to deal with client limitations and security
87rules on your proxy server. I recommend going no further.
88
89=head1 REQUIRES
90
91This role requires the following methods in the consuming class.
92
93=head2 match
94
95=head2 match_captures
96
97Returns 1 if the action matches the existing request and zero if not.
98
99=head1 METHODS
100
101This role defines the following methods
102
103=head2 match
104
105=head2 match_captures
106
107Around method modifier that return 1 if the request method matches one of the
108allowed methods (see L</http_methods>) and zero otherwise.
109
110=head2 allowed_http_methods
111
112An array of strings that are the allowed http methods for matching this action
113normalized as noted above (using X-Method* overrides).
114
115=head2 _has_expected_http_method ($expected)
116
117Private method which returns 1 if C<$expected> matches one of the allowed
118in L</http_methods> and zero otherwise.
119
120=head1 AUTHORS
121
122Catalyst Contributors, see Catalyst.pm
123
124=head1 COPYRIGHT
125
126This library is free software. You can redistribute it and/or modify it under
127the same terms as Perl itself.
128
129=cut