NAME

PAGI::Server::Protocol::HTTP2 - HTTP/2 protocol handler using nghttp2

SYNOPSIS

use PAGI::Server::Protocol::HTTP2;

my $proto = PAGI::Server::Protocol::HTTP2->new;

if ($proto->available) {
    my $session = $proto->create_session(
        on_request => sub { ... },
        on_body    => sub { ... },
        on_close   => sub { ... },
    );
}

DESCRIPTION

PAGI::Server::Protocol::HTTP2 provides HTTP/2 support for PAGI::Server using the nghttp2 C library via Net::HTTP2::nghttp2.

Unlike HTTP/1.1, HTTP/2 uses binary framing, multiplexed streams on a single connection, HPACK header compression, and per-stream flow control.

This module bridges nghttp2's callback-based API to PAGI's event model.

detect_preface

if (PAGI::Server::Protocol::HTTP2->detect_preface($bytes)) { ... }

Returns true if $bytes starts with the HTTP/2 client connection preface. Used for h2c (cleartext HTTP/2) detection.

new

my $proto = PAGI::Server::Protocol::HTTP2->new(
    max_concurrent_streams  => 100,    # Default
    initial_window_size     => 65535,  # Default
    max_frame_size          => 16384,  # Default
    enable_push             => 0,      # Default (disabled)
    enable_connect_protocol => 1,      # Default (enabled, RFC 8441)
    max_header_list_size    => 65536,  # Default (64KB)
);

Creates a new HTTP/2 protocol handler with the specified settings.

create_session

my $session = $proto->create_session(
    on_request => sub { ($stream_id, $pseudo, $headers, $has_body) = @_ },
    on_body    => sub { ($stream_id, $data, $eof) = @_ },
    on_close   => sub { ($stream_id, $error_code) = @_ },
);

Creates a new HTTP/2 session for a connection. Returns a PAGI::Server::Protocol::HTTP2::Session wrapper.

feed

my $consumed = $session->feed($data);

Feed incoming data to the HTTP/2 session. Returns bytes consumed.

extract

my $data = $session->extract;

Extract outgoing data from the session. Returns bytes to send.

want_read

if ($session->want_read) { ... }

Check if session wants to read.

want_write

if ($session->want_write) { ... }

Check if session has data to write.

submit_response

$session->submit_response($stream_id,
    status  => 200,
    headers => [['content-type', 'text/html']],
    body    => $body,
);

Submit a response on a stream. body can be a string (sent as single response) or a coderef for streaming.

submit_response_streaming

$session->submit_response_streaming($stream_id,
    status        => 200,
    headers       => [['content-type', 'text/event-stream']],
    data_callback => sub {
        my ($stream_id, $max_len) = @_;
        return ($chunk, $is_eof);
    },
);

Submit a streaming response with a data provider callback.

resume_stream

$session->resume_stream($stream_id);

Resume a deferred stream after data becomes available.

submit_data

$session->submit_data($stream_id, $data, $eof);

Push data directly onto a stream. Used for WebSocket frame delivery over HTTP/2 where frames are sent as DATA payloads.

terminate

$session->terminate($error_code);

Terminate the session with GOAWAY.

HTTP/2 vs HTTP/1.1

Key differences that affect PAGI integration:

  • Multiplexing - Multiple concurrent requests on one TCP connection

  • Binary Framing - nghttp2 handles all framing; PAGI feeds/extracts bytes

  • Header Compression - HPACK is built into nghttp2

  • Flow Control - Per-stream and connection-level, via streaming callbacks

SEE ALSO

Net::HTTP2::nghttp2, PAGI::Server::Protocol::HTTP1