NAME

Linux::Event::HTTP::Client - high-level HTTP/1.x and HTTP/2 client

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,
    http2 => 1,
);

my $operation = $client->get(
    'https://example.com/',

    buffer_body => 1_048_576,

    on_complete => sub ($tx) {
        say $tx->response->status;
        say $tx->response->body;

        $client->close;
        $loop->stop;
    },

    on_error => sub ($tx, $error) {
        warn $error;
        $client->close;
        $loop->stop;
    },
);

$loop->run;

DESCRIPTION

Linux::Event::HTTP::Client is the ordinary outbound HTTP entry point.

It owns URL handling, connection selection and reuse, redirects, optional cookie and authentication policy, explicit proxy routing, TLS policy, and HTTP/2 selection.

Client methods return a Linux::Event::HTTP::Client::Operation. An Operation normally contains one Transaction. Redirects and automatic authentication retries create additional Transactions because one Linux::Event::HTTP::Transaction always means exactly one Request/Response exchange.

CONSTRUCTOR

my $client = Linux::Event::HTTP::Client->new(%options);

Common options include:

  • loop

    The Linux::Event::Loop.

  • http2

    Enables HTTP/2 negotiation for direct HTTPS requests. HTTP/2 requires Net::HTTP2::nghttp2 0.011 or newer.

  • tls

    Linux::Event TLS options for HTTPS connections.

  • max_redirects

    Default redirect limit. Default: 5.

  • max_auth_retries

    Default automatic 401/407 authentication retry limit. Default: 3.

  • cookie_jar

    An application-owned HTTP::CookieJar.

  • auth

    A Uniform::HTTP::Auth manager for target-server authentication.

  • proxy_auth

    A Uniform::HTTP::Auth manager for proxy authentication.

  • proxy

    Default explicit forward-proxy URL.

  • http2_max_header_list_size

    Maximum decoded HTTP/2 response header-list size. Default: 65,536 bytes.

  • http2_max_buffered_response_bytes

    Aggregate per-HTTP/2-connection budget for active buffered responses. Default: 67,108,864 bytes (64 MiB).

REQUESTS

The general form is:

my $operation = $client->request(
    'POST',
    'https://example.com/items',
    body => $bytes,

    on_response => sub ($tx, $res) { ... },
    on_body     => sub ($tx, $res, $bytes) { ... },
    on_complete => sub ($tx) { ... },
    on_error    => sub ($tx, $error) { ... },
);

Only absolute http and https target URLs are accepted.

Convenience methods get, head, post, put, and delete call request with the corresponding method.

CALLBACKS

on_response runs when the final response head is available.

on_body receives decoded response-body bytes incrementally.

on_complete runs after the complete final response boundary.

on_error reports terminal operation failure.

on_redirect runs when an actual redirect is followed.

Low-level informational responses may be exposed through the appropriate connection callback path; redirect and authentication challenge bodies are consumed internally when the Client is going to continue the Operation.

RESPONSE BODIES

Incoming response bodies are streaming-first.

Use on_body for incremental consumption:

on_body => sub ($tx, $res, $bytes) {
    process_bytes($bytes);
}

If on_body is absent, body bytes are drained rather than accumulated.

To request whole-body buffering, provide an explicit limit:

buffer_body => 4 * 1024 * 1024

After successful completion:

my $bytes = $tx->response->body;

There is no implicit unbounded response buffer.

REQUEST BODIES

For a complete body already in memory:

$client->post(
    $url,
    body => $bytes,
    ...
);

For incremental production:

my $operation = $client->post(
    $url,

    stream_body => {
        on_drain  => sub ($body) { ... },
        on_cancel => sub ($body) { ... },
    },

    ...
);

my $body = $operation->request_body;
$body->write($chunk);
$body->complete;

A streaming producer is available immediately, including while HTTPS TLS/ALPN selection is still in progress.

A supplied Content-Length is enforced. Unknown-length HTTP/1.1 streaming uses chunked framing automatically. HTTP/2 uses its native DATA framing and does not add Transfer-Encoding.

HTTP/2

Enable HTTP/2 with:

my $client = Linux::Event::HTTP::Client->new(
    loop  => $loop,
    http2 => 1,
);

For direct HTTPS requests the Client advertises h2 before http/1.1. If H2 is selected, the same high-level Operation, Transaction, Request, and callback model is used.

Selected HTTP/2 connections are pooled per origin and may carry concurrent streams. The current local active-stream admission cap is 100 per connection; nghttp2 also enforces peer SETTINGS.

A connection that receives GOAWAY is marked draining and receives no new Operations. Existing streams are allowed to finish. Transparent replay based on GOAWAY is not attempted without reliable last-stream-id information.

