Request(3pm)

🌸 APR::Request β€” wrapper for libapreq2's module/handle API 🌸

okay bestie, sit down, hydrate, and let me tell you about Request(3pm) β€” this is the APR::Request Perl module, and yes she's from the User Contributed Perl Documentation corner of the manual, and yes she's iconic. πŸ’… This is a whole wrapper for libapreq2's module/handle API, so buckle up. This page is long so it comes in parts β€” this is part 1, more follows. 🫢


✨ NAME ✨

APR::Request β€” wrapper for libapreq2's module/handle API.


🌈 SYNOPSIS 🌈

like literally just look at her go:

use APR::Request;

$req = APR::Request::Custom->handle($pool,
                                    "foo=arg1&bar=arg2",
                                    "apache=quux",
                                     $parser, 1e6, $bb);
$param = $req->param("foo");
$cookie = $req->jar("apache");

that's the whole vibe. 🀩


πŸŽ€ DESCRIPTION πŸŽ€

The APR::Request module gives you the base methods for interfacing with libapreq2's module API. She also brings a few utility functions and constants to the party, because she's generous like that. πŸ‘‘

This manpage documents version 2.17 of the APR::Request, APR::Request::Custom, APR::Request::Cookie::Table, and APR::Request::Param::Table packages. no cap, write that number down. πŸ“


πŸ’– METHODS πŸ’–

πŸ¦‹ APR::Request::Custom β€” derived from APR::Request πŸ¦‹

handle ✨

APR::Request::Custom->handle($pool,
                             $query_string,
                             $cookie_header,
                             $parser,
                             $read_limit,
                             $brigade)

Creates a brand new APR::Request::Custom object, she's fresh out the box. πŸ’« The $query_string and $cookie_headers get parsed immediately into the args and jar tables β€” no waiting around, no small talk. The $parser is an APR::Request::Parser object, and she gets invoked whenever you go fetch body entries from the $brigade. And the $read_limit? That's the maximum number of bytes this handle is allowed to feed into the parser. Respect the limit bestie, it's there for a reason. 🚧


🌸 METHODS 🌸

πŸ’œ APR::Request πŸ’œ

pool 🏊

$req->pool()

Returns the APR::Pool object associated to this handle. that's her home base. 🫧

bucket_alloc πŸͺ£

$req->bucket_alloc()

Returns the APR::BucketAlloc object associated to this handle. buckets. allocation. you know the drill. ✨

jar_status πŸͺ

$req->jar_status()

Returns the final status code of the handle's cookie header parser. it's giving receipts for the cookie situation. πŸ“

args_status πŸ“₯

$req->args_status()

Returns the final status code of the handle's query-string parser. πŸ“©

body_status πŸ«€

$req->body_status()

Returns the final status code of the handle's body parser. the body, obviously. πŸ’€

param_status 🧠

$req->param_status()

In list context she returns ($req->args_status, $req->body_status) β€” a little duo 🫢. Otherwise (scalar context) she returns $req->args_status || $req->body_status. pick your fighter. βš”οΈ

parse πŸ”

$req->parse()

Parses the jar, args, and body tables. Returns $req->jar_status, $req->args_status, $req->body_status.

and here's the proof, test vibes included:

@status = $req->parse;
ok @status == 3;
ok $status[0] == $req->jar_status;
ok $status[1] == $req->args_status;
ok $status[2] == $req->body_status;

three statuses, three checks, slay. βœ…βœ…βœ…

jar πŸͺπŸ’…

$req->jar()
$req->jar($key)

With no arguments, this method returns a tied APR::Request::Cookie::Table object (or undef if the Cookie header is absent, rip 😭) in scalar context β€” or, in list context, the names (in order, with repetitions, because she does not dedupe) of all the parsed cookies. πŸͺ

With the $key argument: in scalar context she fetches the first matching cookie. In list context she returns all matching cookies. The returned cookies are the values as they appeared in the incoming Cookie header β€” no glow-up, no edits. ✨

jar() will throw an APR::Request::Error object whenever jar_status() is non-zero and the return value is potentially invalid (eg scalar $req->jar($key) will not die if the desired cookie was successfully parsed). so like, she's dramatic but only when it's warranted. 🎭
$jar = $req->jar;
@cookie_names = $req->jar;
ok $jar->isa("APR::Request::Cookie::Table");
ok shift @cookie_names eq $_ for keys %$jar;

$cookie = $req->jar("apache");
@cookies = $req->jar("apache");

args πŸ“₯🌸

$req->args()
$req->args($key)

With no arguments, this method returns a tied APR::Request::Param::Table object (or undef if the query string is absent) in scalar context β€” or the names (in order, with repetitions) of all the parsed query-string arguments. πŸ“

With the $key argument: in scalar context she fetches the first matching query-string arg. In list context she returns all matching args.

