NAME
Net::HTTP2::nghttp2::Session - HTTP/2 session management
SYNOPSIS
use Net::HTTP2::nghttp2::Session;
my $session = Net::HTTP2::nghttp2::Session->new_server(
callbacks => {
on_begin_headers => sub {
my ($session, $stream_id) = @_;
# New stream started
},
on_header => sub {
my ($session, $stream_id, $name, $value, $flags) = @_;
# Header received
},
on_frame_recv => sub {
my ($session, $frame) = @_;
# Frame received
},
on_stream_close => sub {
my ($session, $stream_id, $error_code) = @_;
# Stream closed
},
on_data_chunk_recv => sub {
my ($session, $stream_id, $data, $flags) = @_;
# Body data received
},
},
);
# Send connection preface
$session->send_connection_preface(
max_concurrent_streams => 100,
);
# Process incoming data
$session->mem_recv($incoming_bytes);
# Get outgoing data to send
my $outgoing = $session->mem_send();
# Submit a response
$session->submit_response($stream_id,
status => 200,
headers => [
['content-type', 'text/html'],
],
body => '<html>...</html>',
);
METHODS
new_server
my $session = Net::HTTP2::nghttp2::Session->new_server(%args);
Create a new server-side HTTP/2 session.
Arguments:
- callbacks
-
Hashref of callback handlers. Required callbacks:
on_begin_headers,on_header,on_frame_recv. Optional:on_data_chunk_recv,on_stream_close. - user_data
-
Optional scalar passed to callbacks.
- settings
-
Optional hashref of initial HTTP/2 settings.
new_client
my $session = Net::HTTP2::nghttp2::Session->new_client(%args);
Create a new client-side HTTP/2 session.
Arguments:
- callbacks
-
Hashref of callback handlers. Recommended:
on_header,on_data_chunk_recv,on_stream_close. - user_data
-
Optional scalar passed to callbacks.
send_connection_preface
$session->send_connection_preface(%settings);
Send HTTP/2 connection preface (SETTINGS frame). Default settings: max_concurrent_streams => 100, initial_window_size => 65535.
Additional settings:
- enable_connect_protocol
-
Set to 1 to advertise RFC 8441 extended CONNECT support (
SETTINGS_ENABLE_CONNECT_PROTOCOL). Required for WebSocket over HTTP/2.
mem_recv
my $consumed = $session->mem_recv($data);
Feed incoming data to the session. Returns number of bytes consumed. Triggers registered callbacks as frames are parsed.
mem_send
my $data = $session->mem_send();
Get outgoing data from the session. Returns bytes to send to peer (empty string if nothing pending).
submit_request
my $stream_id = $session->submit_request(%args);
Submit an HTTP/2 request (client-side). Returns the stream ID.
Arguments:
- method
-
HTTP method. Default:
'GET'. - path
-
Request path. Default:
'/'. - scheme
-
URL scheme. Default:
'https'. -
Host authority (e.g.
'example.com'). - headers
-
Arrayref of
[$name, $value]pairs for additional headers (including pseudo-headers like:protocolfor RFC 8441 extended CONNECT). - body
-
Request body. Can be:
undef(or omitted)-
No body. HEADERS frame sent with END_STREAM.
- String
-
Static body. Sent as DATA frame(s) with END_STREAM after the last frame.
- CODE ref
-
Streaming callback for bidirectional streams. The callback receives
($stream_id, $max_length)and must return one of:($data, $eof_flag)-
Send
$dataas a DATA frame. If$eof_flagis true, END_STREAM is set. undef-
Defer data production. Call
resume_stream($stream_id)when data is ready.
This is required for protocols that keep the stream open for bidirectional exchange, such as WebSocket over HTTP/2 (RFC 8441 extended CONNECT).
submit_response
$session->submit_response($stream_id, %args);
Submit an HTTP/2 response on the given stream.
Arguments:
- status
-
HTTP status code. Default:
200. - headers
-
Arrayref of
[$name, $value]pairs. - body
-
Response body. Same types as
submit_request:undef(no body), string (static body), or CODE ref (streaming callback with identical signature). - data_callback
-
Alternative to passing a CODE ref as
body. Callback with the same streaming signature. - callback_data
-
Optional user data passed as third argument to the streaming callback.
submit_push_promise
my $promised_stream_id = $session->submit_push_promise($stream_id, %args);
Submit a server push promise.
submit_data
$session->submit_data($stream_id, $data, $eof);
Push data directly onto an existing stream. The stream must already have a data provider (established by submit_request or submit_response with a CODE ref or data_callback). This replaces the streaming callback with a one-shot static body, then resumes the stream.
Arguments:
$stream_id-
The stream to send data on.
$data-
The data to send. Can be
undeffor an empty DATA frame. $eof-
If true, the DATA frame will include END_STREAM, closing the stream.
This is useful when you have data available outside the streaming callback context and want to push it directly, such as forwarding WebSocket frames received from another source.
resume_stream
$session->resume_stream($stream_id);
Resume data production for a deferred stream. Call this after a streaming body callback has returned undef and new data is available. Works for both request and response streams.
terminate_session
$session->terminate_session($error_code);
Send a GOAWAY frame and terminate the session. The $error_code should be an nghttp2 error code (0 for NGHTTP2_NO_ERROR).
submit_rst_stream
$session->submit_rst_stream($stream_id, $error_code);
Send a RST_STREAM frame to abnormally terminate a stream. The $error_code should be an HTTP/2 error code (e.g. 0 for NO_ERROR, 8 for CANCEL).
submit_ping
$session->submit_ping($ack, $opaque_data);
Send a PING frame. Set $ack to 1 for a PING ACK response, 0 for an unsolicited PING. $opaque_data must be exactly 8 bytes, or undef for default.
submit_window_update
$session->submit_window_update($stream_id, $window_size_increment);
Send a WINDOW_UPDATE frame to increase the flow control window. Use $stream_id = 0 for connection-level flow control, or a specific stream ID for stream-level.
get_stream_user_data
my $data = $session->get_stream_user_data($stream_id);
Retrieve user data associated with a stream. Returns undef if no data is set.
set_stream_user_data
$session->set_stream_user_data($stream_id, $data);
Associate arbitrary user data with a stream. Useful for storing per-stream application state.
is_stream_deferred
my $bool = $session->is_stream_deferred($stream_id);
Returns true if the stream's data provider has been deferred (i.e. the streaming callback returned undef). The stream can be resumed with resume_stream().
want_read
my $bool = $session->want_read();
Returns true if the session wants to read more data.
want_write
my $bool = $session->want_write();
Returns true if the session has data to write.
resume_data
$session->resume_data($stream_id);
Low-level resume for deferred data production. Prefer resume_stream() which also clears the internal deferred flag.
CALLBACKS
All callbacks receive positional arguments and should return 0 on success.
on_begin_headers
sub { my ($stream_id, $frame_type, $flags) = @_; return 0; }
Called when a new headers block begins (new stream or trailers).
on_header
sub { my ($stream_id, $name, $value, $flags) = @_; return 0; }
Called for each header. Pseudo-headers (:method, :path, :scheme, :authority, :status, :protocol) are delivered before regular headers.
on_frame_recv
sub { my ($frame_hashref) = @_; return 0; }
Called when a complete frame is received. The hashref contains: type, flags, stream_id, length.
on_data_chunk_recv
sub { my ($stream_id, $data, $flags) = @_; return 0; }
Called when body data is received on a stream.
on_stream_close
sub { my ($stream_id, $error_code) = @_; return 0; }
Called when a stream is closed.