Current HTTP/2 boundaries:

  • Direct HTTPS + ALPN is the production HTTP/2 path.

  • Cleartext h2c is not provided.

  • Explicit forward proxies use the HTTP/1 path.

  • HTTP/1 Upgrade and CONNECT handoff use the HTTP/1 path.

  • Explicit HTTP version selection uses the HTTP/1 path.

  • HTTP/2 currently requires the default Client connection class.

REDIRECTS

The Client follows 301, 302, 303, 307, and 308 by default.

max_redirects defaults to 5. Set it to 0 to disable automatic redirect following.

Every followed redirect creates another Transaction in the Operation.

301 and 302 may convert POST to GET. 303 uses GET except for HEAD. 307 and 308 preserve method and body.

Complete scalar bodies can be replayed where required. Streaming body producers are not automatically replayed.

Sensitive caller-supplied origin credentials are not propagated across origins.

COOKIES

Cookie policy is provided by an injected HTTP::CookieJar:

my $client = Linux::Event::HTTP::Client->new(
    loop       => $loop,
    cookie_jar => $jar,
);

The jar is application-owned. Linux::Event::HTTP does not create an implicit global cookie store.

Target URL identity remains separate from proxy route identity.

AUTHENTICATION

HTTP authentication mechanics are delegated to Uniform::HTTP::Auth.

Use auth for target-server 401 challenges and proxy_auth for proxy 407 challenges.

Automatic authentication retry creates another Transaction in the same Operation. The default retry limit is 3.

Streaming Request producers are not automatically replayed after a challenge.

FORWARD PROXIES

A default explicit proxy may be supplied to the Client:

proxy => 'http://proxy.example:3128'

It may also be overridden per request.

The target URL remains the Operation identity while the proxy URL selects the route connection. Target cookies and target authentication remain keyed to the target; proxy authentication remains keyed to the proxy.

For an HTTPS proxy endpoint, TLS is established to the proxy itself. An HTTPS target sent through ordinary forward-proxy mode is not silently converted into a CONNECT tunnel.

CLIENT UPGRADE

An ordinary HTTP/1.1 request can opt into protocol Upgrade with:

upgrade_to => 'MyProtocolConnection'

The Request must advertise the Upgrade normally. On a validated 101 response, the HTTP Transaction completes and the same live Linux::Event stream transitions to the requested class.

Already-read post-HTTP bytes are preserved for the new protocol.

Upgrade is an HTTP/1 transport handoff and therefore uses the HTTP/1 path even when this Client has http2 => 1.

CONNECT TUNNELS

Use connect_tunnel when a real HTTP/1.1 CONNECT tunnel is required:

$client->connect_tunnel(
    $proxy_url,
    $target_authority,
    tunnel_to => 'MyTunnelConnection',
    ...
);

A successful 2xx CONNECT response completes the HTTP Transaction at the response-head boundary and transitions the same live Linux::Event stream to the requested tunnel class.

Non-2xx responses remain ordinary HTTP responses.

CONNECTION REUSE

HTTP/1 connections are reused when response framing and persistence rules leave the connection safe for another exchange.

Selected HTTP/2 connections remain in a per-origin pool while streams are active and may carry concurrent Operations.

Forward-proxy HTTP/1 connections are pooled by route origin rather than target origin.

METHODS

request

Starts one high-level HTTP Operation and returns it immediately.

get, head, post, put, delete

Convenience request methods.

connect_tunnel

Establishes an explicit HTTP/1.1 CONNECT tunnel.

loop

Returns the Loop.

http2

True when HTTP/2 support is enabled.

http2_max_header_list_size

Returns the HTTP/2 decoded response header-list limit.

http2_max_buffered_response_bytes

Returns the aggregate per-H2-connection buffered-response budget.

max_redirects

Returns the default redirect limit.

max_auth_retries

Returns the default automatic authentication retry limit.

Returns the configured cookie jar or undef.

auth

Returns the configured target authentication manager or undef.

proxy_auth

Returns the configured proxy authentication manager or undef.

proxy

Returns the configured default forward-proxy URL or undef.

connection_class

Returns the configured HTTP/1 Client::Connection class.

is_closed

True after the Client has been closed.

close

Closes Client-owned idle and active connections according to Client shutdown semantics.

SEE ALSO

Linux::Event::HTTP, Linux::Event::HTTP::Server, Linux::Event::HTTP::Client::Operation, Linux::Event::HTTP::Client::Connection, Linux::Event::HTTP::Request, Linux::Event::HTTP::Response, Linux::Event::HTTP::Transaction, Linux::Event::HTTP::Body::Stream, Uniform::HTTP::Auth, HTTP::CookieJar.