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