Hello community, here is the log from the commit of package perl-Mojolicious for openSUSE:Factory checked in at 2017-10-23 16:36:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Mojolicious (Old) and /work/SRC/openSUSE:Factory/.perl-Mojolicious.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Mojolicious" Mon Oct 23 16:36:22 2017 rev:78 rq:533851 version:7.47 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Mojolicious/perl-Mojolicious.changes 2017-09-18 19:53:00.651389937 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Mojolicious.new/perl-Mojolicious.changes 2017-10-23 16:36:26.076020924 +0200 @@ -1,0 +2,11 @@ +Fri Oct 13 05:33:53 UTC 2017 - [email protected] + +- updated to 7.47 + see /usr/share/doc/packages/perl-Mojolicious/Changes + + 7.47 2017-10-05 + - Added multipart content generator to Mojo::UserAgent::Transactor. + - Fixed a bug in Mojo::File where parts of a path could get accidentally + upgraded from bytes to characters. + +------------------------------------------------------------------- Old: ---- Mojolicious-7.46.tar.gz New: ---- Mojolicious-7.47.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Mojolicious.spec ++++++ --- /var/tmp/diff_new_pack.U6wqUS/_old 2017-10-23 16:36:26.695991899 +0200 +++ /var/tmp/diff_new_pack.U6wqUS/_new 2017-10-23 16:36:26.703991525 +0200 @@ -17,7 +17,7 @@ Name: perl-Mojolicious -Version: 7.46 +Version: 7.47 Release: 0 %define cpan_name Mojolicious Summary: Real-time web framework ++++++ Mojolicious-7.46.tar.gz -> Mojolicious-7.47.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/Changes new/Mojolicious-7.47/Changes --- old/Mojolicious-7.46/Changes 2017-09-12 13:45:12.000000000 +0200 +++ new/Mojolicious-7.47/Changes 2017-10-06 00:58:29.000000000 +0200 @@ -1,4 +1,9 @@ +7.47 2017-10-05 + - Added multipart content generator to Mojo::UserAgent::Transactor. + - Fixed a bug in Mojo::File where parts of a path could get accidentally + upgraded from bytes to characters. + 7.46 2017-09-12 - Fixed support for versions of IO::Socket::SSL older than 1.965 again. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/META.json new/Mojolicious-7.47/META.json --- old/Mojolicious-7.46/META.json 2017-09-12 14:26:32.000000000 +0200 +++ new/Mojolicious-7.47/META.json 2017-10-12 10:25:37.000000000 +0200 @@ -58,6 +58,6 @@ }, "x_IRC" : "irc://irc.perl.org/#mojo" }, - "version" : "7.46", + "version" : "7.47", "x_serialization_backend" : "JSON::PP version 2.94" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/META.yml new/Mojolicious-7.47/META.yml --- old/Mojolicious-7.46/META.yml 2017-09-12 14:26:32.000000000 +0200 +++ new/Mojolicious-7.47/META.yml 2017-10-12 10:25:37.000000000 +0200 @@ -31,5 +31,5 @@ homepage: http://mojolicious.org license: http://www.opensource.org/licenses/artistic-license-2.0 repository: https://github.com/kraih/mojo.git -version: '7.46' +version: '7.47' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/lib/Mojo/File.pm new/Mojolicious-7.47/lib/Mojo/File.pm --- old/Mojolicious-7.46/lib/Mojo/File.pm 2017-09-11 23:23:41.000000000 +0200 +++ new/Mojolicious-7.47/lib/Mojo/File.pm 2017-10-05 19:35:11.000000000 +0200 @@ -78,6 +78,10 @@ sub new { my $class = shift; + + # File systems require bytes, make sure we don't accidentally upgrade + utf8::downgrade $_, 1 for @_; + my $value = @_ == 1 ? $_[0] : @_ > 1 ? catfile @_ : canonpath getcwd; return bless \$value, ref $class || $class; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/lib/Mojo/Server/Prefork.pm new/Mojolicious-7.47/lib/Mojo/Server/Prefork.pm --- old/Mojolicious-7.46/lib/Mojo/Server/Prefork.pm 2017-08-03 10:37:33.000000000 +0200 +++ new/Mojolicious-7.47/lib/Mojo/Server/Prefork.pm 2017-10-12 10:24:51.000000000 +0200 @@ -315,7 +315,7 @@ ... }); -Emitted when a child process dies. +Emitted when a child process exited. $prefork->on(reap => sub { my ($prefork, $pid) = @_; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/lib/Mojo/UserAgent/Transactor.pm new/Mojolicious-7.47/lib/Mojo/UserAgent/Transactor.pm --- old/Mojolicious-7.46/lib/Mojo/UserAgent/Transactor.pm 2017-07-17 21:07:54.000000000 +0200 +++ new/Mojolicious-7.47/lib/Mojo/UserAgent/Transactor.pm 2017-10-04 14:10:51.000000000 +0200 @@ -14,7 +14,8 @@ use Mojo::Util qw(encode url_escape); use Mojo::WebSocket qw(challenge client_handshake); -has generators => sub { {form => \&_form, json => \&_json} }; +has generators => + sub { {form => \&_form, json => \&_json, multipart => \&_multipart} }; has name => 'Mojolicious (Perl)'; sub add_generator { $_[0]->generators->{$_[1]} = $_[2] and return $_[0] } @@ -32,13 +33,13 @@ # Proxy for normal HTTP requests my $socks; if (my $proxy = $req->proxy) { $socks = $proxy->protocol eq 'socks' } - return $self->_proxy($tx, $proto, $host, $port) + return _proxy($tx, $proto, $host, $port) if $proto eq 'http' && !$req->is_handshake && !$socks; return $proto, $host, $port; } -sub peer { $_[0]->_proxy($_[1], $_[0]->endpoint($_[1])) } +sub peer { _proxy($_[1], $_[0]->endpoint($_[1])) } sub proxy_connect { my ($self, $old) = @_; @@ -154,6 +155,8 @@ return client_handshake $tx; } +sub _content { Mojo::Content::MultiPart->new(headers => $_[0], parts => $_[1]) } + sub _form { my ($self, $tx, $form, %options) = @_; $options{charset} = 'UTF-8' unless exists $options{charset}; @@ -168,9 +171,7 @@ # Multipart if ($multipart) { - my $parts = $self->_multipart($options{charset}, $form); - $req->content( - Mojo::Content::MultiPart->new(headers => $headers, parts => $parts)); + $req->content(_content($headers, _form_parts($options{charset}, $form))); _type($headers, 'multipart/form-data'); return $tx; } @@ -187,6 +188,19 @@ return $tx; } +sub _form_parts { + my ($charset, $form) = @_; + + my @parts; + for my $name (sort keys %$form) { + next unless defined(my $values = $form->{$name}); + $values = [$values] unless ref $values eq 'ARRAY'; + push @parts, @{_parts($charset, $name, $values)}; + } + + return \@parts; +} + sub _json { my ($self, $tx, $data) = @_; _type($tx->req->body(encode_json $data)->headers, 'application/json'); @@ -194,58 +208,64 @@ } sub _multipart { - my ($self, $charset, $form) = @_; + my ($self, $tx, $parts) = @_; + my $req = $tx->req; + $req->content(_content($req->headers, _parts(undef, undef, $parts))); + return $tx; +} + +sub _parts { + my ($charset, $name, $values) = @_; my @parts; - for my $name (sort keys %$form) { - next unless defined(my $values = $form->{$name}); - for my $value (ref $values eq 'ARRAY' ? @$values : ($values)) { - push @parts, my $part = Mojo::Content::Single->new; + for my $value (@$values) { + push @parts, my $part = Mojo::Content::Single->new; - # Upload - my $filename; - my $headers = $part->headers; - if (ref $value eq 'HASH') { - - # File - if (my $file = delete $value->{file}) { - $file = Mojo::Asset::File->new(path => $file) unless ref $file; - $part->asset($file); - $value->{filename} //= path($file->path)->basename - if $file->isa('Mojo::Asset::File'); - } - - # Memory - elsif (defined(my $content = delete $value->{content})) { - $part->asset(Mojo::Asset::Memory->new->add_chunk($content)); - } - - # Filename and headers - $filename = url_escape delete $value->{filename} // $name, '"'; - $filename = encode $charset, $filename if $charset; - $headers->from_hash($value); + my $filename; + my $headers = $part->headers; + if (ref $value eq 'HASH') { + + # File + if (my $file = delete $value->{file}) { + $file = Mojo::Asset::File->new(path => $file) unless ref $file; + $part->asset($file); + $value->{filename} //= path($file->path)->basename + if $file->isa('Mojo::Asset::File'); } - # Field - else { - $value = encode $charset, $value if $charset; - $part->asset(Mojo::Asset::Memory->new->add_chunk($value)); + # Memory + elsif (defined(my $content = delete $value->{content})) { + $part->asset(Mojo::Asset::Memory->new->add_chunk($content)); } - # Content-Disposition - $name = url_escape $name, '"'; - $name = encode $charset, $name if $charset; - my $disposition = qq{form-data; name="$name"}; - $disposition .= qq{; filename="$filename"} if defined $filename; - $headers->content_disposition($disposition); + # Filename and headers + $filename = delete $value->{filename}; + $headers->from_hash($value); + next unless defined $name; + $filename = url_escape $filename // $name, '"'; + $filename = encode $charset, $filename if $charset; + } + + # Field + else { + $value = encode $charset, $value if $charset; + $part->asset(Mojo::Asset::Memory->new->add_chunk($value)); } + + # Content-Disposition + next unless defined $name; + $name = url_escape $name, '"'; + $name = encode $charset, $name if $charset; + my $disposition = qq{form-data; name="$name"}; + $disposition .= qq{; filename="$filename"} if defined $filename; + $headers->content_disposition($disposition); } return \@parts; } sub _proxy { - my ($self, $tx, $proto, $host, $port) = @_; + my ($tx, $proto, $host, $port) = @_; my $req = $tx->req; if ($req->via_proxy && (my $proxy = $req->proxy)) { @@ -294,13 +314,19 @@ $t->tx(POST => 'http://example.com' => form => {a => 'b'}); Generate query string, C<application/x-www-form-urlencoded> or -C<multipart/form-data> content. +C<multipart/form-data> content. See L</"tx"> for more. =head2 json $t->tx(PATCH => 'http://example.com' => json => {a => 'b'}); -Generate JSON content with L<Mojo::JSON>. +Generate JSON content with L<Mojo::JSON>. See L</"tx"> for more. + +=head2 multipart + + $t->tx(PUT => 'http://example.com' => multipart => ['Hello', 'World!']); + +Generate multipart content. See L</"tx"> for more. =head1 ATTRIBUTES @@ -311,8 +337,8 @@ my $generators = $t->generators; $t = $t->generators({foo => sub {...}}); -Registered content generators, by default only C<form> and C<json> are already -defined. +Registered content generators, by default only C<form>, C<json> and C<multipart> +are already defined. =head2 name @@ -372,12 +398,14 @@ my $tx = $t->tx(PUT => 'http://example.com' => 'Content!'); my $tx = $t->tx(PUT => 'http://example.com' => form => {a => 'b'}); my $tx = $t->tx(PUT => 'http://example.com' => json => {a => 'b'}); + my $tx = $t->tx(PUT => 'https://example.com' => multipart => ['a', 'b']); + my $tx = $t->tx(POST => 'example.com' => {Accept => '*/*'} => 'Content!'); my $tx = $t->tx( - POST => 'http://example.com' => {Accept => '*/*'} => 'Content!'); + PUT => 'example.com' => {Accept => '*/*'} => form => {a => 'b'}); my $tx = $t->tx( - PUT => 'http://example.com' => {Accept => '*/*'} => form => {a => 'b'}); + PUT => 'example.com' => {Accept => '*/*'} => json => {a => 'b'}); my $tx = $t->tx( - PUT => 'http://example.com' => {Accept => '*/*'} => json => {a => 'b'}); + PUT => 'example.com' => {Accept => '*/*'} => multipart => ['a', 'b']); Versatile general purpose L<Mojo::Transaction::HTTP> transaction builder for requests, with support for L</"GENERATORS">. @@ -470,6 +498,39 @@ my $headers = {'Content-Type' => 'multipart/form-data'}; my $tx = $t->tx(POST => 'example.com' => $headers => form => {a => 'b'}); +The C<multipart> content generator can be used to build custom multipart +requests and does not set a content type. + + # POST request with multipart content ("foo" and "bar") + my $tx = $t->tx(POST => 'http://example.com' => multipart => ['foo', 'bar']); + +Similar to the C<form> content generator you can also pass hash references with +C<content> or C<file> values, as well as headers. + + # POST request with multipart content streamed from file + my $tx = $t->tx( + POST => 'http://example.com' => multipart => [{file => '/foo.txt'}]); + + # PUT request with multipart content streamed from asset + my $headers = {'Content-Type' => 'multipart/custom'}; + my $asset = Mojo::Asset::Memory->new->add_chunk('lalala'); + my $tx = $t->tx( + PUT => 'http://example.com' => $headers => multipart => [{file => $asset}]); + + # POST request with multipart content and custom headers + my $tx = $t->tx(POST => 'http://example.com' => multipart => [ + { + content => 'Hello', + 'Content-Type' => 'text/plain', + 'Content-Language' => 'en-US' + }, + { + content => 'World!', + 'Content-Type' => 'text/plain', + 'Content-Language' => 'en-US' + } + ]); + =head2 upgrade my $tx = $t->upgrade(Mojo::Transaction::HTTP->new); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/lib/Mojo/Util.pm new/Mojolicious-7.47/lib/Mojo/Util.pm --- old/Mojolicious-7.46/lib/Mojo/Util.pm 2017-07-29 14:34:45.000000000 +0200 +++ new/Mojolicious-7.47/lib/Mojo/Util.pm 2017-10-05 23:14:51.000000000 +0200 @@ -127,7 +127,7 @@ Data::Dumper->new([@_])->Indent(1)->Sortkeys(1)->Terse(1)->Useqq(1)->Dump; } -sub encode { _encoding($_[0])->encode("$_[1]") } +sub encode { _encoding($_[0])->encode("$_[1]", 0) } sub extract_usage { my $file = @_ ? "$_[0]" : (caller)[1]; @@ -499,14 +499,14 @@ my $bytes = b64_decode $b64; -Base64 decode bytes. +Base64 decode bytes with L<MIME::Base64>. =head2 b64_encode my $b64 = b64_encode $bytes; my $b64 = b64_encode $bytes, "\n"; -Base64 encode bytes, the line ending defaults to a newline. +Base64 encode bytes with L<MIME::Base64>, the line ending defaults to a newline. =head2 camelize @@ -572,7 +572,8 @@ my $chars = decode 'UTF-8', $bytes; -Decode bytes to characters, or return C<undef> if decoding failed. +Decode bytes to characters with L<Encode>, or return C<undef> if decoding +failed. =head2 deprecated @@ -591,7 +592,7 @@ my $bytes = encode 'UTF-8', $chars; -Encode characters to bytes. +Encode characters to bytes with L<Encode>. =head2 extract_usage @@ -637,7 +638,7 @@ my $checksum = hmac_sha1_sum $bytes, 'passw0rd'; -Generate HMAC-SHA1 checksum for bytes. +Generate HMAC-SHA1 checksum for bytes with L<Digest::SHA>. # "11cedfd5ec11adc0ec234466d8a0f2a83736aa68" hmac_sha1_sum 'foo', 'passw0rd'; @@ -668,13 +669,13 @@ my $checksum = md5_bytes $bytes; -Generate binary MD5 checksum for bytes. +Generate binary MD5 checksum for bytes with L<Digest::MD5>. =head2 md5_sum my $checksum = md5_sum $bytes; -Generate MD5 checksum for bytes. +Generate MD5 checksum for bytes with L<Digest::MD5>. # "acbd18db4cc2f85cedef654fccc4a4d8" md5_sum 'foo'; @@ -727,13 +728,13 @@ my $checksum = sha1_bytes $bytes; -Generate binary SHA1 checksum for bytes. +Generate binary SHA1 checksum for bytes with L<Digest::SHA>. =head2 sha1_sum my $checksum = sha1_sum $bytes; -Generate SHA1 checksum for bytes. +Generate SHA1 checksum for bytes with L<Digest::SHA>. # "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" sha1_sum 'foo'; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/lib/Mojolicious/Guides/Cookbook.pod new/Mojolicious-7.47/lib/Mojolicious/Guides/Cookbook.pod --- old/Mojolicious-7.46/lib/Mojolicious/Guides/Cookbook.pod 2017-09-11 23:28:26.000000000 +0200 +++ new/Mojolicious-7.47/lib/Mojolicious/Guides/Cookbook.pod 2017-10-04 05:49:32.000000000 +0200 @@ -1110,7 +1110,7 @@ $ua->put('http://example.com/upload' => stream => '/home/sri/mojo.png'); $ua->post('http://example.com/upload' => stream => '/home/sri/minion.png'); -The C<json> and C<form> content generators are always available. +The C<json>, C<form> and C<multipart> content generators are always available. use Mojo::UserAgent; @@ -1119,14 +1119,17 @@ my $tx = $ua->patch('http://api.example.com' => json => {foo => 'bar'}); # Send query parameters via GET - my $tx2 = $ua->get('http://search.example.com' => form => {q => 'test'}); + my $tx2 = $ua->get('search.example.com' => form => {q => 'test'}); # Send "application/x-www-form-urlencoded" content via POST my $tx3 = $ua->post('http://search.example.com' => form => {q => 'test'}); # Send "multipart/form-data" content via PUT - my $tx4 = $ua->put('http://upload.example.com' => - form => {test => {content => 'Hello World!'}}); + my $tx4 = $ua->put( + 'upload.example.com' => form => {test => {content => 'Hello World!'}}); + + # Send custom multipart content via PUT + my $tx5 = $ua->put('api.example.com' => multipart => ['Hello', 'World!']); For more information about available content generators see also L<Mojo::UserAgent::Transactor/"tx">. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/lib/Mojolicious/Static.pm new/Mojolicious-7.47/lib/Mojolicious/Static.pm --- old/Mojolicious-7.46/lib/Mojolicious/Static.pm 2017-07-27 00:10:13.000000000 +0200 +++ new/Mojolicious-7.47/lib/Mojolicious/Static.pm 2017-10-06 01:00:27.000000000 +0200 @@ -43,9 +43,10 @@ my ($self, $rel) = @_; # Search all paths + my @parts = split '/', $rel; for my $path (@{$self->paths}) { - my $asset = $self->_get_file(path($path, split('/', $rel))->to_string); - return $asset if $asset; + next unless my $asset = _get_file(path($path, @parts)->to_string); + return $asset; } # Search DATA @@ -53,7 +54,7 @@ # Search extra files my $extra = $self->extra; - return exists $extra->{$rel} ? $self->_get_file($extra->{$rel}) : undef; + return exists $extra->{$rel} ? _get_file($extra->{$rel}) : undef; } sub is_fresh { @@ -142,7 +143,7 @@ } sub _get_file { - my ($self, $path) = @_; + my $path = shift; no warnings 'newline'; return -f $path && -r _ ? Mojo::Asset::File->new(path => $path) : undef; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/lib/Mojolicious.pm new/Mojolicious-7.47/lib/Mojolicious.pm --- old/Mojolicious-7.46/lib/Mojolicious.pm 2017-09-11 23:23:41.000000000 +0200 +++ new/Mojolicious-7.47/lib/Mojolicious.pm 2017-10-08 05:50:30.000000000 +0200 @@ -58,7 +58,7 @@ has validator => sub { Mojolicious::Validator->new }; our $CODENAME = 'Doughnut'; -our $VERSION = '7.46'; +our $VERSION = '7.47'; sub AUTOLOAD { my $self = shift; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.46/t/mojo/transactor.t new/Mojolicious-7.47/t/mojo/transactor.t --- old/Mojolicious-7.46/t/mojo/transactor.t 2017-07-17 21:07:54.000000000 +0200 +++ new/Mojolicious-7.47/t/mojo/transactor.t 2017-10-04 01:21:09.000000000 +0200 @@ -360,6 +360,57 @@ is $tx->req->content->parts->[1]->asset->slurp, 'works', 'right part'; is $tx->req->content->parts->[2], undef, 'no more parts'; +# Multipart request (long) +$tx = $t->tx(POST => 'http://example.com/foo' => multipart => + [{content => 'just'}, {content => 'works'}]); +is $tx->req->url->to_abs, 'http://example.com/foo', 'right URL'; +is $tx->req->method, 'POST', 'right method'; +is $tx->req->headers->content_type, undef, 'no "Content-Type" value'; +is $tx->req->content->parts->[0]->headers->content_disposition, undef, + 'no "Content-Disposition" value'; +is $tx->req->content->parts->[0]->asset->slurp, 'just', 'right part'; +is $tx->req->content->parts->[1]->headers->content_disposition, undef, + 'no "Content-Disposition" value'; +is $tx->req->content->parts->[1]->asset->slurp, 'works', 'right part'; +is $tx->req->content->parts->[2], undef, 'no more parts'; + +# Multipart request (short) +$tx + = $t->tx(POST => 'http://example.com/foo' => multipart => ['just', 'works']); +is $tx->req->url->to_abs, 'http://example.com/foo', 'right URL'; +is $tx->req->method, 'POST', 'right method'; +is $tx->req->headers->content_type, undef, 'no "Content-Type" value'; +is $tx->req->content->parts->[0]->headers->content_disposition, undef, + 'no "Content-Disposition" value'; +is $tx->req->content->parts->[0]->asset->slurp, 'just', 'right part'; +is $tx->req->content->parts->[1]->headers->content_disposition, undef, + 'no "Content-Disposition" value'; +is $tx->req->content->parts->[1]->asset->slurp, 'works', 'right part'; +is $tx->req->content->parts->[2], undef, 'no more parts'; + +# Multipart request with asset +$tx = $t->tx(POST => 'http://example.com/foo' => multipart => + [{file => Mojo::Asset::Memory->new->add_chunk('snowman')}]); +is $tx->req->url->to_abs, 'http://example.com/foo', 'right URL'; +is $tx->req->method, 'POST', 'right method'; +is $tx->req->headers->content_type, undef, 'no "Content-Type" value'; +is $tx->req->content->parts->[0]->headers->content_disposition, undef, + 'no "Content-Disposition" value'; +is $tx->req->content->parts->[0]->asset->slurp, 'snowman', 'right part'; +is $tx->req->content->parts->[1], undef, 'no more parts'; + +# Multipart request with real file and custom header +$tx = $t->tx(POST => 'http://example.com/foo' => multipart => + [{file => __FILE__, DNT => 1}]); +is $tx->req->url->to_abs, 'http://example.com/foo', 'right URL'; +is $tx->req->method, 'POST', 'right method'; +is $tx->req->headers->content_type, undef, 'no "Content-Type" value'; +like $tx->req->content->parts->[0]->asset->slurp, qr/mytext/, 'right part'; +ok $tx->req->content->parts->[0]->asset->is_file, 'stored in file'; +ok !$tx->req->content->parts->[0]->headers->header('file'), 'no "file" header'; +is $tx->req->content->parts->[0]->headers->dnt, 1, 'right "DNT" header'; +is $tx->req->content->parts->[1], undef, 'no more parts'; + # Simple endpoint $tx = $t->tx(GET => 'mojolicious.org'); is(($t->endpoint($tx))[0], 'http', 'right scheme');