args() will throw an APR::Request::Error object whenever args_status() is non-zero and the return value is potentially invalid (eg scalar $req->args($key) will not die if the desired query argument was successfully parsed). 🚨
$args = $req->args;
@arg_names = $req->args;
ok $args->isa("APR::Request::Param::Table");
ok shift @arg_names eq $_ for keys %$args;

$foo = $req->args("foo");
@bar = $req->args("bar");

body πŸ«€βœ¨

$req->body()
$req->body($key)

With no arguments, this method returns a tied APR::Request::Param::Table object (or undef if the request body is absent) in scalar context β€” or the names (in order, with repetitions) of all the parsed cookies. yes, the original really says "cookies" here, we report, we don't editorialize. πŸ’€πŸͺ

With the $key argument: in scalar context she fetches the first matching body param. In list context she returns all matching body params.

body() will throw an APR::Request::Error object whenever body_status() is non-zero and the return value is potentially invalid (eg scalar $req->body($key) will not die if the desired body param was successfully parsed). ⚠️
$body = $req->body;
@body_names = $req->body;
ok $body->isa("APR::Request::Param::Table");
ok shift @body_names eq $_ for keys %$body;

$alpha = $req->body("alpha");
@beta = $req->body("beta");

param πŸ‘‘πŸ§ 

$req->param()
$req->param($key)

With no arguments, this method returns a tied APR::Request::Param::Table object (or undef, if the query string and request body are both absent) in scalar context β€” or the names (in order, with repetitions) of all the incoming (args + body) params. main character energy, she combines both worlds. 🌈

With the $key argument: in scalar context she fetches the first matching param. In list context she returns all matching params.

param() will throw an APR::Request::Error object whenever param_status() is non-zero and the return value is potentially invalid (eg scalar $req->param($key) will not die if the desired param was successfully parsed). πŸ”₯
$param = $req->param;
@param_names = $req->param;
ok $param->isa("APR::Request::Param::Table");
ok shift @param_names eq $_ for keys %$param;

$foo = $req->param("foo");
@foo = $req->param("foo");

upload πŸ“€πŸ¦‹

$req->upload()
$req->upload($key)

With no arguments, this method returns a tied APR::Request::Param::Table object (or undef if the request body is absent) in scalar context (whose entries are APR::Request::Param objects) β€” or the names (in order, with repetitions) of all the incoming uploads. πŸ“Ž

With the $key argument: in scalar context she fetches the first matching upload. In list context she returns all matching uploads. The return values are APR::Request::Param objects. πŸ’«

upload() will throw an APR::Request::Error object whenever body_status() is non-zero. no exceptions, literally. 😀
$uploads = $req->upload;
@upload_names = $req->upload;
ok $uploads->isa("APR::Request::Param::Table");
ok shift @upload_names eq $_ for keys %$uploads;
ok $_->upload for values %$uploads;

$up = $req->upload("beta");
@ups = $req->upload("beta");
ok $_->isa("APR::Request::Param") for $up, @ups;
ok $_->upload for $up, @ups;

read_limit πŸ“

$req->read_limit()
$req->read_limit($set)

Get/set the read limit, which controls the total amount of bytes that can be fed to the current parser. she's counting every single one. πŸ”’

brigade_limit 🚧

$req->brigade_limit()
$req->brigade_limit($set)

Get/set the brigade_limit for the current parser. This limit determines how many bytes of a file upload the parser may spool into main memory. Uploads that exceed this limit get written directly to disk instead. the vibes simply cannot stay in RAM bestie. πŸ’Ύ

temp_dir πŸ—‚οΈ

$req->temp_dir()
$req->temp_dir($set)

Get/set the spool directory for uploads which exceed the configured brigade_limit. That's where the too-big-to-hold uploads go to chill. 🧊

disable_uploads 🚫

$req->disable_uploads()

Engage the disable_uploads hook for this request. that's it, that's the whole move. πŸ™ˆ

upload_hook πŸͺ

$req->upload_hook($callback)

Add an upload hook callback for this request. The arguments passed to the $callback sub are ($upload, $new_data). two args, no more, no less. ✌️

import πŸ“¦

Exports a list of subs into the caller's package. spreading the love. 🫢


⭐ SUBROUTINES ⭐

🧚 APR::Request 🧚

encode πŸ”

encode($string)

Exportable sub which returns the url-encoded form of $string. ✨

decode πŸ”“

decode($string)

Exportable sub which returns the url-decoded form of $string. ✨


πŸ’€ SUBCLASSING πŸ’€

🐣 APR::Request 🐣

If the instances of your subclass are hash references then you can actually inherit from APR::Request β€” as long as the APR::Request object is stored in an attribute called r or _r. (The APR::Request class effectively does the delegation for you automagically, as long as it knows where to find the APR::Request object to delegate to.) it's giving "just tell me where she lives and I'll handle the rest." 🏠

For example:

