Plack-Handler-H2

 view release on metacpan or  search on metacpan

lib/Plack/Handler/H2.pm  view on Meta::CPAN


__END__

=head1 NAME

Plack::Handler::H2 - High-performance HTTP/2 server handler for Plack

=head1 SYNOPSIS

Create a PSGI application file (C<app.psgi>):

    my $app = sub {
        my $env = shift;
        return [
            200,
            ['Content-Type' => 'text/plain'],
            ['Hello, HTTP/2 World!']
        ];
    };

Run with plackup:

    # With custom certificates
    plackup -s H2 \
        --ssl-cert-file=/path/to/server.crt \
        --ssl-key-file=/path/to/server.key \
        --port=8443 \
        app.psgi

    # Development mode (auto-generates self-signed certificate)
    plackup -s H2 --port=8443 app.psgi

=head1 DESCRIPTION

Plack::Handler::H2 is a production-ready PSGI/Plack handler that implements 
HTTP/2 server functionality using native C++ code with Perl XS bindings. It 
leverages industry-standard libraries (nghttp2, libevent, OpenSSL) to provide 
efficient, asynchronous HTTP/2 request handling with TLS/SSL support.

This handler is designed to be used with C<plackup> for most use cases. Direct 
instantiation is only recommended for advanced scenarios where plackup cannot 
be used.

=head1 FEATURES

=over 4

=item * B<Full HTTP/2 Protocol Support>

Complete HTTP/2 implementation using nghttp2 with header compression (HPACK), 
stream multiplexing, server push capabilities, and flow control.

=item * B<TLS/SSL Required>

Secure connections with OpenSSL, including ALPN (Application-Layer Protocol 
Negotiation). Supports OpenSSL 1.1.1+ and 3.0+. Automatically generates 
self-signed certificates for development.

=item * B<Streaming Responses>

Full support for PSGI streaming and delayed responses, including chunked 
transfer without Content-Length, progressive rendering, and server-sent 
events compatibility.

=item * B<Asynchronous I/O>

Event-driven architecture using libevent2 with non-blocking request handling, 
concurrent stream processing, and efficient memory management for large request 
bodies.

=item * B<High Performance>

Native C++ implementation with minimal overhead, automatic buffering strategy 
for request bodies (memory for small, temp files for large), and HTTP/2 header 
compression.

=item * B<PSGI Compliant>

Full compatibility with PSGI specification and works with any PSGI-compatible 
framework including Dancer2, Mojolicious::Lite, and custom PSGI applications.

=back

=head1 CONFIGURATION

When using plackup, configuration is provided via command-line options:

=head2 SSL/TLS Options

=over 4

=item B<--ssl-cert-file> (optional)

Path to SSL certificate file in PEM format. If not provided, a self-signed 
certificate is automatically generated for development use.

=item B<--ssl-key-file> (optional)

Path to SSL private key file in PEM format. Required if C<--ssl-cert-file> 
is provided.

=back

=head2 Server Options

=over 4

=item B<--host> (optional, default: C<0.0.0.0>)

IP address to bind to.

=item B<--port> (optional, default: C<5000>)

Port number to listen on.

=item B<--timeout> (optional, default: C<120>)

General timeout in seconds.

=item B<--read-timeout> (optional, default: C<60>)

lib/Plack/Handler/H2.pm  view on Meta::CPAN


    plackup -s H2 \
        --host=127.0.0.1 \
        --port=8443 \
        --ssl-cert-file=server.crt \
        --ssl-key-file=server.key \
        --max-request-body-size=20971520 \
        app.psgi

=head1 METHODS

=head2 new

    my $handler = Plack::Handler::H2->new(%options);

Creates a new handler instance. This is typically called by plackup and 
rarely needs to be called directly.

B<Options:>

=over 4

=item * C<ssl_cert_file> - Path to SSL certificate file

=item * C<ssl_key_file> - Path to SSL private key file

=item * C<host> - IP address to bind to

=item * C<port> - Port number to listen on

=item * C<timeout> - General timeout in seconds

=item * C<read_timeout> - Read timeout in seconds

=item * C<write_timeout> - Write timeout in seconds

=item * C<request_timeout> - Request timeout in seconds

=item * C<max_request_body_size> - Maximum request body size in bytes

=back

=head2 run

    $handler->run($app);

Runs the PSGI application with the configured options. This method starts 
the HTTP/2 server and enters the event loop. It will not return until the 
server is shut down.

