HTTP-Handy
view release on metacpan or search on metacpan
lib/HTTP/Handy.pm view on Meta::CPAN
The caller is responsible for encoding the JSON string.
Default status is 200.
use mb::JSON; # or any JSON encoder that works with Perl 5.5.3
return HTTP::Handy->response_json(encode_json(\%data));
=head2 C<response_redirect($location [, $code])>
Build a redirect response with a C<Location> header.
Default status is 302.
return HTTP::Handy->response_redirect('/new/path');
return HTTP::Handy->response_redirect('https://example.com/', 301);
=head1 ERROR HANDLING
=over 4
=item * If the application C<die>s, a 500 response is sent to the client
and the error message is printed to STDERR. The server continues running.
=item * An unsupported HTTP method returns a 405 response.
=item * A POST body exceeding C<max_post_size> (default 10 MB) returns a 413 response.
=item * Socket errors are printed to STDERR and the server continues
to the next request.
=back
=head1 STATIC FILES, CGI, AND HTMX
HTTP::Handy can serve static files and handle dynamic routes in the same
application, making it self-contained with no external web server needed.
my $app = sub {
my $env = shift;
my $path = $env->{PATH_INFO};
# Dynamic API route (used as HTMX target)
if ($path =~ m{^/api/}) {
my $html_fragment = compute_fragment($env);
return HTTP::Handy->response_html($html_fragment);
}
# Static files (HTML, CSS, JS)
return HTTP::Handy->serve_static($env, './htdocs');
};
When used with HTMX, the server simply returns HTML fragments for
C<hx-get> / C<hx-post> requests. No special support is required.
Reading POST body (equivalent to CGI's C<STDIN>):
my $body = '';
$env->{'psgi.input'}->read($body, $env->{CONTENT_LENGTH} || 0);
my %post = HTTP::Handy->parse_query($body);
=head1 HTTPS
HTTP::Handy does not support HTTPS. TLS requires C<IO::Socket::SSL> and
OpenSSL, which depend on Perl 5.8+ and external C libraries.
For local personal use, this is not a problem: modern browsers treat
C<127.0.0.1> and C<localhost> as secure contexts and do not show
HTTPS warnings for HTTP on these addresses.
For LAN or internet use, place a reverse proxy in front of HTTP::Handy:
Browser <--HTTPS--> Caddy / nginx / Apache <--HTTP--> HTTP::Handy
A minimal Caddy configuration:
localhost {
reverse_proxy 127.0.0.1:8080
}
=head1 PSGI COMPATIBILITY NOTES
HTTP::Handy implements a strict I<subset> of the PSGI/1.1 specification.
The following keys defined by the PSGI spec are B<not> set in C<$env>:
psgi.version (PSGI requires [1,1]; not set)
psgi.multithread (not set; effectively false)
psgi.multiprocess (not set; effectively false)
psgi.run_once (not set; effectively false)
psgi.nonblocking (not set; always blocking)
psgi.streaming (not set; not supported)
Applications that check for these keys must treat their absence as false.
For full PSGI/1.1 compliance use L<Plack> (requires Perl 5.8+).
=head1 SECURITY
HTTP::Handy is designed for B<personal use and local development only>.
It is not hardened for production or internet-facing deployment.
=over 4
=item * B<No authentication or access control.>
Any client that can reach the listening port has unrestricted access.
=item * B<No rate limiting or DoS protection.>
A slow or malicious client can occupy the single-threaded server indefinitely.
=item * B<No HTTPS.>
All traffic is transmitted in plaintext (see L</HTTPS>).
=item * B<POST body capped at 10 MB by default.>
Requests exceeding C<max_post_size> receive a 413 response, but there is no
timeout on slow uploads.
=back
Recommended practice: bind to C<127.0.0.1> (loopback only) and place a
hardened reverse proxy in front of HTTP::Handy for any LAN or internet use.
=head1 LIMITATIONS
=over 4
( run in 1.700 second using v1.01-cache-2.11-cpan-39bf76dae61 )