Provided by: libprotocol-http2-perl_1.08-1_all bug

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 = Procotol::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' => 'locahost: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.