view release on metacpan or search on metacpan
lib/HTTP/Promise/Body/Form/Data.pm view on Meta::CPAN
=head1 DESCRIPTION
This class represents a C<form-data> content as key-value pairs and is designed to make construction and manipulation of C<multipart/form-data> easier. It inherits from L<HTTP::Promise::Body::Form>
For C<x-www-form-urlencoded>, use L<HTTP::Promise::Body::Form> instead.
Each key represents a C<form-data> field and its value can either be a simple string or a C<HTTP::Promise::Body::Form::Field> object.
C<multipart/form-data> is the only valid Content-Type for sending multiple data. L<rfc7578 in section 4.3|https://tools.ietf.org/html/rfc7578#section-4.3> states: "[RFC2388] suggested that multiple files for a single form field be transmitted using a...
See also this L<Stackoverflow discussion|https://stackoverflow.com/questions/36674161/http-multipart-form-data-multiple-files-in-one-input/41204533#41204533> and L<this one too|https://stackoverflow.com/questions/51575746/http-header-content-type-mul...
=head1 CONSTRUCTOR
=head2 new
This takes an optional data, and some options and returns a new L<HTTP::Promise::Body::Form> object.
Acceptable data are:
=over 4
lib/HTTP/Promise/Entity.pm view on Meta::CPAN
=head2 make_boundary
Returns a uniquely generated multipart boundary created using L<Data::UUID>
=head2 make_multipart
This transforms the current entity into the first part of a <multipart/form-data> HTTP message.
For HTTP request, C<multipart/form-data> is the only valid C<Content-Type> for sending multiple data. L<rfc7578 in section 4.3|https://tools.ietf.org/html/rfc7578#section-4.3> states: "[RFC2388] suggested that multiple files for a single form field b...
See also this L<Stackoverflow discussion|https://stackoverflow.com/questions/36674161/http-multipart-form-data-multiple-files-in-one-input/41204533#41204533> and L<this one too|https://stackoverflow.com/questions/51575746/http-header-content-type-mul...
Of course, technically, nothing prevents an HTTP message (request or response) from being a C<multipart/mixed> or something else.
This method takes a multipart subtype, such as C<form-data>, or C<mixed>, etc and creates a multipart entity of which this current entity will become the first part. If no multipart subtype is specified, this defaults to C<form-data>.
It takes also an optional hash or hash reference of parameters.
Valid parameters are:
=over 4
lib/HTTP/Promise/Headers.pm view on Meta::CPAN
# NOTE: proxy_authorization_basic() is inherited
# NOTE: push_header() is inherited
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range>
sub range { return( shift->_set_get_multi( 'Range', @_ ) ); }
sub recommended_filename
{
my $self = shift( @_ );
foreach my $attr_name ( qw( content-disposition.filename* content-disposition.filename content-type.name ) )
{
my $value = $self->mime_attr( $attr_name );
if( defined( $value ) &&
$value ne '' &&
$value =~ /\S/ )
{
return( $self->decode_filename( $value ) );
}
}
return;
lib/HTTP/Promise/Headers/Generic.pm view on Meta::CPAN
{
# We'll return the caller's original value, not the lowercase one we use for comparison
$ok->push( $this->[$i] );
}
}
}
}
return( $ok->unique );
}
# Works for language and content-type and content-encoding
sub _qv_match_wildcard
{
my $self = shift( @_ );
# $proposals contain the value offered in lower case, whereas $original contains
# the original value and we return our value from there. Both $proposals and $original
# are of the same size.
my( $acceptable, $proposals, $original, $seen ) = @_;
return( $self->error( "Bad arguments. Usage: \$h->_qv_match_wildcard( \$acceptable, \$proposals, \$original )" ) ) unless( @_ == 3 );
return( $self->error( "This is not a wildcard acceptable value." ) ) if( $acceptable->index( '*' ) == -1 );
return( $self->error( "Proposed values must be an array reference." ) ) unless( $self->_is_array( $proposals ) );
lib/HTTP/Promise/Message.pm view on Meta::CPAN
This is the same thing as L</add_content>, except it will encode in utf-8 the data provided, i.e. not perl's internal representation.
=head2 add_part
By default, this will check if the HTTP message C<Content-Type> is a multipart one, and if not, it will automatically set it to C<multipart/form-data> and transform the current HTTP message into the first part of a C<multipart/form-data>, and add aft...
If the C<Content-Type> is already a multipart one, but has no part yet and has a body content, it will parse that content to build one or more parts from it.
When used for an HTTP request, C<multipart/form-data> is the only valid Content-Type for sending multiple data. L<rfc7578 in section 4.3|https://tools.ietf.org/html/rfc7578#section-4.3> states: "[RFC2388] suggested that multiple files for a single fo...
See also this L<Stackoverflow discussion|https://stackoverflow.com/questions/36674161/http-multipart-form-data-multiple-files-in-one-input/41204533#41204533> and L<this one too|https://stackoverflow.com/questions/51575746/http-header-content-type-mul...
When used for an HTTP response, one can return either a C<multipart/form-data> or a C<multipart-mixed> HTTP message.
If you want to make an HTTP request, then you need to provide pairs of form-name-and part object (either a L<HTTP::Promise::Entity> or a L<HTTP::Promise::Message> object with an L<HTTP::Promise::Entity> set with L</entity>) OR a list of parts whose L...
If you want to make an HTTP response, you can either return a C<multipart/form-data> by providing pairs of form-name-and part object as mentioned above, or a C<multipart/mixed> by providing a list of part object (either a L<HTTP::Promise::Entity> or ...
For example:
$m->add_part(
lib/HTTP/Promise/Parser.pm view on Meta::CPAN
return( $self->error({ code => 425, message => 'Incomplete request, call again when there is more data.', class => $EXCEPTION_CLASS }) );
}
# response headers:
# {
# "_content_length" => 15,
# "_keepalive" => 0,
# "_message" => "OK",
# "_protocol" => "HTTP/1.0",
# "_status" => 200,
# "content-length" => [15],
# "content-type" => ["text/plain"],
# "host" => ["example.com"],
# "user-agent" => ["hoge"],
# }
# request headers:
# {
# "_content_length" => 27,
# "_keepalive" => 1,
# "_method" => "POST",
# "_protocol" => "HTTP/1.1",
# "_query_string" => "",
# "_request_uri" => "/test",
# "_uri" => "/test",
# "content-length" => [27],
# "content-type" => ["application/x-www-form-urlencoded"],
# "host" => ["foo.example"],
# }
$r->{_protocol} = "HTTP/${bkp_version}" if( defined( $bkp_version ) );
# warn( "HTTP::Parser2::XS->parse_headers_xs: bytes read ($len) differs from _content_length (", ( $r->{_content_length} // '' ), ")\n" ) if( defined( $r->{_content_length} ) && length( $r->{_content_length} ) && $len != $r->{_content_length} && ...
my $def = { length => $len };
# Sadly enough, HTTP::Parser2::XS does not provide the order of the header and
# although we could find out ourself, it would defeat the purpose of using an XS module
# so we default to alphabetical order
# If this is really important, you can use parse_request method instead
my $headers = $self->new_array;
lib/HTTP/Promise/Request.pm view on Meta::CPAN
Obviously you should not use both and if you do, C<file> will take priority.
If this provided, the L<body object|HTTP::Promise::Body> will be a L<HTTP::Promise::Body::Scalar>
=back
=back
C<multipart/form-data> is the only valid Content-Type for sending multiple data. L<rfc7578 in section 4.3|https://tools.ietf.org/html/rfc7578#section-4.3> states: "[RFC2388] suggested that multiple files for a single form field be transmitted using a...
See also this L<Stackoverflow discussion|https://stackoverflow.com/questions/36674161/http-multipart-form-data-multiple-files-in-one-input/41204533#41204533> and L<this one too|https://stackoverflow.com/questions/51575746/http-header-content-type-mul...
See also L<HTTP::Promise::Body::Form::Data> for an alternate easy way to create and manipulate C<form-data>, and see also L<HTTP::Promise::Entity/as_form_data>, which will create and return a L<HTTP::Promise::Body::Form::Data> object.
=head2 method
Sets or gets the HTTP C<method>, such as C<CONNECT>, C<DELETE>, C<GET>, C<HEAD>, C<OPTIONS>, C<PATCH>, C<POST>, C<PUT>, C<TRACE> which are the standard ones as defined by L<rfc7231, section 4.1|https://tools.ietf.org/html/rfc7231#section-4.1>
Note that casing must be uppercase for standard methods, but non-standard ones can be whatever you want as long as it complies with the rfc7231.
This returns the current method set, if any, as an L<scalar object|Module::Generic::Scalar>
t/02.parser.t view on Meta::CPAN
'to' => 'sip:john.doe@somewhere.example.com ; tag = 1234567890n',
'from' => '"Bob \\\\\"" <sip:bob@example.com> ; tag = 12abcd3',
'max-forwards' => '0010',
'call-id' => 'john.doe@192.0.1.2',
'content-length' => '150',
'cseq' => '0009 INVITE',
'via' => 'SIP / 2.0 /UDP 192.0.1.3;branch=123abcdef',
's' => '',
'newfangledheader' => 'newfangled value continued newfangled value',
'unknownheaderwithunusualvalue' => ';;,,;;,;',
'content-type' => 'application/sdp',
'route' => '<sip:services.example.com;lr;unknownwith=value;unknown-no-value>',
'v' => 'SIP / 2.0 / TCP maybe.example.com ; branch = a1bC2dE3fgh4 , SIP / 2.0 / UDP 192.168.255.123 ; branch= a1bC2dE3fgh4',
'm' => '"Quoted string \"\"" <sip:bob@example.com> ; newparam = newvalue ; secondparam ; q = 0.33',
), length => 764 };
my $p = HTTP::Promise::Parser->new( debug => $DEBUG );
my $headers = $p->parse_headers( \$message );
is_deeply( $headers, $expected, "Parsed headers" );
};
t/10.entity_body.t view on Meta::CPAN
subtest "build entity" => sub
{
{
local $SIG{__WARN__} = sub{ die( "caught warning: ", @_ ) };
{
my $e = HTTP::Promise::Entity->build( path => "${testin_dir}/short.txt", debug => $DEBUG );
diag( "Error instantiating HTTP::Promise::Entity object: ", HTTP::Promise::Entity->error ) if( $DEBUG && !defined( $e ) );
my $name = 'short.txt';
my $got;
$got = $e->headers->mime_attr( 'content-type.name' );
# diag( "Content-Type is '", $e->header( 'Content-Type' ), "' and content-type.name yielded '$got', double checking '", $e->headers->mime_attr( 'content-type.name' ), "'" ) if( $DEBUG );
is( $got, $name, 'Path: with no Filename, got default content-type.name' );
$got = $e->headers->mime_attr( 'content-disposition.filename' );
is( $got, $name, 'Path: with no Filename, got default content-disposition.filename' );
$got = $e->headers->recommended_filename;
is( $got, $name, 'Path: with no Filename, got default recommended filename' );
}
{
my $e = HTTP::Promise::Entity->build(
path => "${testin_dir}/short.txt",
filename => undef,
debug => $DEBUG
);
my $got = $e->headers->mime_attr( 'content-type.name' );
ok( !$got, 'Path: with explicitly undef Filename, got no filename' );
my $x = $e->as_string;
my $desired = "Content-Type: text/plain${CRLF}${CRLF}" . <<EOT;
Dear «François Müller»,
As you requested, I have written the HTTP::Promise modules to support
the creation of HTTP multipart messages.
Jacques
EOT
is( $x, $desired, 'Tested stringify' );
}
{
my $e = HTTP::Promise::Entity->build(
path => "${testin_dir}/short.txt",
filename => 'foo.txt',
debug => $DEBUG
);
my $got = $e->headers->mime_attr( 'content-type.name' );
is( $got, "foo.txt", "Path: verified explicit 'Filename'" );
}
{
my $e = HTTP::Promise::Entity->build( path => "${testin_dir}/mignonne-ronsard.txt" );
my $got = $e->headers->mime_attr( 'content-type' );
is( $got, 'text/plain', 'Type: default ok' );
}
{
my $e = HTTP::Promise::Entity->build(
path => "${testin_dir}/mignonne-ronsard.txt",
type => 'text/foo'
);
my $got = $e->headers->mime_attr( 'content-type' );
is( $got, 'text/foo', 'Type: explicit ok' );
}
{
my $e = HTTP::Promise::Entity->build(
path => "${testin_dir}/science-sans-conscience-rabelais.txt",
encoding => 'suggest'
);
my $got = $e->headers->content_encoding;
is( $got, undef, 'No encoding for small body' );
}
t/10.entity_body.t view on Meta::CPAN
path => "${testin_dir}/tengu.png",
encoding => 'suggest'
);
my $got = $e->headers->content_encoding;
is( $got, undef, 'No encoding suggested for images' );
}
{
my $e = HTTP::Promise::Entity->build(
path => "${testin_dir}/short.txt"
);
my $got = $e->headers->mime_attr( 'content-type.charset' );
ok( !$got, 'Charset: default ok' );
}
{
my $e = HTTP::Promise::Entity->build(
path => "${testin_dir}/short.txt",
charset => 'utf-8'
);
my $got = $e->headers->mime_attr( 'content-type.charset' );
is( $got, 'utf-8', 'Charset: explicit' );
}
{
my $e = HTTP::Promise::Entity->build(
type => 'message/http',
encoding => 'base64',
data => "GET / HTTP/1.0${CRLF}Host: wwww.example.org${CRLF}${CRLF}Foo\n"
);
my $encoding = $e->headers->content_encoding;
t/13.header_fields.t view on Meta::CPAN
is( $h->style_src, 'https://example.com/' );
is( $h->style_src_attr, 'https://example.com/' );
is( $h->style_src_elem, 'https://example.com/' );
is( $h->trusted_types, 1 );
is( $h->upgrade_insecure_requests, 1 );
is( $h->worker_src, 'https://example.com/' );
$h->block_all_mixed_content(0);
is( $h->block_all_mixed_content, 0 );
};
subtest 'content-type' => sub
{
use ok( 'HTTP::Promise::Headers::ContentType' );
my $str = q{text/html; charset=UTF-8};
my $h = HTTP::Promise::Headers::ContentType->new( $str );
is( "$h", $str );
is( $h->type, 'text/html' );
is( $h->charset, 'UTF-8' );
$str = q{application/octet-stream};
$h = HTTP::Promise::Headers::ContentType->new( $str );