= NAME

Multipart::Encoder - encoder for mime-type `multipart/form-data`.

= VERSION

v0.0.3

= SINOPSIS

	`echo "Simple text." > /tmp/file.txt`;
	$?	#  0
	`gzip < /tmp/file.txt > /tmp/file.gz`;
	$?	#  0
	
	use Multipart::Encoder;

	my $multipart = Multipart::Encoder->new(
		x=>1,
		file_name => \"/tmp/file.txt",
		y=>[
			"Content-Type" => "text/json",
			name => 'my-name',
			filename => 'my-filename',
			_ => '{"count": 666}',
			'Any-Header' => 123,
		],
		z => {
			_ => \'/tmp/file.gz',
			'Any-Header' => 123,
		}
	)->buffer_size(2048)->boundary("xYzZY");

	my $str = $multipart->as_string;

	utf8::is_utf8($str)			## ""
	
	$str 						#~ \r\n--xYzZY--\r\n\z

	$multipart->to("/tmp/file.form-data");

	open my $f, "<", "/tmp/file.form-data"; binmode $f; read $f, my $buf, -s $f; close $f;
	
	utf8::is_utf8($buf)			## ""
	
	$buf						## $str

	$multipart->to(\*STDOUT);	##>> $str

= DESCRIPTION

The encoder in 'multipart/form-data' is not represented in perl libraries. It is only used as part of other libraries, for example, `HTTP::Tiny::Multipart`.

But there is no such library for `AnyEvent::HTTP`.

The only module `HTTP::Body::Builder::MultiPart` does not allow adding a file as a string to a **multipart**.

= INSTALL

`$ cpm install -g Multipart::Encoder`

= SUBROUTINES/METHODS

== new

Constructor.

	my $multipart1 = Multipart::Encoder->new;
	my $multipart2 = $multipart1->new;
	$multipart2	##!= $multipart1
	
	ref Multipart::Encoder::new(0)	# 0
	
**Return** new object.

Arguments is a params for serialize to multipart-format.

	Multipart::Encoder->new(x=>123)->as_string    #~ 123	

== content_type

	$multipart->content_type	# multipart/form-data
	
== buffer_size

Set or get buffer size. Buffer using for write to file.

	$multipart->buffer_size(1024)->buffer_size		# 1024

Default buffer size:

	Multipart::Encoder->new->buffer_size			# 2048

== boundary

Boundary is a separator before params in multipart-data.

	$multipart->boundary("XYZooo")->boundary		# XYZooo

Default boundary:

	Multipart::Encoder->new->boundary				# xYzZY
	
== as_string

Serialize params to a string.

	Multipart::Encoder->new(x=>123, y=>456)->as_string   #~ 123
	
== to

Serialize params and print it in multipart format to a file use buffer with `buffer_size`.
Argument for `to`  must by path or filehandle.

	$multipart->to("/tmp/file.form-data");
	
	open my $f, ">", "/tmp/file.form-data"; binmode $f;
	$multipart->to($f);
	close $f;

If file not open raise the die.

	$multipart->to("/")		#@ ~ Not open file `/`. Is a directory

= PARAMS

Param types is file and string.

== String param type

	Multipart::Encoder->new(x=>"Simple string")->as_string	#~ Simple string
	
With headers:

	my $str = Multipart::Encoder->new(
		x => {
			_ => "Simple string",
			header => 123,
		},
	)->as_string;

	$str #~ Simple string
	$str #~ header: 123

Header **Content-Disposition** added automically.

	Multipart::Encoder->new(x=>"Simple string")->as_string	#~ Content-Disposition: form-data; name="x"
	
Name in **Content-Disposition** set as key, or name-header:
	
	my $str = Multipart::Encoder->new(
		x => {
			_ => "Simple string",
			name => "xyz",
		},
	)->as_string;
	
	$str #~ Content-Disposition: form-data; name="xyz"
	
If need filename in **Content-Disposition**, add it:

	my $str = Multipart::Encoder->new(
		0 => {
			_ => "Simple string",
			filename => "xyz.tgz",
		},
	)->as_string;
	
	$str #~ Content-Disposition: form-data; name="0"; filename="xyz.tgz"
	
If **Content-Disposition** is, then it use once.

	my $str = Multipart::Encoder->new(
		x => {
			_ => "Simple string",
			'content-disposition' => "form-data; name=\"z\"; filename=\"xyz\"",
		},
	)->as_string;
	
	$str #~ content-disposition: form-data; name="z"; filename="xyz"
	
== File param type
	
Header **Content-Disposition** added automically.

	open my $f, ">/tmp/0"; close $f;

	Multipart::Encoder->new(x=>\"/tmp/0")->as_string	#~ Content-Disposition: form-data; name="x"; filename="0"
	
Header **Content-Type** added automically.

	Multipart::Encoder->new(x=>\"/tmp/file.gz")->as_string	#~ Content-Type: application/x-gzip; charset=binary
	
But if it is, then used once.

	my $str = Multipart::Encoder->new(
		x => [
			_ => \"/tmp/file.gz",
			'content-type' => 'text/plain',
		]
	)->as_string;

	$str #~ content-type: text/plain
	$str #!~ Content-Type
	
Name in **Content-Disposition** set as key, or name-header:
	
	my $str = Multipart::Encoder->new(
		x => {
			_ => \"/tmp/file.txt",
			name => "xyz",
		},
	)->as_string;
	
	$str #~ Content-Disposition: form-data; name="xyz"; filename="file.txt"
	
If need filename in **Content-Disposition**, add it:

	my $str = Multipart::Encoder->new(
		0 => {
			_ => \"/tmp/file.txt",
			filename => "xyz.tgz",
		},
	)->as_string;
	
	$str #~ Content-Disposition: form-data; name="0"; filename="xyz.tgz"
	
If **Content-Disposition** is, then it use once.

	my $str = Multipart::Encoder->new(
		x => [
			_ => \"/tmp/file.txt",
			'content-disposition' => "form-data; name=\"z\"; filename=\"xyz\"",
		],
	)->as_string;
	
	$str #~ content-disposition: form-data; name="z"; filename="xyz"

Big file.

	open my $f, ">", "/tmp/bigfile"; binmode $f; print $f 0 x 65534; close $f;
	Multipart::Encoder->new(x=>\"/tmp/bigfile")->as_string	#~ \n0{65534}\r

Raise if not open file.

	Multipart::Encoder->new(x=>\"/tmp/NnKkMm346485923")->as_string #@ ~ Not open file `/tmp/NnKkMm346485923`: No such file or directory 
	

= SEE ALSO

* `HTTP::Tiny::Multipart`
* `HTTP::Body::Builder::MultiPart`

= LICENSE

Copyright (C) Yaroslav O. Kosmina.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

= AUTHOR

Yaroslav O. Kosmina <darviarush@mail.ru>
