File Coverage

blib/lib/HTTP/Body/MultiPart/Extend.pm
Criterion Covered Total %
statement 28 28 100.0
branch 2 4 50.0
condition n/a
subroutine 10 10 100.0
pod 5 5 100.0
total 45 47 95.7


line stmt bran cond sub pod time code
1             package HTTP::Body::MultiPart::Extend;
2              
3 2     2   199919 use warnings;
  2         6  
  2         83  
4 2     2   11 use strict;
  2         4  
  2         161  
5              
6             =head1 NAME
7              
8             HTTP::Body::MultiPart::Extend - Extend HTTP::Body::MultiPart's handler to do something you want
9              
10             =cut
11              
12             our $VERSION = '0.01';
13              
14             =head1 SYNOPSIS
15              
16             use HTTP::Body::MultiPart::Extend qw(extend no_extend patch_new);
17              
18             # Overwrite HTTP::Body::MultiPart::handler
19             use HTTP::Body;
20             use HTTP::Body::MultiPart::Extend qw(extend);
21            
22             extend( sub {
23             my($self, $part) = @_;
24              
25             my $headers = $part->{headers}; # A hash ref to this part's header fields
26             my $size = $part->{size}; # The current size this time
27             my $done = $part->{done}; # If this part is done (the final call for this part)
28             # Please don't modify these fields listed above.
29              
30             my $data = substr($part->{data}, 0, length($part->{data}), '');
31             # Each time, the comming data will be appended here.
32             # You can choose whether to take it out, or leave it here (and occupy memory steadily).
33             ...
34             $self->SUPER::handler(@_); # You can call the original one like this when need
35             } );
36             $body = HTTP::Body->new( $content_type, $content_length );
37             # Then use HTTP::Body in a normal way.
38             # See the document of HTTP::Body
39              
40             # You can overwrite different subs alternatively.
41             use HTTP::Body;
42             use HTTP::Body::MultiPart::Extend qw(extend no_extend);
43              
44             extend(\&A);
45             my $body_a = HTTP::Body->new(...);
46             # Overwrite by sub A
47              
48             extend(\&B);
49             my $body_b = HTTP::Body->new(...);
50             # Then overwrite by sub B
51              
52             no_extend;
53             my $body = HTTP::Body->new(...);
54             # Switch back to the original one.
55              
56             # You can use $body_a, $body_b, and $body here.
57             # They will work with handlers A, B, and the original one respectively
58              
59              
60             # Beside extend and no_extend, you can use patch_new with a no-side-effect style
61             use HTTP::Body::MultiPart::Extend qw(patch_new);
62             my $body = patch_new( sub { ... }, ... other args for HTTP::Body->new ... );
63             # It will call HTTP::Body->new(...) for you
64              
65             # Note that if the request is not multipart/form-data, it's no effect by this module
66              
67             =cut
68              
69 2     2   1050 use HTTP::Body;
  2         74352  
  2         99  
70 2     2   13 use base qw(Exporter HTTP::Body::MultiPart);
  2         5  
  2         223  
71 2     2   12 use Carp;
  2         3  
  2         893  
