1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
=pod
=encoding UTF-8
=head1 NAME
CGI::Tiny::Multipart - Tiny multipart/form-data form parser
=head1 SYNOPSIS
use CGI::Tiny::Multipart qw(extract_multipart_boundary parse_multipart_form_data);
my $boundary = extract_multipart_boundary($content_type) // die "Failed to parse multipart boundary";
my $parts = parse_multipart_form_data($fh, $content_length, $boundary) // die "Malformed multipart/form-data content";
=head1 DESCRIPTION
CGI::Tiny::Multipart is a tiny C<multipart/form-data> parser for L<CGI::Tiny>,
based on L<RFC 2388|https://datatracker.ietf.org/doc/html/rfc2388> and
L<RFC 7578|https://datatracker.ietf.org/doc/html/rfc7578>.
=head1 FUNCTIONS
The following functions are exported on request.
=head2 extract_multipart_boundary
my $boundary = extract_multipart_boundary($content_type);
Extracts the multipart boundary from a C<Content-Type> header. Returns C<undef>
if the boundary was not found.
=head2 parse_multipart_form_data
my $parts = parse_multipart_form_data($fh, $content_length, $boundary, \%options);
my $parts = parse_multipart_form_data(\$bytes, length($bytes), $boundary, \%options);
Parses C<multipart/form-data> request content into an ordered array reference,
or returns C<undef> if the request content is malformed and cannot be parsed.
The input parameter may be a filehandle, which will have C<binmode> applied to
remove any translation layers, or a scalar reference to a string containing the
request content. Bytes will be read from the input up to the specified
C<$content_length>.
The following options may be specified in an optional hashref parameter:
=over
=item buffer_size
buffer_size => 262144
Buffer size (number of bytes to read at once) for reading the request body from
an input filehandle. Defaults to 262144 (256 KiB). A value of 0 will use the
default value.
=item parse_as_files
parse_as_files => 1
parse_as_files => 0
If set to a true value, all form field values will be parsed as file uploads,
calling C<on_file_buffer> or storing the contents in a tempfile. If set to a
false (but defined) value, all form field values will be returned as
C<content>, even file uploads. By default, text field values will be returned
as C<content> and file uploads will be parsed by C<on_file_buffer> or stored in
tempfiles.
=item on_file_buffer
on_file_buffer => sub { my ($bytes, $hashref, $eof) = @_; }
Callback for custom parsing of file upload form fields. If specified, it will
be called with each (possibly empty) chunk of file contents that is read from
the form as bytes. The hash reference representing this form field is passed as
the second argument. The third argument will be true the last time the callback
is called for a particular form field.
The hash reference passed to the callback persists between calls for the same
form field, and is the same hash reference that will ultimately be returned to
represent the form field. It will contain the C<headers>, undecoded C<name> and
C<filename>, and C<size> of contents read so far (including the bytes just
passed to the callback). Modifying these values may result in unexpected
behavior, but other modifications to the hash reference are allowed.
If C<on_file_buffer> is not specified, file uploads will be stored in C<file>
as a L<File::Temp> object created with C<tempfile_args>.
# approximate the default behavior
on_file_buffer => sub {
my ($bytes, $hashref, $eof) = @_;
$hashref->{file} //= File::Temp->new;
print {$hashref->{file}} $bytes;
if ($eof) {
$hashref->{file}->flush;
seek $hashref->{file}, 0, 0;
}
}
=item tempfile_args
tempfile_args => [TEMPLATE => 'tempXXXXX', SUFFIX => '.dat']
Arguments to pass to the L<File::Temp> constructor when creating tempfiles for
file uploads. By default no arguments are passed. Not used if a custom
C<on_file_buffer> callback is passed.
=item discard_files
discard_files => 1
If set to a true value, file upload field contents will be discarded without
calling C<on_file_buffer>, and neither C<content> nor C<file> will be provided
for those form fields. Note that this discards the contents of form fields with
a defined C<filename> regardless of the C<parse_as_files> setting.
=back
Form fields are represented as hash references containing:
=over
=item headers
Hash reference of form field headers. Header names are represented in
lowercase.
=item name
Form field name from C<Content-Disposition> header, undecoded.
=item filename
Filename from C<Content-Disposition> header if present, undecoded.
=item size
Size of form field contents in bytes.
=item content
Form field contents as undecoded bytes, for form fields without a defined
C<filename>, or for all form fields if the C<parse_as_files> option was set to
a false value. File uploads are stored in a temporary C<file> instead by
default.
=item file
L<File::Temp> object referencing temporary file containing the form field
contents, for form fields with a defined C<filename>, or for all form fields if
the C<parse_as_files> option was set to a true value.
=back
=head1 BUGS
Report any issues on the public bugtracker.
=head1 AUTHOR
Dan Book <dbook@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2021 by Dan Book.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
=head1 SEE ALSO
L<HTTP::Body::MultiPart>
|