NAME
Plack::Handler::H2 - High-performance HTTP/2 server handler for Plack
SYNOPSIS
Create a PSGI application file (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
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 plackup for most use cases. Direct instantiation is only recommended for advanced scenarios where plackup cannot be used.
FEATURES
Full HTTP/2 Protocol Support
Complete HTTP/2 implementation using nghttp2 with header compression (HPACK), stream multiplexing, server push capabilities, and flow control.
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.
Streaming Responses
Full support for PSGI streaming and delayed responses, including chunked transfer without Content-Length, progressive rendering, and server-sent events compatibility.
Asynchronous I/O
Event-driven architecture using libevent2 with non-blocking request handling, concurrent stream processing, and efficient memory management for large request bodies.
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.
PSGI Compliant
Full compatibility with PSGI specification and works with any PSGI-compatible framework including Dancer2, Mojolicious::Lite, and custom PSGI applications.
CONFIGURATION
When using plackup, configuration is provided via command-line options:
SSL/TLS Options
- --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.
- --ssl-key-file (optional)
-
Path to SSL private key file in PEM format. Required if
--ssl-cert-fileis provided.
Server Options
- --host (optional, default:
0.0.0.0) -
IP address to bind to.
- --port (optional, default:
5000) -
Port number to listen on.
- --timeout (optional, default:
120) -
General timeout in seconds.
- --read-timeout (optional, default:
60) -
Read timeout in seconds.
- --write-timeout (optional, default:
60) -
Write timeout in seconds.
- --request-timeout (optional, default:
30) -
Request timeout in seconds.
- --max-request-body-size (optional, default:
10485760) -
Maximum request body size in bytes (default is 10MB).
Example with Custom Configuration
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
METHODS
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.
Options:
ssl_cert_file- Path to SSL certificate filessl_key_file- Path to SSL private key filehost- IP address to bind toport- Port number to listen ontimeout- General timeout in secondsread_timeout- Read timeout in secondswrite_timeout- Write timeout in secondsrequest_timeout- Request timeout in secondsmax_request_body_size- Maximum request body size in bytes
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.
Parameters:
$app- A PSGI application code reference
STREAMING RESPONSES
Plack::Handler::H2 fully supports PSGI streaming responses using the delayed response pattern. This is useful for:
Large responses that don't fit in memory
Server-sent events
Progressive rendering
Long-polling
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 Plack::Handler::H2::Writer which provides write() and close() methods for sending data chunks.
SSL/TLS CONFIGURATION
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
Development Use
For development and testing, simply run plackup without certificate options to auto-generate self-signed certificates:
plackup -s H2 --port=8443 app.psgi
Or generate your own self-signed certificate:
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt \
-days 365 -nodes -subj "/CN=localhost"
plackup -s H2 \
--ssl-cert-file=server.crt \
--ssl-key-file=server.key \
--port=8443 \
app.psgi
Note: Browsers will display security warnings for self-signed certificates. You'll need to accept the security exception to proceed.
SYSTEM REQUIREMENTS
System Libraries
nghttp2 - HTTP/2 C library (version 1.x)
libevent2 - Event notification library (version 2.x)
OpenSSL - TLS/SSL cryptographic library (version 1.1.1 or 3.0+)
C++ Compiler - GCC 7+, Clang 5+, or equivalent with C++17 support
Installation of Dependencies
Ubuntu/Debian:
sudo apt-get install libnghttp2-dev libevent-dev libssl-dev g++ make
CentOS/RHEL:
sudo yum install nghttp2-devel libevent-devel openssl-devel gcc-c++ make
macOS:
brew install nghttp2 libevent openssl
Perl Requirements
Perl 5.024 or higher with XS support
Plack 1.0+
File::Temp 0.22+
XSLoader (core module)
PLATFORM SUPPORT
Supported operating systems:
Linux (Ubuntu, Debian, CentOS, RHEL, etc.)
macOS
FreeBSD
OpenBSD
Windows: Not currently supported due to libevent requirements.
ARCHITECTURE
The module consists of three main layers:
- 1. H2.pm - High-level Perl interface
-
PSGI handler implementation, configuration management, self-signed certificate generation, and streaming response coordination.
- 2. H2.xs - XS bindings layer
-
Efficient Perl-to-C++ interface, type conversion and marshalling, and function wrappers for core operations.
- 3. 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).
PERFORMANCE
The handler is designed for high performance:
Native C++ implementation minimizes overhead
Asynchronous I/O prevents blocking
Stream multiplexing allows concurrent request processing
Automatic buffering strategy (memory for small bodies, temp files for large)
HTTP/2 header compression reduces bandwidth
See the benchmark/ directory in the distribution for benchmarking tools to compare with other Plack handlers.
TROUBLESHOOTING
"Could not create SSL_CTX"
Verify OpenSSL is properly installed
Check that certificate and key files are readable
Ensure certificate and key match
"Could not read certificate file" / "Could not read private key file"
Verify file paths are correct and absolute
Check file permissions (should be readable by the process)
Ensure files are in PEM format
Check for proper line endings (UNIX style)
Connection refused / Connection errors
Verify the server is listening on the correct address and port
Check firewall settings
Ensure no other service is using the same port
For localhost testing, try
https://localhost:PORT(nothttp://)
Browser shows "NET::ERR_CERT_AUTHORITY_INVALID"
This is normal for self-signed certificates. Click "Advanced" and "Proceed to localhost (unsafe)" to continue. For production, use certificates from a trusted CA.
Large request bodies failing
Adjust --max-request-body-size parameter (default 10MB). The handler automatically uses temp files for bodies larger than 1MB.
EXAMPLES
The example/ directory in the distribution contains several working examples:
example.pl - Basic PSGI app with form handling
example_streamed.pl - Streaming response demonstration
example_streamed_2.pl - Delayed response pattern
example_dancer2.pl - Dancer2 framework integration
example_mojo.pl - Mojolicious::Lite integration
SEE ALSO
Plack - PSGI toolkit and server adapters
PSGI - Perl Web Server Gateway Interface specification
Plack::Handler::H2::Writer - Streaming response writer
nghttp2 - HTTP/2 C library
libevent - Event notification library
RFC 7540 - HTTP/2 specification
RFC 9113 - Updated HTTP/2 specification
VERSION
Version 0.0.1
REPOSITORY
https://github.com/rawleyfowler/perl-Plack-Handler-H2
Report bugs and issues at: https://github.com/rawleyfowler/perl-Plack-Handler-H2/issues
AUTHOR
Rawley Fowler <rawley@molluscsoftware.com>
LICENSE
This software is released under the BSD 3-Clause License. See the LICENSE file in the distribution for details.
ACKNOWLEDGMENTS
Built with:
nghttp2 for HTTP/2 protocol implementation
libevent for asynchronous I/O
OpenSSL for TLS/SSL security
Special thanks to the Plack community and all contributors.