File Coverage

lib/Catalyst/Action/DeserializeMultiPart.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package Catalyst::Action::DeserializeMultiPart;
2             $Catalyst::Action::DeserializeMultiPart::VERSION = '1.21';
3 6     6   66886 use Moose;
  6         14  
  6         31  
4 6     6   32032 use namespace::autoclean;
  6         13  
  6         43  
5              
6             extends 'Catalyst::Action::Deserialize';
7 6     6   390 use HTTP::Body;
  6         11  
  6         1390  
8              
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            
32             Catalyst::Action::DeserializeMultiPart - Deserialize Data in a Multipart Request
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            
46             This action will deserialize multipart HTTP POST, PUT, OPTIONS and DELETE
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
77             inside L<HTTP::Body>: C<$HTTP::Body::Types> (a HASH ref).
78            
79             B<WARNING:> As this module modifies the behaviour of HTTP::Body globally,
80             adding it to an application can have unintended consequences as multipart
81             bodies will be parsed differently from before.
82            
83             Feel free to
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
107