1 package Catalyst::Action::DeserializeMultiPart;
4 use namespace::autoclean;
6 extends 'Catalyst::Action::Deserialize';
11 our $NO_HTTP_BODY_TYPES_INITIALIZATION;
12 $HTTP::Body::TYPES->{'multipart/mixed'} = 'HTTP::Body::MultiPart' unless $NO_HTTP_BODY_TYPES_INITIALIZATION;
14 override execute => sub {
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');
21 $c->request->_body->body( $REST_body->fh );
22 $c->request->content_type( $REST_body->type );
28 __PACKAGE__->meta->make_immutable;
34 Catalyst::Action::DeserializeMultiPart - Deserialize Data in a Multipart Request
38 package Foo::Controller::Bar;
41 # see Catalyst::Action::Deserialize for standard config
44 sub begin :ActionClass('DeserializeMultiPart') DeserializePart('REST') {}
48 This action will deserialize multipart HTTP POST, PUT, OPTIONS and DELETE
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.
58 This module's code will only come into play if the following conditions are met:
62 =item * The C<Content-type> of the request is C<multipart/*>
64 =item * The request body (as returned by C<$c->request->body> is not defined
66 =item * There is a part of the request body (as returned by C<$c->request->upload($DeserializePart)>) available
70 =head1 CONFIGURING HTTP::Body
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
79 inside L<HTTP::Body>: C<$HTTP::Body::Types> (a HASH ref).
81 B<WARNING:> As this module modifies the behaviour of HTTP::Body globally,
82 adding it to an application can have unintended consequences as multipart
83 bodies will be parsed differently from before.
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.
91 use Catalyst::Action::DeserializeMultiPart;
93 delete $HTTP::Body::Types->{'multipart/mixed'};
94 $HTTP::Body::Types->{'multipart/my-crazy-content-type'} = 'HTTP::Body::MultiPart';
98 This is a simple sub-class of L<Catalyst::Action::Deserialize>.
102 See L<Catalyst::Action::REST> for authors.
106 You may distribute this code under the same terms as Perl itself.