NAME
Uniform::HTTP - Framework-neutral HTTP messages and authentication
SYNOPSIS
use Uniform::HTTP::Request;
use Uniform::HTTP::Response;
my $request = Uniform::HTTP::Request->new(
method => 'GET',
target => '/users?id=42',
scheme => 'https',
authority => 'example.com',
);
my $response = Uniform::HTTP::Response->new(
status => 200,
body => "hello\n",
);
DESCRIPTION
Uniform::HTTP provides small HTTP message objects that are not tied to one client, server, framework, transport, or event loop.
It gives HTTP implementations a common way to represent requests, responses, headers, trailers, buffered bodies, and authentication data across HTTP/1, HTTP/2, and HTTP/3.
Uniform::HTTP does not open sockets, parse network traffic, serialize HTTP, or send requests. The surrounding HTTP implementation still owns those jobs.
Uniform::HTTP is pure Perl and requires Perl 5.16 or newer. No C compiler is needed to install it. XS-based engines may use its optional native header; ordinary applications use the Perl API.
START HERE
Most application code uses Uniform::HTTP::Request and Uniform::HTTP::Response.
A request needs a method and target:
my $request = Uniform::HTTP::Request->new(
method => 'GET',
target => '/items',
);
A response needs a status:
my $response = Uniform::HTTP::Response->new(
status => 200,
body => 'ok',
);
Headers are stored as ordered name/value pairs so duplicate fields are not lost:
my $response = Uniform::HTTP::Response->new(
status => 200,
headers => [
[ 'Set-Cookie', 'a=1' ],
[ 'Set-Cookie', 'b=2' ],
],
);
my $values = $response->header_values('Set-Cookie');
body() only returns a body that is already buffered. It never consumes a stream or performs I/O.
TRAILERS AND INCREMENTAL MESSAGES
Trailers are separate from initial headers, with the same ordered field API:
$response->add_trailer('Content-Digest', $digest_field_value);
my $digest = $response->trailer('Content-Digest');
For a message following external receipt:
$response->mark_incomplete->freeze_initial;
# Body receipt and trailer delivery happen in the HTTP implementation.
$response->add_trailer('Content-Digest', $digest_field_value);
$response->mark_complete->freeze;
freeze_initial() fixes headers and metadata while body and trailers can still be supplied. freeze() fixes all data. Completeness is independent. See Uniform::HTTP::Message for section capabilities and adapter limitations.
EXTENDED CONNECT
Uniform::HTTP::Request accepts an optional protocol token:
my $request = Uniform::HTTP::Request->new(
method => 'CONNECT', protocol => 'websocket',
scheme => 'https', authority => 'example.com', target => '/chat',
);
Ordinary CONNECT omits protocol and uses its authority-form target. Uniform preserves this metadata; the surrounding HTTP implementation handles negotiation and tunnel behavior. An unset version permits a neutral message without requiring the sender to modify the object.
AUTHENTICATION
Uniform::HTTP::Auth prepares Basic, Bearer, and Digest authentication field values.
use Uniform::HTTP::Auth;
my $auth = Uniform::HTTP::Auth->new(
origin => 'https://example.com:443',
credentials => {
username => 'user',
password => 'secret',
},
);
Authentication calculation is separate from sending or retrying a request.
MODULES
-
Shared request/response behavior.
-
HTTP request data.
-
HTTP response data.
-
Optional versioned bulk access for native-backed HTTP engines. Normal application code does not need it.
-
HTTP Basic, Bearer, and Digest authentication.
SCOPE
Uniform::HTTP represents HTTP semantics. It deliberately does not own:
sockets, TLS, or connections
HTTP parsing or serialization
HTTP/1 framing or HTTP/2 and HTTP/3 streams
event loops
streaming I/O
retries, redirects, or framework lifecycle
This narrow boundary is what allows the same contract to be used by unrelated HTTP implementations.
Library authors implementing adapters should see docs/MESSAGE-SPEC.md and docs/ADAPTERS.md in the distribution.
VERSION
Version 0.06.
AUTHOR
Joshua S. Day <HAX@cpan.org>
LICENSE
This software is available under the MIT License.