table of contents
Protocol::HTTP2::Server(3pm) | User Contributed Perl Documentation | Protocol::HTTP2::Server(3pm) |
NAME¶
Protocol::HTTP2::Server - HTTP/2 server
SYNOPSIS¶
use Protocol::HTTP2::Server; # You must create tcp server yourself use AnyEvent; use AnyEvent::Socket; use AnyEvent::Handle; my $w = AnyEvent->condvar; # Plain-text HTTP/2 connection tcp_server 'localhost', 8000, sub { my ( $fh, $peer_host, $peer_port ) = @_; my $handle; $handle = AnyEvent::Handle->new( fh => $fh, autocork => 1, on_error => sub { $_[0]->destroy; print "connection error\n"; }, on_eof => sub { $handle->destroy; } ); # Create Protocol::HTTP2::Server object my $server; $server = Protocol::HTTP2::Server->new( on_request => sub { my ( $stream_id, $headers, $data ) = @_; my $message = "hello, world!"; # Response to client $server->response( ':status' => 200, stream_id => $stream_id, # HTTP/1.1 Headers headers => [ 'server' => 'perl-Protocol-HTTP2/0.13', 'content-length' => length($message), 'cache-control' => 'max-age=3600', 'date' => 'Fri, 18 Apr 2014 07:27:11 GMT', 'last-modified' => 'Thu, 27 Feb 2014 10:30:37 GMT', ], # Content data => $message, ); }, ); # First send settings to peer while ( my $frame = $server->next_frame ) { $handle->push_write($frame); } # Receive clients frames # Reply to client $handle->on_read( sub { my $handle = shift; $server->feed( $handle->{rbuf} ); $handle->{rbuf} = undef; while ( my $frame = $server->next_frame ) { $handle->push_write($frame); } $handle->push_shutdown if $server->shutdown; } ); }; $w->recv;
DESCRIPTION¶
Protocol::HTTP2::Server is HTTP/2 server library. It's intended to make http2-server implementations on top of your favorite event loop.
See also Shuvgey <https://github.com/vlet/Shuvgey> - AnyEvent HTTP/2 Server for PSGI based on Protocol::HTTP2::Server.
METHODS¶
new
Initialize new server object
my $server = Protocol::HTTP2::Client->new( %options );
Available options:
- on_request => sub {...}
- Callback invoked when receiving client's requests
on_request => sub { # Stream ID, headers array reference and body of request my ( $stream_id, $headers, $data ) = @_; my $message = "hello, world!"; $server->response( ':status' => 200, stream_id => $stream_id, headers => [ 'server' => 'perl-Protocol-HTTP2/0.13', 'content-length' => length($message), ], data => $message, ); ... },
- upgrade => 0|1
- Use HTTP/1.1 Upgrade to upgrade protocol from HTTP/1.1 to HTTP/2. Upgrade
possible only on plain (non-tls) connection.
See Starting HTTP/2 for "http" URIs <https://tools.ietf.org/html/rfc7540#section-3.2>
- on_error => sub {...}
- Callback invoked on protocol errors
on_error => sub { my $error = shift; ... },
- on_change_state => sub {...}
- Callback invoked every time when http/2 streams change their state. See
Stream States <https://tools.ietf.org/html/rfc7540#section-5.1>
on_change_state => sub { my ( $stream_id, $previous_state, $current_state ) = @_; ... },
response
Prepare response
my $message = "hello, world!"; $server->response( # HTTP/2 status ':status' => 200, # Stream ID stream_id => $stream_id, # HTTP/1.1 headers headers => [ 'server' => 'perl-Protocol-HTTP2/0.01', 'content-length' => length($message), ], # Body of response data => $message, );
response_stream
If body of response is not yet ready or server will stream data
# P::H::Server::Stream object my $server_stream; $server_stream = $server->response_stream( # HTTP/2 status ':status' => 200, # Stream ID stream_id => $stream_id, # HTTP/1.1 headers headers => [ 'server' => 'perl-Protocol-HTTP2/0.01', ], # Callback if client abort this stream on_cancel => sub { ... } ); # Send partial data $server_stream->send($chunk_of_data); $server_stream->send($chunk_of_data); ## 3 ways to finish stream: # # The best: send last chunk and close stream in one action $server_stream->last($chunk_of_data); # Close the stream (will send empty frame) $server_stream->close(); # Destroy object (will send empty frame) undef $server_stream
push
Prepare Push Promise. See Server Push <https://tools.ietf.org/html/rfc7540#section-8.2>
# Example of push inside of on_request callback on_request => sub { my ( $stream_id, $headers, $data ) = @_; my %h = (@$headers); # Push promise (must be before response) if ( $h{':path'} eq '/index.html' ) { # index.html contain styles.css resource, so server can push # "/style.css" to client before it request it to increase speed # of loading of whole page $server->push( ':authority' => 'localhost:8000', ':method' => 'GET', ':path' => '/style.css', ':scheme' => 'http', stream_id => $stream_id, ); } $server->response(...); ... }
shutdown
Get connection status:
- 0 - active
- 1 - closed (you can terminate connection)
next_frame
get next frame to send over connection to client. Returns:
- undef - on error
- 0 - nothing to send
- binary string - encoded frame
# Example while ( my $frame = $server->next_frame ) { syswrite $fh, $frame; }
feed
Feed decoder with chunks of client's request
sysread $fh, $binary_data, 4096; $server->feed($binary_data);
ping
Send ping frame to client (to keep connection alive)
$server->ping
or
$server->ping($payload);
Payload can be arbitrary binary string and must contain 8 octets. If payload argument is omitted server will send random data.
2024-07-03 | perl v5.40.0 |