Protoc...:Client(3pm)
π Protocol::HTTP2::Client β the manual, but make it cute π
okay bestie so this is Protocol::HTTP2::Client(3pm), from the User Contributed Perl Documentation section of the manual. It's a whole HTTP/2 client library written in Perl and it is lowkey iconic. Let's get into it. π¦
β¨ NAME β¨
Protocol::HTTP2::Client β the HTTP/2 client. yes. that's the whole name. slay. π
πΈ SYNOPSIS πΈ
here's the whole vibe in one code block, copied exactly because I would never mess with your code, bestie:
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 an HTTP/2 client library, periodt. The whole point of it is to let you build http2-client implementations on top of your favorite event-loop. your loop, your rules. main character energy fr fr. π
π§ METHODS π§
new
Initialize a brand new client object:
my $client = Protocol::HTTP2::Client->new( %options );
Available options, and bestie I need you to read all of them:
on_push=> sub {...} β if the server sends a push promise, this callback gets invoked. it's giving β¨unsolicited giftsβ¨. The shape of it:
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 the protocol from HTTP/1.1 to HTTP/2. Heads up: upgrade is possible only on a plain (non-tls) connection. Default value is0.
See Starting HTTP/2 for "http" URIs <https://tools.ietf.org/html/rfc7540#section-3.2>
keepalive=> 0|1 β keep the connection alive after requests. Default value is0. Don't forget to explicitly call theclosemethod if you set this to true. yes it's a whole commitment, treat it like one. πon_error=> sub {...} β callback invoked on protocol errors:
on_error => sub {
my $error = shift;
...
},
on_change_state=> sub {...} β callback invoked every time http/2 streams change their state. the way it fires on every single transitionβ¦ obsessed.
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 an HTTP/2 request. here's what it looks like:
$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",
);
and yes, you can chain requests one by one, look at her go:
$client->request( 1-st request )->request( 2-nd request );
Available callbacks:
on_done=> sub {...} β invoked when the full server's response is available. the grand finale π
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 of toon_done.on_donewill receive an empty string. (yes it's handing over the aux, but politely. π§)
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 the connection alive after requests:
my $bool = $client->keepalive;
$client = $client->keepalive($bool);
shutdown
Get the connection status:
0β active1β closed (you can terminate connection)
close
Explicitly close the connection (sends a GOAWAY frame). This is required if the client has the keepalive option enabled. like, mandatory mandatory. π
next_frame
get the next frame to send over the connection to the server. Returns:
undefβ on error0β nothing to send- binary string β encoded frame
# Example
while ( my $frame = $client->next_frame ) {
syswrite $fh, $frame;
}
feed
Feed the decoder with chunks of the server's response:
sysread $fh, $binary_data, 4096;
$client->feed($binary_data);
ping
Send a ping frame to the server (to keep the connection alive). just checking in on her π«Ά
$client->ping
or
$client->ping($payload);
The payload can be an arbitrary binary string and must contain 8 octets. If the payload argument is omitted, the client will send random data.
and that's the whole page, bestie, no notes. this one shipped in perl v5.42.3, dated 2026-09-04, and it lives at Protoc...:Client(3pm) in your man pages. go build something iconic with it. πβ¨π
π¦ where this page comes from
- fedora 43: perl-Protocol-HTTP2 1.14-1.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- fedora 44: perl-Protocol-HTTP2 1.14-1.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms