Commit | Line | Data |
8bf1f20e |
1 | package Catalyst::Action::DeserializeMultiPart; |
2 | |
3 | use Moose; |
4 | use namespace::autoclean; |
5 | |
6 | extends 'Catalyst::Action::Deserialize'; |
7 | use HTTP::Body; |
8 | |
1c4b501b |
9 | our $VERSION = '0.93'; |
8bf1f20e |
10 | $VERSION = eval $VERSION; |
11 | |
12 | our $NO_HTTP_BODY_TYPES_INITIALIZATION; |
13 | $HTTP::Body::TYPES->{'multipart/mixed'} = 'HTTP::Body::MultiPart' unless $NO_HTTP_BODY_TYPES_INITIALIZATION; |
14 | |
15 | override execute => sub { |
16 | my $self = shift; |
17 | my ( $controller, $c ) = @_; |
18 | if($c->request->content_type =~ m{^multipart/}i && !defined($c->request->body)){ |
19 | my $REST_part = $self->attributes->{DeserializePart} || []; |
20 | my($REST_body) = $c->request->upload($REST_part->[0] || 'REST'); |
21 | if($REST_body){ |
22 | $c->request->_body->body( $REST_body->fh ); |
23 | $c->request->content_type( $REST_body->type ); |
24 | } |
25 | } |
26 | super; |
27 | }; |
28 | |
29 | __PACKAGE__->meta->make_immutable; |
30 | |
31 | 1; |
32 | |
33 | =head1 NAME |
34 | |
14fa118e |
35 | Catalyst::Action::DeserializeMultiPart - Deserialize Data in a Multipart Request |
8bf1f20e |
36 | |
37 | =head1 SYNOPSIS |
38 | |
39 | package Foo::Controller::Bar; |
40 | |
41 | __PACKAGE__->config( |
42 | # see Catalyst::Action::Deserialize for standard config |
43 | ); |
44 | |
45 | sub begin :ActionClass('DeserializeMultiPart') DeserializePart('REST') {} |
46 | |
47 | =head1 DESCRIPTION |
48 | |
14fa118e |
49 | This action will deserialize multipart HTTP POST, PUT, OPTIONS and DELETE |
8bf1f20e |
50 | requests. It is a simple extension of L<Catalyst::Action::Deserialize> |
51 | with the exception that rather than using the entire request body (which |
52 | may contain multiple sections), it will look for a single part in the request |
53 | body named according to the C<DeserializePart> attribute on that action |
54 | (defaulting to C<REST>). If a part is found under that name, it then |
55 | proceeds to deserialize the request as normal based on the content-type |
56 | of that individual part. If no such part is found, the request would |
57 | be processed as if no data was sent. |
58 | |
59 | This module's code will only come into play if the following conditions are met: |
60 | |
61 | =over 4 |
62 | |
63 | =item * The C<Content-type> of the request is C<multipart/*> |
64 | |
65 | =item * The request body (as returned by C<$c->request->body> is not defined |
66 | |
67 | =item * There is a part of the request body (as returned by C<$c->request->upload($DeserializePart)>) available |
68 | |
69 | =back |
70 | |
71 | =head1 CONFIGURING HTTP::Body |
72 | |
73 | By default, L<HTTP::Body> parses C<multipart/*> requests as an |
74 | L<HTTP::Body::OctetStream>. L<HTTP::Body::OctetStream> does not separate |
75 | out the individual parts of the request body. In order to make use of |
76 | the individual parts, L<HTTP::Body> must be told which content types |
77 | to map to L<HTTP::Body::MultiPart>. This module makes the assumption |
78 | that you would like to have all C<multipart/mixed> requests parsed by |
79 | L<HTTP::Body::MultiPart> module. This is done by a package variable |
0143ed45 |
80 | inside L<HTTP::Body>: C<$HTTP::Body::Types> (a HASH ref). |
81 | |
14fa118e |
82 | B<WARNING:> As this module modifies the behaviour of HTTP::Body globally, |
0143ed45 |
83 | adding it to an application can have unintended consequences as multipart |
14fa118e |
84 | bodies will be parsed differently from before. |
0143ed45 |
85 | |
86 | Feel free to |
8bf1f20e |
87 | add other content-types to this hash if needed or if you would prefer |
88 | that C<multipart/mixed> NOT be added to this hash, simply delete it |
89 | after loading this module. |
90 | |
91 | # in your controller |
92 | use Catalyst::Action::DeserializeMultiPart; |
93 | |
94 | delete $HTTP::Body::Types->{'multipart/mixed'}; |
95 | $HTTP::Body::Types->{'multipart/my-crazy-content-type'} = 'HTTP::Body::MultiPart'; |
96 | |
97 | =head1 SEE ALSO |
98 | |
99 | This is a simple sub-class of L<Catalyst::Action::Deserialize>. |
100 | |
101 | =head1 AUTHORS |
102 | |
103 | See L<Catalyst::Action::REST> for authors. |
104 | |
105 | =head1 LICENSE |
106 | |
107 | You may distribute this code under the same terms as Perl itself. |
108 | |
109 | =cut |