Application API in Unblock::HTTP3
Unblock::HTTP3 follows the same Client, Server, and Transaction vocabulary as Unblock::HTTP1 and Unblock::HTTP2. It runs over an existing Net::QUIC connection rather than accepting TCP/TLS wire bytes from a framework stream.
Server application
use Unblock::HTTP3::Server;
my $server = Unblock::HTTP3::Server->new(
quic => $quic,
on_request => sub {
my ($tx, $request) = @_;
$tx->respond(status => 200, body => "hello\n");
},
);
$server->start;
Client application
use Unblock::HTTP3::Client;
my $client = Unblock::HTTP3::Client->new(quic => $quic);
$client->start;
my $tx = $client->request(
method => 'GET',
target => '/',
scheme => 'https',
authority => 'example.test',
on_response => sub {
my ($tx, $response) = @_;
print $response->status, "\n";
},
);
Request and response objects from Uniform::HTTP are still accepted, and the engine returns those canonical objects to callbacks. The named forms avoid manual construction for common applications.
Incoming body lifecycle
Buffered incoming bodies are the standalone engine default. Each Client or
Server accepts receive_body => 'buffered' and a positive
max_buffered_body_bytes limit (64 MiB by default). When body reception
successfully completes, the same canonical Uniform message receives its final
body before it is frozen and before the body-completion callback. Empty bodies
remain empty strings, not undefined. A buffered-body overflow fails only its
HTTP/3 stream and discards that stream's retained bytes.
For streaming reception, register on_data while handling the incoming
headers, before any body bytes arrive:
my $server = Unblock::HTTP3::Server->new(
quic => $quic,
on_request => sub {
my ($tx, $request) = @_;
$tx->on_data(sub {
my ($tx, $bytes) = @_;
process_request_chunk($bytes);
});
$tx->on_finish(sub {
my ($tx) = @_;
record_terminal_state($tx->state, $tx->error);
});
},
);
The client can pass on_data => sub { ... } and on_finish => sub { ... }
directly in request(), or register them during on_response. on_data
receives decoded HTTP body payload octets; it does not decode content
encodings. It disables whole-body accumulation for that transaction. The old
on_body remains available, but must not be combined with on_data.
An on_finish callback fires once after complete, cancelled, or error
terminal state and after applicable completion/error callbacks. Terminal
notification is distinct from incoming body completion and does not alter
the native Transaction's identity.
Transport integration
The host framework owns its UDP socket and timers. Net::QUIC handles QUIC and
TLS 1.3. Unblock::HTTP3 handles HTTP/3 and registers QUIC stream callbacks
when start() is called.
The TCP-oriented transport => $stream, input($bytes) and unblock_send()
contract used by Unblock::HTTP1 and Unblock::HTTP2 is not suitable for HTTP/3
QUIC datagrams. The framework must instead integrate Net::QUIC correctly.
Do not feed UDP packets directly to an HTTP/3 Client or Server.
For the complete UDP and timer contract, read Unblock::HTTP3::Integration.
Working Linux::Event examples are in examples/linux-event-client.pl and
examples/linux-event-server.pl.
Body::Stream, Body::Reader, priority, Datagram, Capsule, Extended CONNECT,
and 0-RTT options remain available to advanced callers.