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