Protocol::HTTP2::Client - HTTP/2 client

NAME  SYNOPSIS  DESCRIPTION  METHODS 

NAME

Protocol::HTTP2::Client − HTTP/2 client

SYNOPSIS

use Protocol::HTTP2::Client;
# Create client object
my $client = Protocol::HTTP2::Client−>new;
# Prepare first request
$client−>request(
# HTTP/2 headers
':scheme' => 'http',
':authority' => 'localhost:8000',
':path' => '/',
':method' => 'GET',
# HTTP/1.1 headers
headers => [
'accept' => '*/*',
'user−agent' => 'perl−Protocol−HTTP2/0.13',
],
# Callback when receive server's response
on_done => sub {
my ( $headers, $data ) = @_;
...
},
);
# Protocol::HTTP2 is just HTTP/2 protocol decoder/encoder
# so you must create connection yourself
use AnyEvent;
use AnyEvent::Socket;
use AnyEvent::Handle;
my $w = AnyEvent−>condvar;
# Plain−text HTTP/2 connection
tcp_connect 'localhost', 8000, sub {
my ($fh) = @_ or die "connection failed: $!\n";
my $handle;
$handle = AnyEvent::Handle−>new(
fh => $fh,
autocork => 1,
on_error => sub {
$_[0]−>destroy;
print "connection error\n";
$w−>send;
},
on_eof => sub {
$handle−>destroy;
$w−>send;
}
);
# First write preface to peer
while ( my $frame = $client−>next_frame ) {
$handle−>push_write($frame);
}
# Receive servers frames
# Reply to server
$handle−>on_read(
sub {
my $handle = shift;
$client−>feed( $handle−>{rbuf} );
$handle−>{rbuf} = undef;
while ( my $frame = $client−>next_frame ) {
$handle−>push_write($frame);
}
# Terminate connection if all done
$handle−>push_shutdown if $client−>shutdown;
}
);
};
$w−>recv;

DESCRIPTION

Protocol::HTTP2::Client is HTTP/2 client library. It’s intended to make http2−client implementations on top of your favorite event-loop.

METHODS

new

Initialize new client object

my $client = Procotol::HTTP2::Client−>new( %options );

Available options:
on_push => sub {...}

If server send push promise this callback will be invoked

on_push => sub {
# received PUSH PROMISE headers
my $pp_header = shift;
...
# if we want reject this push
# return undef
# if we want to accept pushed resource
# return callback to receive data
return sub {
my ( $headers, $data ) = @_;
...
}
},

upgrade => 0|1

Use HTTP/1.1 Upgrade to upgrade protocol from HTTP/1.1 to HTTP/2. Upgrade possible only on plain (non-tls) connection. Default value is 0.

See Starting HTTP/2 for "http" URIs <https://tools.ietf.org/html/rfc7540#section-3.2>

keepalive => 0|1

Keep connection alive after requests. Default value is 0. Don’t forget to explicitly call close method if set this to true.

on_error => sub {...}

Callback invoked on protocol errors

on_error => sub {
my $error = shift;
...
},

on_change_state => sub {...}

Callback invoked every time when http/2 streams change their state. See Stream States <https://tools.ietf.org/html/rfc7540#section-5.1>

on_change_state => sub {
my ( $stream_id, $previous_state, $current_state ) = @_;
...
},

request

Prepare HTTP/2 request.

$client−>request(
# HTTP/2 headers
':scheme' => 'http',
':authority' => 'localhost:8000',
':path' => '/items',
':method' => 'POST',
# HTTP/1.1 headers
headers => [
'content−type' => 'application/x−www−form−urlencoded',
'user−agent' => 'perl−Protocol−HTTP2/0.06',
],
# Callback when receive server's response
on_done => sub {
my ( $headers, $data ) = @_;
...
},
# Callback when receive stream reset
on_error => sub {
my $error_code = shift;
},
# Body of POST request
data => "hello=world&test=done",
);

You can chaining request one by one:

$client−>request( 1−st request )−>request( 2−nd request );

Available callbacks:
on_done => sub {...}

Invoked when full servers response is available

on_done => sub {
my ( $headers, $data ) = @_;
...
},

on_headers => sub {...}

Invoked as soon as headers have been successfully received from the server

on_headers => sub {
my $headers = shift;
...
# if we want reject any data
# return undef
# continue
return 1
}

on_data => sub {...}

If specified all data will be passed to this callback instead if on_done. on_done will receive empty string.

on_data => sub {
my ( $partial_data, $headers ) = @_;
...
# if we want cancel download
# return undef
# continue downloading
return 1
}

on_error => sub {...}

Callback invoked on stream errors

on_error => sub {
my $error = shift;
...
}

keepalive

Keep connection alive after requests

my $bool = $client−>keepalive;
$client = $client−>keepalive($bool);

shutdown

Get connection status:
0 − active
1 − closed (you can terminate connection)

close

Explicitly close connection (send GOAWAY frame). This is required if client has keepalive option enabled.

next_frame

get next frame to send over connection to server. Returns:
undef − on error
0 − nothing to send
binary string − encoded frame

# Example
while ( my $frame = $client−>next_frame ) {
syswrite $fh, $frame;
}

feed

Feed decoder with chunks of server’s response

sysread $fh, $binary_data, 4096;
$client−>feed($binary_data);

ping

Send ping frame to server (to keep connection alive)

$client−>ping

or

$client−>ping($payload);

Payload can be arbitrary binary string and must contain 8 octets. If payload argument is omitted client will send random data.


Updated 2024-01-29 - jenkler.se | uex.se