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

  all_tempfiles => 1

If set to a true value, all form field values will be stored in tempfiles
instead of memory, not just file uploads.

=item no_tempfiles

  no_tempfiles => 1

If set to a true value, all form field values will be stored in memory, even
file uploads.

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

=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
all parts if the C<no_tempfiles> option was passed. 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 all parts if the C<all_tempfiles>
option was passed.

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