NAME
Protocol::HTTP2::Server - HTTP/2 server
SYNOPSIS
use Protocol::HTTP2::Server;# You must create tcp server yourselfuse AnyEvent;use AnyEvent::Socket;use AnyEvent::Handle;my $w = AnyEvent->condvar;# Plain-text HTTP/2 connectiontcp_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 objectmy $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 Headersheaders => ['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',],# Contentdata => $message,);},);# First send settings to peerwhile ( 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 requestmy ( $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 IDstream_id => $stream_id,# HTTP/1.1 headersheaders => ['server' => 'perl-Protocol-HTTP2/0.01','content-length' => length($message),],# Body of responsedata => $message,);
response_stream
If body of response is not yet ready or server will stream data
# P::H::Server::Stream objectmy $server_stream;$server_stream = $server->response_stream(# HTTP/2 status':status' => 200,# Stream IDstream_id => $stream_id,# HTTP/1.1 headersheaders => ['server' => 'perl-Protocol-HTTP2/0.01',],# Callback if client abort this streamon_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 callbackon_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
# Examplewhile ( 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.