NAME

PAGI::Server::Protocol::HTTP1 - HTTP/1.1 protocol handler

SYNOPSIS

use PAGI::Server::Protocol::HTTP1;

my $proto = PAGI::Server::Protocol::HTTP1->new;

# Parse incoming request
my ($request, $consumed) = $proto->parse_request($buffer);

# Serialize response
my $bytes = $proto->serialize_response_start(200, \@headers, $chunked);
$bytes   .= $proto->serialize_response_body($chunk, $more);

DESCRIPTION

PAGI::Server::Protocol::HTTP1 isolates HTTP/1.1 wire-format parsing and serialization from PAGI event handling. This allows clean separation of protocol handling and future addition of HTTP/2 or HTTP/3 modules with the same interface.

METHODS

new

my $proto = PAGI::Server::Protocol::HTTP1->new(%options);

Creates a new HTTP1 protocol handler. Accepts the following options, which bound resource use while parsing untrusted input:

  • max_header_size - maximum size in bytes of the combined header block. Default: 8192 (8KB). Exceeding it yields a 431 error result.

  • max_request_line_size - maximum size in bytes of the request line. Default: 8192 (8KB). Exceeding it yields a 414 error result.

  • max_header_count - maximum number of header fields. Default: 100. Exceeding it yields a 431 error result.

  • max_chunk_size - maximum size in bytes of a single chunk in a chunked request body. Default: 10_485_760 (10MB).

parse_request

my ($request_info, $bytes_consumed) = $proto->parse_request($buffer);

Parses an HTTP request from the buffer. The first return value is one of three things:

  • undef when the request is incomplete (more bytes needed). The second value is 0.

  • an error descriptor when the request is malformed or exceeds a limit:

    { error => 400, message => 'Bad Request' }

    The error key is the HTTP status code to send (400, 413, 414, 431, or 501); message is a short reason. The second return value is the number of bytes to discard.

  • a request hash on success:

    $request_info = {
        method          => 'GET',
        path            => '/foo',
        raw_path        => '/foo%20bar',
        query_string    => 'a=1',
        http_version    => '1.1',
        headers         => [ ['host', 'localhost'], ... ],
        content_length  => 0,     # or undef if no Content-Length header
        chunked         => 0,     # 1 if Transfer-Encoding: chunked
        expect_continue => 0,     # 1 if the request sent Expect: 100-continue
    };

serialize_response_start

my $bytes = $proto->serialize_response_start($status, \@headers, $chunked, $http_version);

Serializes the status line and headers. $chunked (default 0) adds a Transfer-Encoding: chunked header, but only when $http_version (default '1.1') is '1.1' — chunked encoding is not emitted for HTTP/1.0 responses. A default Server header is added when the application does not provide one.

serialize_response_body

my $bytes = $proto->serialize_response_body($chunk, $more, $chunked);

Serializes a body chunk. Uses chunked encoding if $chunked is true.

serialize_chunk_end

my $bytes = $proto->serialize_chunk_end;

Returns the terminating zero-length chunk ("0\r\n\r\n") that ends a chunked response body.

serialize_continue

my $bytes = $proto->serialize_continue;

Returns a HTTP/1.1 100 Continue interim response, sent in reply to a request that carried Expect: 100-continue.

serialize_trailers

my $bytes = $proto->serialize_trailers(\@headers);

Serializes HTTP trailers.

format_date

my $date = $proto->format_date;

Returns the current time formatted as an RFC 7231 IMF-fixdate string suitable for a Date header (e.g. "Sun, 06 Nov 1994 08:49:37 GMT"). The value is cached and regenerated at most once per second.

parse_chunked_body

my ($data, $bytes_consumed, $complete) = $proto->parse_chunked_body($buffer);

Parses chunked Transfer-Encoding body from the buffer. Returns: - $data: decoded body data (may be empty string) - $bytes_consumed: number of bytes consumed from buffer - $complete: 1 if final chunk (0-length) was seen, 0 otherwise

Returns (undef, 0, 0) if more data is needed.

SEE ALSO

PAGI::Server::Connection, HTTP::Parser::XS

AUTHOR

John Napiorkowski <jjnapiork@cpan.org>

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.