72              
73             our @EXPORT_OK = qw(extend no_extend patch_new);
74             our $handler;
75              
76             sub init {
77 5     5 1 379 my $self = shift;
78 5         25 $self->SUPER::init(@_);
79 5         90 $self->{handler} = $handler;
80 5         30 return $self;
81             }
82              
83             sub handler {
84 210     210 1 37174 return $_[0]{handler}(@_)
85             }
86              
87              
88             =head1 DESCRIPTION
89              
90             With this module, you can switch C to your version.
91             Then you can decide how to deal with the user uploads, such as tracking
92             uploading progress, droping malform or too large files in time, etc.
93              
94             =head1 FUNCTIONS
95              
96             =over 4
97              
98             =item extend
99              
100             The only argument of extend should be a CODE ref.
101             All the following C<< HTTP::Body->new >> will use the given sub
102             as the L handler if the request
103             is multipart/form-data, until the next extend or no_extend.
104              
105             =cut
106              
107             sub extend($) {
108 2 50   2 1 575 croak "The only argument of extend should be a CODE ref" unless 'CODE' eq ref $_[0];
109 2         8 $HTTP::Body::TYPES->{'multipart/form-data'} = __PACKAGE__;
110 2         6 $handler = shift;
111             }
112              
113             =item no_extend
114              
115             After this call, all the following C<< HTTP::Body->new >> will
116             switch back to use the original handler.
117              
118             =cut
119              
120             sub no_extend() {
121 1     1 1 6 $HTTP::Body::TYPES->{'multipart/form-data'} = 'HTTP::Body::MultiPart';
122             }
123              
124             =item patch_new
125              
126             This function will call C<< HTTP::Body->new >>, and additionally
127             change the L handler to yours.
128              
129             This function provides a no-side-effect way to extend.
130              
131             The first argument should be a CODE ref, and the following arguments
132             will be passed to C<< HTTP::Body->new >>.
133              
134             =cut
135              
136             sub patch_new($@) {
137 3 50   3 1 22 croak "The first argument of extend should be a CODE ref" unless 'CODE' eq ref $_[0];
138 3         10 local $HTTP::Body::TYPES->{'multipart/form-data'} = __PACKAGE__;
139 3         6 local $handler = shift;
140 3         19 return HTTP::Body->new(@_);
141             }
142              
143             =back
144              
145             =head1 EXPORT
146              
147             This module will not export anything by default. You could export them by yourself,
148             or use the fully qualified name directory.
149              
150             =head1 ORIGINAL HANDLER
151              
152             If you don't known how to design your own handler.
153             Take a look on the original one. It might inspire you some.
154              
155             The code below is HTTP::Body::MultiPart::handler, taken from package L version 1.07.
156              
157             sub handler {
158             my ( $self, $part ) = @_;
159              
160             unless ( exists $part->{name} ) {
161              
162             my $disposition = $part->{headers}->{'Content-Disposition'};
163             my ($name) = $disposition =~ / name="?([^\";]+)"?/;
164             my ($filename) = $disposition =~ / filename="?([^\"]*)"?/;
165             # Need to match empty filenames above, so this part is flagged as an upload type
166              
167             $part->{name} = $name;
168              
169             if ( defined $filename ) {
170             $part->{filename} = $filename;
171              
172             if ( $filename ne "" ) {
173             my $fh = File::Temp->new( UNLINK => 0, DIR => $self->tmpdir );
174              
175             $part->{fh} = $fh;
176             $part->{tempname} = $fh->filename;
177             }
178             }
179             }
180              
181             if ( $part->{fh} && ( my $length = length( $part->{data} ) ) ) {
182             $part->{fh}->write( substr( $part->{data}, 0, $length, '' ), $length );
183             }
184              
185             if ( $part->{done} ) {
186              
187             if ( exists $part->{filename} ) {
188             if ( $part->{filename} ne "" ) {
189             $part->{fh}->close if defined $part->{fh};
190              
191             delete @{$part}{qw[ data done fh ]};
192              
193             $self->upload( $part->{name}, $part );
194             }
195             }
196             else {
197             $self->param( $part->{name}, $part->{data} );
198             }
199             }
200             }
201              
202             =head1 SEE ALSO
203              
204             L, L
205              
206             =head1 AUTHOR
207              
208             Cindy Wang (CindyLinz)
209              
210             =head1 BUGS
211              
212             Please report any bugs or feature requests to C, or through
213             the web interface at L. I will be notified, and then you'll
214             automatically be notified of progress on your bug as I make changes.
215              
216              
217              
218              
219             =head1 SUPPORT
220              
221             You can find documentation for this module with the perldoc command.
222              
223             perldoc HTTP::Body::MultiPart::Extend
224              
225              
226             You can also look for information at:
227              
228             =over 4
229              
230             =item * RT: CPAN's request tracker
231              
232             L
233              
234             =item * AnnoCPAN: Annotated CPAN documentation
235              
236             L
237              
238             =item * CPAN Ratings
239              
240             L
241              
242             =item * Search CPAN
243              
244             L
245              
246             =back
247              
248              
249             =head1 LICENSE AND COPYRIGHT
250              
251             Copyright 2010 Cindy Wang (CindyLinz).
252              
253             This program is free software; you can redistribute it and/or modify it
254             under the terms of either: the GNU General Public License as published
255             by the Free Software Foundation; or the Artistic License.
256              
257             See http://dev.perl.org/licenses/ for more information.
258              
259             =cut
260              
261             1; # End of HTTP::Body::MultiPart::Extend