HTTP::Promise::Message - HTTP Message Class
use HTTP::Promise::Message; my $this = HTTP::Promise::Message->new( [ 'Content-Type' => 'text/plain' ], 'Hello world' ) || die( HTTP::Promise::Message->error, "\n" );
v0.2.0
This class represents an HTTP message, and implements methods that are common to either a request or a response. This class is inherited by HTTP::Promise::Request and HTTP::Promise::Response. It difffers from HTTP::Promise::Entity in that HTTP::Promise::Entity represents en HTTP entity which is composed of headers and a body, and this can be embedded within another entity.
Here is how it fits in overall relation with other classes.
+-------------------------+ +--------------------------+ | | | | | HTTP::Promise::Request | | HTTP::Promise::Response | | | | | +------------|------------+ +-------------|------------+ | | | | | | | +------------------------+ | | | | | +--- HTTP::Promise::Message |---+ | | +------------|-----------+ | | +------------|-----------+ | | | HTTP::Promise::Entity | | | +------------|-----------+ | | +------------|-----------+ | | | HTTP::Promise::Body | | | +------------------------+
This takes some parameters and instantiates a new HTTP::Promise::Message.
Accepted parameters can be one of the followings:
my $msg = HTTP::Promise::Message->new( HTTP::Promise::Headers->new( Content_Type => 'text/plain', Content_Encoding => 'gzip', Host: 'www.example.org', ), "Some content", ); my $str = "Some content"; my $hdr = HTTP::Promise::Headers->new( Content_Type => 'text/plain', Content_Encoding => 'gzip', Host: 'www.example.org', ); my $msg = HTTP::Promise::Message->new( $hdr, \$str );
my $body = HTTP::Promise::Body::Scalar->new( "Some content" ); my $hdr = HTTP::Promise::Headers->new( Content_Type => 'text/plain', Content_Encoding => 'gzip', Host: 'www.example.org', ); my $msg = HTTP::Promise::Message->new( $hdr, $body );
Using the x-www-form-urlencoded class:
my $body = HTTP::Promise::Body::Form->new({ name => '嘉納 治五郎', age => 22, city => 'Tokyo' }); my $hdr = HTTP::Promise::Headers->new( Content_Type => 'text/plain', Content_Encoding => 'gzip', Host: 'www.example.org', ); my $msg = HTTP::Promise::Message->new( $hdr, $body );
my $msg = HTTP::Promise::Message->new([ Content_Type => 'text/plain', Content_Encoding => 'gzip', Host: 'www.example.org', ], "Some content", );
my $hdr = HTTP::Promise::Headers->new( Content_Type => 'text/plain', Content_Encoding => 'gzip', Host: 'www.example.org', ); my $msg = HTTP::Promise::Message->new({ headers => $hdr, content => \$str, # HTP::Promise::Entity entity => $entity_object, debug => 4, });
In any case, you can provide additional object options by providing an hash reference as the last argument, such as:
my $msg = HTTP::Promise::Message->new([ Content_Type => 'text/plain', Content_Encoding => 'gzip', Host: 'www.example.org', ], "Some content", { debug => 4, entity => $entity_object }, );
If some content is provided, a new entity in-memory body object will be initiated
It returns the new http message object, or upon error, sets an error and returns undef.
undef
This takes a string or a scalar reference and append it to the current body if the body object is an HTTP::Promise::Body::File or HTTP::Promise::Body::Scalar object. This does not work for HTTP::Promise::Body::Form. You would have to call yourself the class methods to add your key-value pairs.
The content thus provided is downgraded, which means it is flagged as being in perl's internal utf-8 representation. So you cannot use this method to add binary data. If you want to do so, you would need to use directly the body object methods. For example:
my $io = $msg->entity->body->open( '>', { binmode => 'utf-8', autoflush => 1 }) || die( $msg->entity->body->error ); $io->print( $some_data ) || die( $io->error ); $io->close;
This code works for either HTTP::Promise::Body::File or HTTP::Promise::Body::Scalar
If no entity, or body is set yet, it will create one automatically, and defaults to HTTP::Promise::Body::Scalar for the body class.
It returns the entity body object, or upon error, sets an error and returns undef.
This is the same thing as "add_content", except it will encode in utf-8 the data provided, i.e. not perl's internal representation.
By default, this will check if the HTTP message Content-Type is a multipart one, and if not, it will automatically set it to multipart/form-data and transform the current HTTP message into the first part of a multipart/form-data, and add after all the parts provided.
Content-Type
multipart/form-data
If the 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, multipart/form-data is the only valid Content-Type for sending multiple data. rfc7578 in section 4.3 states: "[RFC2388] suggested that multiple files for a single form field be transmitted using a nested "multipart/mixed" part. This usage is deprecated."
See also this Stackoverflow discussion and this one too
When used for an HTTP response, one can return either a multipart/form-data or a multipart-mixed HTTP message.
multipart-mixed
If you want to make an HTTP request, then you need to provide pairs of form-name-and part object (either a HTTP::Promise::Entity or a HTTP::Promise::Message object with an HTTP::Promise::Entity set with "entity") OR a list of parts whose name attribute is set.
If you want to make an HTTP response, you can either return a multipart/form-data by providing pairs of form-name-and part object as mentioned above, or a multipart/mixed by providing a list of part object (either a HTTP::Promise::Entity or a HTTP::Promise::Message object with an HTTP::Promise::Entity set with "entity").
multipart/mixed
For example:
$m->add_part( file1 => $ent1, file2 => $ent2, first_name => $ent3, last_name => $ent4, # etc... );
or, using the name attribute:
$ent1->name( 'file1' ); $ent2->name( 'file2' ); $ent3->name( 'first_name' ); $ent4->name( 'last_name' ); $m->add_part( $ent1, $ent2, $ent3, $ent4 );
Note that you can always set an entity name, and it will only be used if the HTTP message Content-Type is of type multipart/form-data, unless you set yourself the Content-Disposition header value.
Content-Disposition
It returns the current object, or upon error, sets an error and returns undef.
This will read the body of the HTTP entity and return it as an object of key-value pairs with the module HTTP::Promise::Body::Form
This supports HTTP Content-Type multipart/form-data, application/json, application/x-www-form-urlencoded, or in the case of HTTP method GET, HEAD, or DELETE, it will use any query string parameters, and return a new HTTP::Promise::Body::Form object.
application/json
application/x-www-form-urlencoded
GET
HEAD
DELETE
It defaults to application/x-www-form-urlencoded. Upon error, it will set an HTTP::Promise::Exception and return undef in scalar context, or an empty list in list context.
The way this works is it checks first for multipart/form-data, then application/json, and for query strings only if there is no HTTP body content, and else it fallbacks to application/x-www-form-urlencoded.
This means you must be careful if you send or receive JSON data to properly set the Content-Type to application/json
JSON
This takes an optional end-of-line terminator and returns a scalar object representing the entire HTTP message.
The end-of-line terminator defaults to $CRLF, which is a global variable of HTTP::Promise::Message
$CRLF
This is a shortcut.
It returns the result returned by "boundary" in HTTP::Promise::Headers
This behaves like "can" in UNIVERSAL, with a twist.
Provided with a method name and this check if this is supported by HTTP::Promise::Message, or in last resort by HTTP::Promise::Headers and if the latter is true, it will alias the headers method to this namespace.
It returns the code reference of the requested method, or undef if none could be found.
Clears out the headers object by calling "clear" in HTTP::Promise::Headers, empty the entity body, if any, and remove any part if any.
It does not return anything. This should be called in void context.
This clones the current HTTP message and returns a new object.
Get or set the HTTP message body.
If one or more values are provided, they will be added to the newly created HTTP::Promise::Body object.
You can provide as values one or more instance of either a string or a scalar reference.
$m->content( \$string, 'Hello world', \$another_string );
It returns the newly set HTTP::Promise::Body object upon success or, upon error, sets an error and returns undef.
When no argument is provided, this returns the HTTP::Promise::Body object as a scalar object.
Beware that the content returned might not be decoded if compression has been applied previously, or if compressed content was provided upon instantiation of the HTTP::Promise::Message object, such as:
HTTP::Promise::Message
my $m = HTTP::Promise::Message->new([ 'Content-Type' => 'text/plain', 'Content-Encoding' => 'deflate, base64', ], '80jNyclXCM8vyklRBAA=' ); my $content = $m->content; # 80jNyclXCM8vyklRBAA=
But even with utf-8 content, such as:
my $m = HTTP::Promise::Message->new([ 'Content-Type' => 'text/plain; charset=utf-8', ], "\x{E3}\x{81}\x{8A}\x{E6}\x{97}\x{A9}\x{E3}\x{81}\x{86}\x{EF}\x{BC}\x{81}\x{A}", ); my $content = $m->content;
$content would contain undecoded utf-8 bytes, i.e. not in perl's internal representation. Indeed, charset is never decoded. If you want the charset decoded content, use "decoded_content", which will guess the content charset to decode it into perl's internal representation. If you are sure this is utf-8, you can either call:
$content
my $decoded_content = $m->decoded_content( binmode => 'utf-8' );
or
my $decoded_content = $m->decoded_content_utf8;
See "decoded_content" for more information.
This is a convenient method that calls "content_charset" in HTTP::Promise::Entity and returns the result.
This method attempts at guessing the content charset of the entity body.
It returns a string representing the content charset, possibly empty if nothing was found, or upon error, sets an error and returns undef.
This sets or gets the content as a scalar reference.
In assignment mode, this takes a scalar reference and pass it to "content" and returns the body object
Otherwise, this returns the content as scalar object.
If an error occurs, this sets an error and returns undef.
This gets an array object of all supported and installed decodings on the system, by calling "decodable" in HTTP::Promise::Stream
This decodes the HTTP message body and return true.
If there is no Content-Encoding set, or the entity body is empty, or the entity body already has been decoded, this does nothing obviously. Otherwise, this calls "decode_body" in HTTP::Promise::Entity passing it the encodings as an array reference.
Content-Encoding
This is similar to </decode>, except that it takes an hash or hash reference of options passed to "decode_body" in HTTP::Promise::Entity, notably replace, which if true will replace the body by its decoded version and if false will return a new body version representing the decoded body.
replace
This returns the entity body object upon success, or upon error, sets an error and returns undef.
This takes an hash or hash reference of options and returns the decoded representation of the body, including charset.
This calls "decode_content", passing it the options provided, to decompress the entity body if necessary. Then, unless the binmode option was provided, this calls "io_encoding" in HTTP::Promise::Entity to guess the charset encoding, and set the binmode option to it, if anything was found.
binmode
If the entity body is an xml file, any BOM (Byte Order Mark) will be removed.
BOM
This returns the content as a scalar object, or upon error, sets an error and returns undef.
Supported options are:
The PerlIO encoding to apply to decode the data.
If not provided, this will be guessed by calling "io_encoding" in HTTP::Promise::Entity
charset_strict
If true, this will returns an error if there is some issues with the content charset. By default, this is false, making it lenient, especially with malformed utf-8.
raise_error
When set to true, this will cause this method to die upon error. Default is false.
This calls "decoded_content", but this sets the binmode option to utf-8.
utf-8
It returns whatever "decode_content" returns.
This takes an hash or hash reference of options and either print the resulting dump on the STDOUT in void content, or returns a string representation of the HTTP message, or upon error, sets an error and returns undef.
STDOUT
maxlength
The maximum amount of body data in bytes to display.
no_content
The string to use when there is no entity body data.
prefix
A string to be added at the beginning of each line of the data returned.
preheader
An arbitrary string to add before the HTTP headers, typically the HTTP start line
start line
# Returns a string my $dump = $msg->dump; # Prints on the STDOUT the result $msg->dump;
This takes an optional list of encoding and an optional hash or hash reference of options and encode the entity body and returns true, or upon error, sets an error and returns undef.
This will return an error if it is used on a multipart message or an message/* such as message/http.
message/*
message/http
Obviously this is a no-op if no encoding was found, or if the body is empty, or if the body is already marked as encoded
update_header
When true, this will set the Content-Encoding with the encoding used to encode the entity body and remove the headers Content-Length and Content-MD5. Defaults to true.
Content-Length
Content-MD5
Sets or gets the HTTP entity object
This is a shortcut by calling "header" in HTTP::Promise::Headers
Sets or gets the HTTP::Promise::Headers object.
This is a shortcut to call "as_string" in HTTP::Promise::Headers
Provided with an encoding and this returns true if the encoding is supported by HTTP::Promise::Stream
Returns a newly generated boundary, which is basically a uuid generated by the XS module Data::UUID
Provided with a string and this will try to parse this HTTP message and returns the current message object if it was called with an HTTP message, or a new HTTP message if it was called as a class function, or upon error, sets an error and returns undef.
my $msg = HTTP::Promise::Message->parse( $some_http_message ) || die( HTTP::Promise::Message->error ); $msg->parse( $some_http_message ) || die( HTTP::Promise::Message->error );
This returns the HTTP message entity parts as an array object and returns it, or upon error, sets an error and returns undef.
If the HTTP message has a body with content and there is no part and the mime-type top type is multipart or message, this will first parse the body into parts. Thus you could do:
multipart
message
my $msg = HTTP::Promise::Message->new([ Content_Type => 'multipart/form-data; boundary="abcd"', Content_Encoding => 'gzip', Host => 'example.org', ], <<EOT ); --abcd Content-Disposition: form-data; name="name" Jigoro Kano --abcd Content-Disposition: form-data; name="birthdate" 1860-12-10 --abcd-- EOT my $parts = $msg->parts;
Sets or gets the HTTP protocol. This is typically something like HTTP/1.0, HTTP/1.1, HTTP/2
HTTP/1.0
HTTP/1.1
HTTP/2
Returns the HTTP protocol, if any was set, as a scalar object, or upon error, sets an error and returns undef.
Note that it may return undef if no protocol was set. Errors are likely to occur when assigning an improper value.
This is a no-op since it is superseded by its inheriting classes HTTP::Promise::Request and HTTP::Promise::Response
Sets or gets the HTTP protocol version, something like 1.0, or 1.1, or maybe 2
1.0
1.1
2
This returns a number object
Jacques Deguest <jack@deguest.jp>
HTTP::Promise, HTTP::Promise::Request, HTTP::Promise::Response, HTTP::Promise::Message, HTTP::Promise::Entity, HTTP::Promise::Headers, HTTP::Promise::Body, HTTP::Promise::Body::Form, HTTP::Promise::Body::Form::Data, HTTP::Promise::Body::Form::Field, HTTP::Promise::Status, HTTP::Promise::MIME, HTTP::Promise::Parser, HTTP::Promise::IO, HTTP::Promise::Stream, HTTP::Promise::Exception
Copyright(c) 2022 DEGUEST Pte. Ltd.
All rights reserved This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install HTTP::Promise, copy and paste the appropriate command in to your terminal.
cpanm
cpanm HTTP::Promise
CPAN shell
perl -MCPAN -e shell install HTTP::Promise
For more information on module installation, please visit the detailed CPAN module installation guide.