Version 1.04
[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
44fa7f94 9our $VERSION = '1.04';
8bf1f20e 10$VERSION = eval $VERSION;
11
12our $NO_HTTP_BODY_TYPES_INITIALIZATION;
13$HTTP::Body::TYPES->{'multipart/mixed'} = 'HTTP::Body::MultiPart' unless $NO_HTTP_BODY_TYPES_INITIALIZATION;
14
15override 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
311;
32
33=head1 NAME
34
14fa118e 35Catalyst::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 49This action will deserialize multipart HTTP POST, PUT, OPTIONS and DELETE
8bf1f20e 50requests. It is a simple extension of L<Catalyst::Action::Deserialize>
51with the exception that rather than using the entire request body (which
52may contain multiple sections), it will look for a single part in the request
53body 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
55proceeds to deserialize the request as normal based on the content-type
56of that individual part. If no such part is found, the request would
57be processed as if no data was sent.
58
59This 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
73By default, L<HTTP::Body> parses C<multipart/*> requests as an
74L<HTTP::Body::OctetStream>. L<HTTP::Body::OctetStream> does not separate
75out the individual parts of the request body. In order to make use of
76the individual parts, L<HTTP::Body> must be told which content types
77to map to L<HTTP::Body::MultiPart>. This module makes the assumption
78that you would like to have all C<multipart/mixed> requests parsed by
79L<HTTP::Body::MultiPart> module. This is done by a package variable
0143ed45 80inside L<HTTP::Body>: C<$HTTP::Body::Types> (a HASH ref).
81
14fa118e 82B<WARNING:> As this module modifies the behaviour of HTTP::Body globally,
0143ed45 83adding it to an application can have unintended consequences as multipart
14fa118e 84bodies will be parsed differently from before.
0143ed45 85
86Feel free to
8bf1f20e 87add other content-types to this hash if needed or if you would prefer
88that C<multipart/mixed> NOT be added to this hash, simply delete it
89after 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
99This is a simple sub-class of L<Catalyst::Action::Deserialize>.
100
101=head1 AUTHORS
102
103See L<Catalyst::Action::REST> for authors.
104
105=head1 LICENSE
106
107You may distribute this code under the same terms as Perl itself.
108
109=cut