File Coverage

blib/lib/CatalystX/RequestModel/ContentBodyParser/MultiPart.pm
Criterion Covered Total %
statement 34 34 100.0
branch 6 10 60.0
condition 1 3 33.3
subroutine 7 7 100.0
pod 0 4 0.0
total 48 58 82.7


line stmt bran cond sub pod time code
1             package CatalystX::RequestModel::ContentBodyParser::MultiPart;
2              
3 6     6   3539 use warnings;
  6         20  
  6         282  
4 6     6   63 use strict;
  6         25  
  6         155  
5 6     6   32 use base 'CatalystX::RequestModel::ContentBodyParser';
  6         20  
  6         2948  
6              
7 84     84 0 622 sub content_type { 'multipart/form-data' }
8              
9             sub default_attr_rules {
10 2     2 0 7 my ($self, $attr_rules) = @_;
11 2         13 return +{ flatten=>1, %$attr_rules };
12             }
13              
14             sub expand_cgi {
15 1     1 0 7 my ($self) = shift;
16 1         2 my $params = +{ %{$self->{ctx}->req->body_parameters}, %{$self->{ctx}->req->uploads} };
  1         5  
  1         78  
17              
18              
19 1         62 my $data;
20 1         5 foreach my $param (keys %$params) {
21 2         10 my (@segments) = split /\./, $param;
22 2         7 my $data_ref = \$data;
23 2         6 foreach my $segment (@segments) {
24 2 100       6 $$data_ref = {} unless defined $$data_ref;
25              
26 2         7 my ($prefix,$i) = ($segment =~m/^(.+)?\[(\d*)\]$/);
27 2 50       6 $segment = $prefix if defined $prefix;
28              
29 2 50       8 die "CGI param clash for $param=$_" unless ref $$data_ref eq 'HASH';
30 2         6 $data_ref = \($$data_ref->{$segment});
31 2 50       7 $data_ref = \($$data_ref->{$i}) if defined $i;
32             }
33 2 50       6 die "CGI param clash for $param value $params->{$param}" if defined $$data_ref;
34 2         7 $$data_ref = $params->{$param};
35             }
36              
37 1         6 return $data;
38             }
39              
40             sub new {
41 1     1 0 6 my ($class, %args) = @_;
42 1         14 my $self = bless \%args, $class;
43 1   33     23 $self->{context} ||= $self->expand_cgi;
44              
45 1         7 return $self;
46             }
47              
48             1;
49              
50             =head1 NAME
51              
52             CatalystX::RequestModel::ContentBodyParser::MultiPart - Parse multipart uploads
53              
54             =head1 SYNOPSIS
55              
56             TBD
57              
58             =head1 DESCRIPTION
59              
60             Given a list of uploads and possible form parameters:
61              
62             [debug] "POST" request for "upload" from "127.0.0.1"
63             [debug] Body Parameters are:
64             .-------------------------------------+--------------------------------------.
65             | Parameter | Value |
66             +-------------------------------------+--------------------------------------+
67             | notes | This is the file you seek! |
68             '-------------------------------------+--------------------------------------'
69             [debug] File Uploads are:
70             .--------------+----------------------------+--------------------+-----------.
71             | Parameter | Filename | Type | Size |
72             +--------------+----------------------------+--------------------+-----------+
73             | file | file.txt | | 13 |
74             '--------------+----------------------------+--------------------+-----------'
75              
76             If you have a request model like:
77              
78             package Example::Model::UploadRequest;
79              
80             use Moose;
81             use CatalystX::RequestModel;
82              
83             extends 'Catalyst::Model';
84             content_type 'multipart/form-data';
85              
86             has notes => (is=>'ro', required=>1, property=>1);
87             has file => (is=>'ro', property=>1);
88              
89             __PACKAGE__->meta->make_immutable();
90              
91             This will be mapped to an instance of the request model:
92              
93             $request_model->notes; # 'This is the file you seek!';
94             $request_model->file; # Instance of L<Catalyst::Request::Upload>.
95              
96             This is basically a subclass of L<CatalystX::RequestModel::ContentBodyParser::FormURLEncoded>
97             with added support for multipart form uploads. You should see the parent file for more
98             details.
99              
100             =head1 EXCEPTIONS
101              
102             See L<CatalystX::RequestModel::ContentBodyParser> for exceptions.
103              
104             =head1 AUTHOR
105              
106             See L<CatalystX::RequestModel>.
107            
108             =head1 COPYRIGHT
109            
110             See L<CatalystX::RequestModel>.
111              
112             =head1 LICENSE
113            
114             See L<CatalystX::RequestModel>.
115            
116             =cut