package MySubClass;
use APR::Request::Custom;
our @ISA = qw(APR::Request);
sub new {
    my($class, @args) = @_;
    return bless { r => APR::Request::Custom->handle(@args) }, $class;
}

πŸ“ METHODS πŸ“

Tables in this class normally arise from calls to APR::Request::jar(). πŸͺ so if you see one of these, you know exactly who sent her.

$table->cookie_class()
$table->cookie_class($set)

Get/set the class each table element is blessed into during a get or FETCH call. If defined, the class must be derived from APR::Request::Cookie β€” no outsiders allowed. 🚫 When called with $set, it returns the $table. Otherwise it returns the name of the current class, or undef if no cookie class is defined. πŸ€·β€β™€οΈ

get πŸ“₯

$table->get($key)

Same as FETCH. that's the whole description, she's a shortcut and she owns it. πŸ’…

FETCH πŸ”Ž

$table->FETCH($key)

In scalar context, this returns the first value matching $key (note: see NEXTKEY for additional notes πŸ‘€). The match is always case-insensitive. In list context, this returns all matching values. Note: the type of the return values depends on the table's current cookie_class. 🎭

EXISTS ❓

Synonym for defined; these tables are not allowed to contain undefined values. And since these are constant tables, they don't autovivify either β€” nothing spawns out of nowhere here. 🚫✨

FIRSTKEY πŸ₯‡

$table->FIRSTKEY()

Returns the first key in the table. 🏁

NEXTKEY ➑️

$table->NEXTKEY()

Returns the next key in the table. For perl 5.8+, if the key is multivalued, a subsequent FETCH on this key will return the corresponding value β€” until either NEXTKEY or FIRSTKEY is invoked again. For perl 5.6, FETCH always returns the first value. ok so your perl version genuinely changes the vibe here, respect it. 🧐

do πŸŒ€

$table->do($callback, @keys)

Same as APR::Table::do; iterates over the table calling $callback->($key, $value) for each matching @keys. If @keys is empty, this iterates over the entire table. 🌈

Note: The type of $value inserted into the callback depends on the table's current cookie_class. πŸͺ

bestie this page is long long, so ✨ more parts follow ✨ β€” don't go anywhere, the rest of her is coming πŸ’–

🌸 APR::Request::Param::Table 🌸

okay so this is the table object you get for your params, and here's everything it can do πŸ’…


πŸ’– param_class πŸ’–

$table->param_class()
$table->param_class($set)

This is the getter/setter for the class that every element in this table gets blessed into whenever there's a "get" or "FETCH" call. If you're setting one, lowkey it has to be derived from APR::Request::Param β€” no exceptions bestie, the vibes must be correct.

When you call it with $set, it hands you back the $table (so yes, chaining, slay). Otherwise it gives you the name of the current class, or undef if literally no param class has been defined yet. πŸ™ˆ

✨ get ✨

$table->get($key)

It's giving… exactly the same thing as FETCH. Same method, different name, iconic behaviour. 🫢

πŸ”₯ FETCH πŸ”₯

$table->FETCH($key)

In scalar context this returns the first value matching $key (peep NEXTKEY for the extra tea on that). The match is always case-insensitive, no cap. In list context, you get all the matching values at once. πŸ’€

Note: the type of those return values depends on the table's current param_class. So check that before you get surprised.

πŸ¦‹ EXISTS πŸ¦‹

Basically a synonym for "defined". These tables are simply not allowed to hold undefined values β€” it's not that kind of party. And since they're constant tables, they don't autovivify either. Nothing spawns out of nowhere here, periodt.

πŸŽ€ NEXTKEY πŸŽ€

$table->NEXTKEY()

Returns the next key in the table.

For perl 5.8+, if that key is multivalued, a subsequent FETCH on this same key will give you the corresponding value, and it keeps doing that until either NEXTKEY or FIRSTKEY gets invoked again. For perl 5.6, FETCH always returns the first value. Yes, this is a whole era thing. 😭

πŸ’œ FIRSTKEY πŸ’œ

$table->FIRSTKEY()

Returns the first key in the table. That's it, that's the whole method. Simple, elegant, main character energy. πŸ‘‘

πŸ“ do πŸ“

$table->do($callback, @keys)

Same as APR::Table::do β€” it iterates over the table and calls $callback->($key, $value) for each matching @keys. If @keys is empty, it just runs over the entire table. Go off. 🌈

Note: the type of $value that gets inserted into the callback depends on the table's current value_class. Keep that in mind, bestie.

🌟 SEE ALSO 🌟

Go read these next, they're all part of the same friend group 🫢

  • APR::Request::Error
  • APR::Request::Param
  • APR::Request::Cookie
  • APR::Request::Parser

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

and that's the whole page bestie!! πŸ’– this one's from perl v5.42.3, dated 2026-08-21, and it's the Request(3pm) page β€” go forth and parse some params, you absolute icon πŸŽ€βœ¨

πŸ“¦ where this page comes from