Merge branch 'klkanet push origin master-master'
[catagits/Catalyst-Action-REST.git] / lib / Catalyst / Action / DeserializeMultiPart.pm
CommitLineData
8bf1f20e 1package Catalyst::Action::DeserializeMultiPart;
2
3use Moose;
4use namespace::autoclean;
5
6extends 'Catalyst::Action::Deserialize';
7use HTTP::Body;
8
8bf1f20e 9our $NO_HTTP_BODY_TYPES_INITIALIZATION;
10$HTTP::Body::TYPES->{'multipart/mixed'} = 'HTTP::Body::MultiPart' unless $NO_HTTP_BODY_TYPES_INITIALIZATION;
11
12override 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
281;
29
30=head1 NAME
31
14fa118e 32Catalyst::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 46This action will deserialize multipart HTTP POST, PUT, OPTIONS and DELETE
8bf1f20e 47requests. It is a simple extension of L<Catalyst::Action::Deserialize>
48with the exception that rather than using the entire request body (which
49may contain multiple sections), it will look for a single part in the request
50body 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
52proceeds to deserialize the request as normal based on the content-type
53of that individual part. If no such part is found, the request would
54be processed as if no data was sent.
55
56This 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
70By default, L<HTTP::Body> parses C<multipart/*> requests as an
71L<HTTP::Body::OctetStream>. L<HTTP::Body::OctetStream> does not separate
72out the individual parts of the request body. In order to make use of
73the individual parts, L<HTTP::Body> must be told which content types
74to map to L<HTTP::Body::MultiPart>. This module makes the assumption
75that you would like to have all C<multipart/mixed> requests parsed by
76L<HTTP::Body::MultiPart> module. This is done by a package variable
0143ed45 77inside L<HTTP::Body>: C<$HTTP::Body::Types> (a HASH ref).
78
14fa118e 79B<WARNING:> As this module modifies the behaviour of HTTP::Body globally,
0143ed45 80adding it to an application can have unintended consequences as multipart
14fa118e 81bodies will be parsed differently from before.
0143ed45 82
83Feel free to
8bf1f20e 84add other content-types to this hash if needed or if you would prefer
85that C<multipart/mixed> NOT be added to this hash, simply delete it
86after 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
96This is a simple sub-class of L<Catalyst::Action::Deserialize>.
97
98=head1 AUTHORS
99
100See L<Catalyst::Action::REST> for authors.
101
102=head1 LICENSE
103
104You may distribute this code under the same terms as Perl itself.
105
106=cut