B<Parameters:>

=over 4

=item * C<$app> - A PSGI application code reference

=back

=head1 STREAMING RESPONSES

Plack::Handler::H2 fully supports PSGI streaming responses using the delayed 
response pattern. This is useful for:

=over 4

=item * Large responses that don't fit in memory

=item * Server-sent events

=item * Progressive rendering

=item * Long-polling

=back

=head2 Streaming Example

    my $app = sub {
        my $env = shift;
        
        return sub {
            my $responder = shift;
            
            # Send headers and get writer
            my $writer = $responder->([
                200,
                ['Content-Type' => 'text/html']
            ]);
            
            # Stream data in chunks
            $writer->write("<html><body>");
            $writer->write("<h1>Streaming Response</h1>");
            sleep 1;  # Simulate processing
            $writer->write("<p>This data arrives progressively.</p>");
            $writer->write("</body></html>");
            
            # Close the stream
            $writer->close();
        };
    };

The writer object is an instance of L<Plack::Handler::H2::Writer> which 
provides C<write()> and C<close()> methods for sending data chunks.

=head1 SSL/TLS CONFIGURATION

=head2 Production Use

For production, obtain valid certificates from a trusted Certificate Authority:

    # Using Let's Encrypt (example)
    certbot certonly --standalone -d yourdomain.com

Then run with plackup:

    plackup -s H2 \
        --ssl-cert-file=/etc/letsencrypt/live/yourdomain.com/fullchain.pem \
        --ssl-key-file=/etc/letsencrypt/live/yourdomain.com/privkey.pem \
        --port=443 \
        --host=0.0.0.0 \
        app.psgi

lib/Plack/Handler/H2.pm  view on Meta::CPAN


=item * B<C++ Compiler> - GCC 7+, Clang 5+, or equivalent with C++17 support

=back

=head2 Installation of Dependencies

B<Ubuntu/Debian:>

    sudo apt-get install libnghttp2-dev libevent-dev libssl-dev g++ make

B<CentOS/RHEL:>

    sudo yum install nghttp2-devel libevent-devel openssl-devel gcc-c++ make

B<macOS:>

    brew install nghttp2 libevent openssl

=head2 Perl Requirements

=over 4

=item * Perl 5.024 or higher with XS support

=item * Plack 1.0+

=item * File::Temp 0.22+

=item * XSLoader (core module)

=back

=head1 PLATFORM SUPPORT

Supported operating systems:

=over 4

=item * Linux (Ubuntu, Debian, CentOS, RHEL, etc.)

=item * macOS

=item * FreeBSD

=item * OpenBSD

=back

B<Windows:> Not currently supported due to libevent requirements.

=head1 ARCHITECTURE

The module consists of three main layers:

=over 4

=item 1. B<H2.pm> - High-level Perl interface

PSGI handler implementation, configuration management, self-signed certificate 
generation, and streaming response coordination.

=item 2. B<H2.xs> - XS bindings layer

Efficient Perl-to-C++ interface, type conversion and marshalling, and function 
wrappers for core operations.

=item 3. B<plack_handler_h2.cc/h> - Core C++ implementation

nghttp2 integration for HTTP/2 protocol, libevent event loop for async I/O, 
OpenSSL for TLS/SSL and ALPN, request/response handling, stream multiplexing, 
and memory-efficient body handling (auto-switches to temp files for large bodies).

=back

=head1 PERFORMANCE

The handler is designed for high performance:

=over 4

=item * Native C++ implementation minimizes overhead

=item * Asynchronous I/O prevents blocking

=item * Stream multiplexing allows concurrent request processing

=item * Automatic buffering strategy (memory for small bodies, temp files for large)

=item * HTTP/2 header compression reduces bandwidth

=back

See the C<benchmark/> directory in the distribution for benchmarking tools to 
compare with other Plack handlers.

=head1 TROUBLESHOOTING

=head2 "Could not create SSL_CTX"

=over 4

=item * Verify OpenSSL is properly installed

=item * Check that certificate and key files are readable

=item * Ensure certificate and key match

=back

=head2 "Could not read certificate file" / "Could not read private key file"

=over 4

=item * Verify file paths are correct and absolute

=item * Check file permissions (should be readable by the process)

=item * Ensure files are in PEM format

=item * Check for proper line endings (UNIX style)



( run in 1.430 second using v1.01-cache-2.11-cpan-0b5f733616e )