=pod

=encoding UTF-8

=head1 NAME

CGI::Tiny::Multipart - Tiny multipart/form-data 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 multipart/form-data parser for L<CGI::Tiny>.

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

=item tempfiles

  tempfiles => 1
  tempfiles => 0

If set to a true value, all form field values will be stored in tempfiles
instead of memory, not just file uploads. If set to a false (but defined)
value, all form fields values will be stored in memory, even file uploads.
By default, text field values will be stored in memory and file uploads will be
stored in tempfiles.

=item discard_files

  discard_files => 1

If set to a true value, file upload field contents will be discarded, and
neither C<content> nor C<file> will be provided for those form fields.

=back

Form fields are represented as hash references containing:

=over

=item headers

Hash reference of part 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 part contents in bytes.

=item content

Part contents as undecoded bytes, for parts without a defined C<filename>, or
for all parts if the C<tempfiles> 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 part contents,
for parts with a defined C<filename>, or for all parts if the C<tempfiles>
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>
