NAME
HTTP::Promise::IO - I/O Handling Class for HTTP::Promise
SYNOPSIS
use HTTP::Promise::IO;
my $this = HTTP::Promise::IO->new( $fh ) ||
die( HTTP::Promise::IO->error, "\n" );
VERSION
v0.1.0
DESCRIPTION
This class implements a filehandle reader and writer with a twist.
First off, it does not rely on lines, since data stream or in general data from HTTP requests and responses do not necessarily always contain lines. Binary data are sent without necessarily any line at all.
Second, it is easy on memory by implementing "read", which uses a shared "buffer", and you can use "unread" to return data to it (they would be prepended).
Last, but not least, it implements 2 methods to read in chunks of data from the filehandle until some string pattern specified is found: "read_until" and "read_until_in_memory"
CONSTRUCTOR
new
This takes a proper filehandle and will ensure the O_NONBLOCK
bit is set, so that it can timeout if there is no more data streamed from the filehandle.
It returns the newly instantiated object upon success, and upon error, sets an error and return undef
Possible optional parameters are:
buffer
-
You can pass some data that will set the initial read buffer, from which other methods in this class access before reading from the filehandle.
max_read_buffer
-
An integer. You can set this a default value for the maximum size of the read buffer.
This is used by "getline" and "read_until_in_memory" to limit how much data can be read into the buffer until it returns an error. Hopefully a line or a match specified with
read_until
would be found and returned before this limit is reached.If this is greater than 0 and the amount of data loaded exceeds this limit, and error is returned.
timeout
-
AN integer. This is the read timeout. It defaults to 10.
METHODS
buffer
Sets or gets the buffer.
This is used by those class methods to get leftover data from the buffer, if any, or from the filehandle if necessary.
This returns a scalar object
can_read
Returns true if it can read from the filehandle or false otherwise.
It takes an optional hash or hash reference of options, of which, timeout
is the only one.
close
Close the filehandle and destroys the current object.
connect
Provided with an hash or hash reference of options and this will connect to the remote server.
It returns a new HTTP::Promise::IO object, or upon error, it sets an error and returns undef
Supported options are:
All the options used for object instantiation. See "CONSTRUCTOR" and the following ones:
debug
Integer representing the level of debug.
host
The remote host to connect to.
port
An integer representing the remote port to connect to.
stop_if
A code reference that serves as a callback and that is called where there is an
EINTR
error. If the callback returns true, the connection attempts stop there and returns an error. This default to return false.timeout
An integer or a decimal representing a timeout to be used when resolving the host, or when making remote connection.
connect_ssl
This takes the same options has "connect", but performs an SSL connection.
Like "connect", this returns a new HTTP::Promise::IO object, or upon error, it sets an error and returns undef
connect_ssl_over_proxy
Provided with an hash or hash reference of options and this will connect to the remote server.
It returns a new HTTP::Promise::IO object, or upon error, it sets an error and returns undef
Supported options are:
All the options used for object instantiation. See "CONSTRUCTOR" and the following ones:
debug
Integer representing the level of debug.
host
The remote host to connect to.
port
An integer representing the remote port to connect to.
proxy_authorization
The proxy authorisation string to use for authentication.
proxy_host
The remote proxy host to connect to.
proxy_port
An integer representing the remote proxy port to connect to.
stop_if
A code reference that serves as a callback and that is called where there is an
EINTR
error. If the callback returns true, the connection attempts stop there and returns an error. This default to return false.timeout
An integer or a decimal representing a timeout to be used when resolving the host, or when making remote connection.
filehandle
Sets or gets the filehandle being used. This is the same filehandle that was passed upon object instantiation.
getline
Reads from the buffer, if there is enough data left over, or from the filehandle and returns the first line found.
A line is a string that ends with \012
which is portable and universal. This would be the equivalent of \n
.
It returns the line found, if any, or undef
if there was an error that you can retrieve with error.
it takes an optional hash or hash reference of options:
chomp
-
If true, this will chomp any trailing sequence of
\012
possibly preceded by\015
max_read_buffer
-
An integer that limits how much cumulative data can be read until it exceeds this allowed maximum. When that happens, an error is returned.
inactivity_timeout
Integer representing the amount of second to wait until a connection is deemed idle and closed.
last_delimiter
Sets or gets the last delimiter found. A delimiter is some pattern that is provided to "read_until" and "read_until_in_memory" with the option capture
set to a true value.
This returns the last delimited found as a scalar object
make_select
Provided with an hash or hash reference of options and this "select" in perlfunc the filehandle or socket using the timeout
provided.
It returns a positive integer upon success, and upon error, this sets an error and returns undef
.
Supported options are:
timeout
Integer representing the timeout.
write
Boolean. When true, this will check the filehandle or socket for write capability, or if false for read capability.
make_select_timeout
This takes the same options as "make_select", and it will retry selecting the filehandle or socket until success or a timeout occurs. If an EINTR
error occurs, it will query the callback provided with "stop_if". If the callback returns true, it will return an error, or keep trying otherwise.
Returns true upon success, and upon error, this sets an error and returns undef
.
max_read_buffer
Sets or gets the maximum bytes amount of the read buffer.
This is used by "getline" and "read_until_in_memory" to limit how much data can be read into the buffer until it returns an error. Hopefully a line or a match specified with read_until
would be found and returned before this limit is reached.
If this is greater than 0 and the amount of data loaded exceeds this limit, and error is returned.
Provided with some data to print to the underlying filehandle or socket, and this will call "write" and return true upon success, or false otherwise.
read
my $bytes = $r->read( $buffer, $length );
my $bytes = $r->read( $buffer, $length, $offset );
This reads $length
bytes from either the internal buffer if there are leftover data, or the filehandle, or even both if the internal buffer is not big enough to meet the $length
requirement.
It returns how many bytes actually were loaded into the caller's $buffer
. It returns undef
after having set an error if an error occurred.
Just like the perl core "read" in perlfunc function, this one too will pad with \0
the caller's buffer if the offset specified is greater than the actual size of the caller's buffer.
Note that there is no guarantee that you can read from the filehandle the desired amount of bytes in just one time, especially if the filehandle is a socket, so you may need to do:
my $bytes;
my $total_to_read = 102400;
my $total_bytes;
while( $bytes = $r->read( $buffer, $chunk_size ) )
{
$out-print( $buffer ) || die( $! );
# If you want to make sure you do not read more than necessary, otherwise, you can discard this line
$chunk_size = ( $total_to_read - $total_bytes ) if( ( $total_bytes < $total_to_read ) && ( ( $total_bytes + $chunk_size ) > $total_to_read ) );
$total_bytes += $bytes;
last if( $total_bytes == $total_to_read );
}
# Check if something bad happened
die( "Something wrong happened: ", $r->error ) if( !defined( $bytes ) );
read_until
my $bytes = $r->read_until( $buffer, $length, $options_hashref );
my $bytes = $r->read_until( $buffer, $length, $offset, $options_hashref );
This is similar to "read", but will read data from either the buffer, the filehandle or a combination of both until the specified string
, passed as an option, is found.
It loads data in chunks specified with the option chunk_size
or by default 2048 bytes. If the specified string is not found within that buffer, it returns how many bytes where read and sets the caller's buffer with the data collected.
Upon the last call when the string
is finally found, this will return the number of bytes read, but as a negative number. This will tell you it has found the match. You can consider the number is negative because those are the last n bytes.
When no more data at all can be read, this will return 0.
If an error occurred, this will set an error and return undef
The possible options that can be passed as an hash reference only are:
capture
-
Boolean. When set to true, this will capture the match specified with
string
. The resulting would then be retrievable using "last_delimiter" chunk_size
-
An integer. This is the maximum bytes this will read per each iteration.
exclude
-
Boolean. If this is true, this will exclude the
string
sought from the buffer allocation. include
-
Boolean. If this is true, this will set the buffer including the
string
sought after. string
-
This is the
string
to read data until it is found. Thestring
can be a simple string, or a regular expression.
read_until_in_memory
my $data = $r->read_until_in_memory( $string );
my $data = $r->read_until_in_memory( $string, $options_hash_or_hashref );
die( "Error: ", $r->error ) if( !defined( $data ) );
Provided with a string
to be found, this will load data from the internal buffer, the filehandle, or a combination of both into memory until the specified string
is found.
Upon success, it returns the data read, which could be an empty string if nothing matched.
If an error occurred, this will set an error and return undef
.
It takes the following possible options, either as an hash or hash reference:
capture
-
Boolean. When set to true, this will capture the match specified with
string
. The resulting would then be retrievable using "last_delimiter" chunk_size
-
An integer. This is the maximum bytes this will read per each iteration.
exclude
-
Boolean. If this is true, this will exclude the
string
sought from the buffer allocation. include
-
Boolean. If this is true, this will set the buffer including the
string
sought after.
ssl_opts
Sets or gets an hash reference of ssl options to be used with "start_SSL" in IO::Socket::SSL
stop_if
Sets or gets a code reference acting as a callback when an error EINTR
if encountered. If the callback returns true, the method using it, will stop and return an error, otherwise, it will keep trying.
timeout
Sets or gets the timeout threshold. This returns a number object
unread
Provided with some data and this will put it back into the internal buffer, at its beginning.
This returns the current object for chaining.
write
This write to the filehandle set, and takes a buffer to write, an optional length, an optional offset, and an optional timeout value.
If no length is provided, this default to the length of the buffer.
If no offset is provided, this default to 0
.
If no timeout is provided, this default to the value set with "timeout"
It returns the number of bytes written or, upon error, sets an error and returns undef
write_all
Provided with some data an an optional timeout, and this will write the data to the filehandle set.
It returns the number of bytes written or, upon error, sets an error and returns undef
AUTHOR
Jacques Deguest <jack@deguest.jp>
SEE ALSO
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 & LICENSE
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.