NAME
Linux::Event::HTTP::Client - Make HTTP requests with Linux::Event
SYNOPSIS
use v5.36;
use Linux::Event::Loop;
use Linux::Event::HTTP::Client;
my $loop = Linux::Event::Loop->new;
my $client = Linux::Event::HTTP::Client->new(loop => $loop);
$client->get(
'https://example.com/',
timeout => 15,
on_response => sub ($tx, $res) {
say "HTTP ", $res->status;
say $res->body;
},
on_error => sub ($object, $error, @details) {
warn "Request failed: $error\n";
},
on_finish => sub { $loop->stop },
);
$loop->run;
DESCRIPTION
Linux::Event::HTTP::Client makes HTTP requests without blocking the event loop. Create one Client and reuse it for many requests. The Client manages connections, HTTPS, and HTTP messages for you.
HTTP/1.1 works by default. HTTP/2 and HTTP/3 are optional.
MAKING REQUESTS
Call get, post, put, head, or delete with a URL followed by options. Each call returns immediately; the request is handled while the loop runs.
To send a POST with a body and headers:
$client->post(
'https://example.com/messages',
headers => [['content-type', 'text/plain']],
body => "Hello\n",
on_response => sub ($tx, $res) {
say $res->status;
say $res->body;
},
);
Headers are an array reference of name/value pairs. For other HTTP methods, use request:
$client->request(
method => 'PATCH',
url => 'https://example.com/item/1',
body => 'updated',
on_response => sub ($tx, $res) {
say $res->status;
},
);
RESPONSES AND CALLBACKS
on_response receives a transaction $tx and a response $res. The response is a Uniform::HTTP::Response object. Common methods are:
$res->status; # HTTP status code
$res->body; # Response body
$res->header('content-type'); # A header value
HTTP 404 and 500 are valid responses, not connection errors. Check $res->status to decide how to handle them.
Response bodies are not automatically decompressed. If you want to request plain content, pass headers => [['accept-encoding', 'identity']] in the request. Servers can still send compressed content, so check the Content-Encoding response header and decode the body yourself when necessary.
By default, on_response runs after the entire response body has arrived. $res->body is ready to read at that point.
on_response($tx, $res)- receives the response.on_error($object, $error, @details)- reports failures, such as connection errors or timeouts.on_finish- runs once when the operation ends, including after success, failure, or cancellation.
For a single-request program, stop the loop in on_finish, not in on_response. That way the program also stops if the request fails. An HTTP request's timeout is in seconds and includes connection waiting time.
STREAMING A RESPONSE
For a large body, add on_data to process chunks as they arrive:
$client->get(
'https://example.com/large-file',
on_response => sub ($tx, $res) {
say "HTTP ", $res->status;
},
on_data => sub ($tx, $bytes) {
print $bytes;
},
on_end => sub ($tx) {
say "\nBody complete";
},
on_error => sub ($object, $error, @details) {
warn "Request failed: $error\n";
},
on_finish => sub { $loop->stop },
);
Adding on_data changes the timing:
Without
on_data,on_responseruns after the full body.With
on_data,on_responseruns as soon as headers arrive.on_datareceives body chunks;on_endsignals successful body completion.
Without streaming, responses are buffered up to 1 MiB by default. If the body exceeds that limit, the request fails and on_error runs; on_response does not receive a partial buffered body.
You often cannot know the body size in advance. If a response might be larger than the limit, or its size is unknown, use on_data from the start. This works for small responses too. The Client does not switch from buffered mode to streaming automatically. A Content-Length header is not always available, and may not predict the amount of body data delivered.
STREAMING AN UPLOAD
Set stream_body => 1 and send pieces through the transaction provided to on_transaction:
$client->post(
'https://example.com/upload',
stream_body => 1,
on_transaction => sub ($tx) {
$tx->write("First part\n");
$tx->end("Last part\n");
},
on_response => sub ($tx, $res) {
say $res->status;
},
);
on_transaction may run before the request call returns. Use its $tx argument, not a variable holding the returned operation. For large producers, respect backpressure and resume sending through on_drain. A false return from write means the bytes were accepted; do not send them twice.
CANCELLING AND SHUTTING DOWN
Each request returns an operation handle:
my $op = $client->get('https://example.com/',
on_response => sub ($tx, $res) { say $res->status },
);
$op->cancel; # Cancel when no longer needed
$op->state; # Current state
$op->error; # Error, if any
$op->is_terminal; # Whether it has ended
$op->transaction; # Available once the request starts
Call $client->shutdown to cancel queued work, let active requests finish, and retire pooled connections. pool_stats and pending_count report connection and queue information.
HTTPS AND HTTP VERSIONS
HTTPS checks certificates and hostnames by default. To trust a private certificate authority:
my $client = Linux::Event::HTTP::Client->new(
loop => $loop,
tls => { ca_file => 'ca.pem' },
);
HTTP/1.1 is enabled by default. To enable HTTP/2, install Unblock::HTTP2 0.13 or later and pass http2 => 1 to new. For HTTP/3, install Unblock::HTTP3 0.14 or later and Net::QUIC 0.06 or later, then pass http3 => 1. HTTP/3 uses HTTPS and supports a private CA through quic => { ca_file => 'ca.pem' }.
To require a specific HTTP version on a request, set http_version => '1.1', '2', or '3'. If the required version is unavailable, the request fails instead of falling back.
MORE OPTIONS
new requires loop => $loop. Other options include max_connections_per_origin (default 4), max_pending_requests (default 128), and idle_timeout (in seconds, disabled by default).
The Client does not automatically follow redirects or manage cookies or authentication retries.
Optional WebSocket support uses connect_websocket with a protocol option such as http1 => { websocket => 1 }. See Unblock::HTTP::Client for the full WebSocket API. For custom Upgrade and CONNECT handoff, see docs/CONNECT.md in the distribution.
SEE ALSO
Linux::Event::HTTP::Server, Linux::Event::Loop, Unblock::HTTP::Client, Uniform::HTTP::Response.
The distribution's docs/GETTING-STARTED.md contains more complete examples.