| 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
|
|
|
|
|
|
|
|