docs::a...uestRec(3)

πŸ“¦ version 2.0.13, in nixos 26.05, nixpkgs unstable

docs::a...uestRec(3) β€” User Contributed Perl Documentation, bestie. This is the page for Apache2::RequestRec, aka the Perl API for Apache request record accessors. πŸ’…

🌸 NAME 🌸

Apache2::RequestRec β€” the Perl API for Apache request record accessors, and honestly it's giving main-character energy for request handling. ✨

✨ Synopsis ✨

Okay so here's the whole vibe in code form β€” every accessor this page is about:

use Apache2::RequestRec ();

# set supported by the handler HTTP methods
$allowed = $r->allowed();

# auth type
$auth_type = $r->ap_auth_type();

# QUERY_STRING
$args = $r->args();

# non-parsed-headers handler
$status = $r->assbackwards();

# how many bytes were sent
$bytes_sent = $r->bytes_sent();

# client connection record
$c = $r->connection();

# "Content-Encoding" HTTP response header
$r->content_encoding("gzip");

# the languages of the content
$languages = $r->content_languages();

# "Content-Encoding" HTTP response header
$r->content_type('text/plain');

# special response headers table
$err_headers_out = $r->err_headers_out();

# request mapped filename
$filename = $r->filename();

# request finfo
$finfo = $r->finfo();

# 'SetHandler perl-script' equivalent
$r->handler('perl-script');

# was it a HEAD request?
$status = $r->header_only();

# request input headers table
$headers_in = $r->headers_in();

# request output headers table
$headers_out = $r->headers_out();

# hostname
$hostname = $r->hostname();

# input filters stack
$input_filters = $r->input_filters();

# get the main request obj in a sub-request
$main_r = $r->main();

# what's the current request (GET/POST/etc)?
$method = $r->method();

# what's the current method number?
$methnum = $r->method_number();

# current resource last modified time
$mtime = $r->mtime();

# next request object (in redirect)
$next_r = $r->next();

# there is no local copy
$r->no_local_copy();

# Apache ascii notes table
$notes = $r->notes();

# output filters stack
$output_filters = $r->output_filters();

# PATH_INFO
$path_info = $r->path_info();

# used in configuration directives modules
$per_dir_config = $r->per_dir_config();

# pool with life span of the current request
$p = $r->pool();

# previous request object in the internal redirect
$prev_r = $r->prev();

# connection level input filters stack
$proto_input_filters = $r->proto_input_filters();

# HTTP protocol version number
$proto_num = $r->proto_num();

# connection level output filters stack
$proto_output_filters = $r->proto_output_filters();

# the protocol, the client speaks: "HTTP/1.0", "HTTP/1.1", etc.
$protocol = $r->protocol();

# is it a proxy request
$status = $r->proxyreq($val);

# Time when the request started
$request_time = $r->request_time();

# server object
$s = $r->server();

# response status
$status = $r->status();

# response status line
$status_line = $r->status_line();

# manipulate %ENV of the subprocess
$r->subprocess_env;
$r->subprocess_env($key => $val);

# first HTTP request header
$request = $r->the_request();

# the URI without any parsing performed
$unparsed_uri = $r->unparsed_uri();

# The path portion of the URI
$uri = $r->uri();

# auth username
$user = $r->user();

πŸ’– Description πŸ’–

Apache2::RequestRec gives you the Perl API for the Apache request_rec object. It's the request-record bestie you call when you need to peek at or poke the request. 🫢

And the following packages extend the Apache2::RequestRec functionality β€” like little accessory packs for your request-record fit:

  • Apache2::Access
  • Apache2::Log
  • Apache2::RequestIO
  • Apache2::RequestUtil
  • Apache2::Response
  • Apache2::SubRequest
  • Apache2::URI

🫢 API 🫢

Apache2::RequestRec provides the following functions and/or methods. Slay. ✨

allowed

Get/set the allowed methods bitmask.

$allowed      = $r->allowed();
$prev_allowed = $r->allowed($new_allowed);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $new_allowed ( bitmask ) β€” sets the bitvector.
  • ret: $allowed ( bitmask ) β€” returns $allowed, which is a bitvector of the allowed methods. If the $new_allowed argument is passed, you get the value from before the change. πŸ’–
  • since: 2.0.00

A handler has to make sure the request method is one it can actually handle. Generally modules should Apache2::DECLINE any request methods they do not handle. And before aborting the handler like that, the handler should set $r->allowed to the list of methods it is willing to handle. This bitvector is used to construct the Allow: header required for OPTIONS requests, and Apache2::Const::HTTP_METHOD_NOT_ALLOWED (405) and Apache2::Const::HTTP_NOT_IMPLEMENTED (501) status codes.

Since the default Apache handler deals with the OPTIONS method, all response handlers can usually decline to deal with OPTIONS. For example, if the response handler handles only GET and POST methods, and not OPTIONS, it may want to say:

use Apache2::Const -compile => qw(OK DECLINED M_GET M_POST M_OPTIONS);
if ($r->method_number == Apache2::Const::M_OPTIONS) {
    $r->allowed($r->allowed | (1<<Apache2::Const::M_GET) | (1<<Apache2::Const::M_POST));
    return Apache2::Const::DECLINED;
}

TRACE is always allowed, modules don't need to set it explicitly.

Since the default_handler will always handle a GET, a module which does not implement GET should probably return Apache2::Const::HTTP_METHOD_NOT_ALLOWED. Unfortunately this means that a script GET handler can't be installed by mod_actions.

For example, if the module can handle only the POST method, it could start with:

use Apache2::Const -compile => qw(M_POST HTTP_METHOD_NOT_ALLOWED);
unless ($r->method_number == Apache2::Const::M_POST) {
    $r->allowed($r->allowed | (1<<Apache2::Const::M_POST));
    return Apache2::Const::HTTP_METHOD_NOT_ALLOWED;
}

ap_auth_type

If an authentication check was made, get or set the ap_auth_type slot in the request record. πŸ”

$auth_type = $r->ap_auth_type();
$r->ap_auth_type($newval);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $newval (string) β€” if this argument is passed, then a new auth type is assigned. For example:
$r->auth_type('Basic');
  • ret: $auth_type (string) β€” if $newval is passed, nothing is returned. Otherwise the current auth type is returned.
  • since: 2.0.00

ap_auth_type holds the authentication type that has been negotiated between the client and server during the actual request. Generally, ap_auth_type is populated automatically when you call $r->get_basic_auth_pw, so you don't really need to worry too much about it. But if you want to roll your own authentication mechanism, then you will have to populate ap_auth_type yourself.

Note that $r->ap_auth_type was $r->connection->auth_type in the mod_perl 1.0 API.

args

Get/set the request QUERY string.

$args      = $r->args();
$prev_args = $r->args($new_args);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $new_args ( string ) β€” optionally set the new QUERY string.
  • ret: $args ( string ) β€” the current QUERY string. If $new_args was passed, returns the value before the change. ✨
  • since: 2.0.00

assbackwards

When set to a true value, Apache won't send any HTTP response headers, allowing you to send any headers.

$status      = $r->assbackwards();
$prev_status = $r->assbackwards($newval);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $newval (integer) β€” assign a new state.
  • ret: $status (integer) β€” current state.
  • since: 2.0.00

If you send your own set of headers, which includes the Keep-Alive HTTP response header, you must make sure to increment the number of requests served over this connection. Normally the core connection output filter ap_http_header_filter does this, but it's skipped when assbackwards is enabled. So do this:

$r->connection->keepalives($r->connection->keepalives + 1);

Otherwise code relying on the value of $r->connection->keepalives may malfunction. For example, this counter is used to tell when a new request is coming in over the same connection to a filter that wants to parse only HTTP headers (like Apache2::Filter::HTTPHeadersFixup). Of course you will need to set $r->connection->keepalive(1) ) as well.

bytes_sent

The number of bytes sent to the client β€” handy for logging, etc. πŸ“Š

$bytes_sent = $r->bytes_sent();
  • obj: $r ( Apache2::RequestRec object )
  • ret: $bytes_sent (integer)
  • since: 2.0.00

Though as of this writing in Apache 2.0 it doesn't really do what it did in Apache 1.3. It's just set to the size of the response body. The issue is that buckets from one request may get buffered and not sent during the lifetime of the request, so it's not easy to give a truly accurate count of "bytes sent to the network for this response".

connection

Get the client connection record.

$c = $r->connection();
  • obj: $r ( Apache2::RequestRec object )
  • ret: $c ( Apache2::Connection object )
  • since: 2.0.00

content_encoding

Get/set content encoding β€” that's the Content-Encoding HTTP header. Content encodings are strings like gzip or compress.

$ce      = $r->content_encoding();
$prev_ce = $r->content_encoding($new_ce);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $new_ce ( string ) β€” if passed, sets the content encoding to a new value. It must be a lowercased string.
  • ret: $ce ( string ) β€” the current content encoding. If $new_ce is passed, then the previous value is returned.
  • since: 2.0.00

For example, here is how to send a gzip'ed response:

require Compress::Zlib;
$r->content_type("text/plain");
$r->content_encoding("gzip");
$r->print(Compress::Zlib::memGzip("some text to be gzipped));

content_languages

Get/set content languages β€” that's the Content-Language HTTP header. Content languages are strings like en or fr.

$languages = $r->content_languages();
$prev_lang = $r->content_languages($nev_lang);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $new_lang ( ARRAY ref ) β€” if passed, sets the content languages to new values. It must be an ARRAY reference of language names, like en or fr.
  • ret: $languages ( ARRAY ref ) β€” the current list of content languages, as an ARRAY reference. If $new_lang is passed, then the previous value is returned.
  • since: 2.0.00

content_type

Get/set the HTTP response Content-type header value.

my $content_type      = $r->content_type();
my $prev_content_type = $r->content_type($new_content_type);

Okay so, back to the params for this one πŸ’…

  • $r β€” an Apache2::RequestRec object, the usual main character
  • $new_content_type (optional, a MIME type string) β€” assign a brand new HTTP response content-type. Heads up though: it only actually affects the response if the HTTP headers haven't been sent yet. Once they've left the building, this does nothing πŸ’€
  • returns $content_type β€” the current content-type value. But bestie, if $new_content_type was passed, you get the previous value back instead β€” she's a swap, not a peek πŸ”
  • since: 2.0.00

Example time β€” set the Content-type header to text/plain:

$r->content_type('text/plain');
Real talk: if you set this header by going straight at the headers_out table, Apache will ignore it. So do not do that. πŸ™ˆ

err_headers_out

Get/set the MIME response headers that get printed even on errors and stick around across internal redirects.

$err_headers_out = $r->err_headers_out();
  • $r β€” Apache2::RequestRec object
  • returns $err_headers_out β€” APR::Table object
  • since: 2.0.00

The tea between headers_out and err_headers_out β˜•: the latter ones get printed even on error, and they persist across internal redirects (so the headers printed for ErrorDocument handlers will have them 🫢).

So like, if a handler wants to return a 404 but nevertheless set a cookie, it has to be:

$r->err_headers_out->add('Set-Cookie' => $cookie);
return Apache2::Const::NOT_FOUND;

But if the handler does this instead:

$r->headers_out->add('Set-Cookie' => $cookie);
return Apache2::Const::NOT_FOUND;

then the Set-Cookie header just... won't be sent. Ghosted. πŸ’€

filename

Get/set the filename on disk that corresponds to this response (aka the result of the URI β†’ filename translation).

$filename      = $r->filename();
$prev_filename = $r->filename($new_filename);
  • $r β€” Apache2::RequestRec object
  • $new_filename (optional, string) β€” new value
  • returns $filename (string) β€” the current filename, or the previous value if you passed the optional $new_filename argument
  • since: 2.0.00
⚠️ Okay important: if you change the filename after the PerlMapToStorageHandler phase has already run, and you're expecting Apache to actually serve it, you need to update its stat record too, like so:
use Apache2::RequestRec ();
use APR::Finfo ();
use APR::Const -compile => qw(FINFO_NORM);
$r->filename($newfile);
$r->finfo(APR::Finfo::stat($newfile, APR::Const::FINFO_NORM, $r->pool));

If you don't do that, Apache will still try to use the previously cached information about the previously set value of the filename. Lowkey stubborn of her, but okay. πŸ™„

finfo

Get and set the finfo request record member:

$finfo = $r->finfo();
$r->finfo($finfo);
  • $r β€” Apache2::RequestRec object
  • $finfo (optional, an APR::Finfo object)
  • returns $finfo β€” an APR::Finfo object. Always returns the current object ✨
  • since: 2.0.00

Because of the internal Apache implementation, it is literally not possible to have two different objects originating from $r->finfo at the same time. Whenever $r->finfo gets updated, all the objects get updated too, to the latest value. Shared braincell energy fr 🧠

Most of the time this method is used to get the finfo member. The only reason you'd ever want to set it is if you need to use it before Apache's default map_to_storage phase is called.

Examples:

  • What Apache thinks the current request filename is (post the PerlMapToStorageHandler phase):
use Apache2::RequestRec ();
use APR::Finfo ();
print $r->finfo->fname;
  • Populate the finfo member (normally, before the PerlMapToStorageHandler phase):
use APR::Finfo ();
use APR::Const -compile => qw(FINFO_NORM);

my $finfo = APR::Finfo::stat(__FILE__, APR::Const::FINFO_NORM, $r->pool);
$r->finfo($finfo);

handler

Get/set the equivalent of the SetHandler directive.

$handler      = $r->handler();
$prev_handler = $r->handler($new_handler);
  • $r β€” Apache2::RequestRec object
  • $new_handler (optional, string) β€” the new handler
  • returns $handler (string) β€” the current handler. If $new_handler was passed, the previous value is returned
  • since: 2.0.00

header_only

Did the client ask for headers only?? Like when the request method was HEAD:

$status = $r->header_only();
  • $r β€” Apache2::RequestRec object
  • returns $status (boolean) β€” returns true if the client is asking for headers only, false otherwise
  • since: 2.0.00

headers_in

Get/set the request MIME headers:

$headers_in = $r->headers_in();
  • $r β€” Apache2::RequestRec object
  • returns $headers_in β€” APR::Table object
  • since: 2.0.00

This table is available starting from the PerlHeaderParserHandler phase πŸŽ€

For example, you can use it to retrieve the cookie value the client sent, in the Cookie: header:

my $cookie = $r->headers_in->{Cookie} || '';

headers_out

Get/set the MIME response headers β€” these get printed only on 2xx responses πŸ’…

$headers_out = $r->headers_out();
  • $r β€” Apache2::RequestRec object
  • returns $headers_out β€” APR::Table object
  • since: 2.0.00

Also peep err_headers_out, which is the one that lets you set headers for non-2xx responses and keeps them alive across internal redirects 🫢

hostname

Host, as set by full URI or Host:

$hostname      = $r->hostname();
$prev_hostname = $r->hostname($new_hostname);
  • $r β€” Apache2::RequestRec object
  • $new_hostname (optional, string) β€” new value
  • returns $hostname (string) β€” the current hostname, or the previous value if you passed the optional $new_hostname argument
  • since: 2.0.00

input_filters

Get/set the first filter in a linked list of request-level input filters:

$input_filters      = $r->input_filters();
$prev_input_filters = $r->input_filters($new_input_filters);
  • $r β€” Apache2::RequestRec object
  • $new_input_filters (optional) β€” set a new value
  • returns $input_filters β€” an Apache2::Filter object: the first filter in the request-level input filters chain. If $new_input_filters was passed, it returns the previous value
  • since: 2.0.00

For example, instead of using $r->read() to read the POST data, you could do an explicit walk through the incoming bucket brigades to get that data. This read_post() function does exactly that (and honestly it's literally what $r->read() does behind the scenes πŸ‘€):

use APR::Brigade ();
use APR::Bucket ();
use Apache2::Filter ();

use Apache2::Const -compile => qw(MODE_READBYTES);
use APR::Const    -compile => qw(SUCCESS BLOCK_READ);

use constant IOBUFSIZE => 8192;

sub read_post {
    my $r = shift;

    my $bb = APR::Brigade->new($r->pool,
                               $r->connection->bucket_alloc);

    my $data = '';
    my $seen_eos = 0;
    do {
        $r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
                                       APR::Const::BLOCK_READ, IOBUFSIZE);

        for (my $b = $bb->first; $b; $b = $bb->next($b)) {
            if ($b->is_eos) {
                $seen_eos++;
                last;
            }

            if ($b->read(my $buf)) {
                $data .= $buf;
            }

            $b->remove; # optimization to reuse memory
        }

    } while (!$seen_eos);

    $bb->destroy;

    return $data;
}

So as you can see, $r->input_filters gives us a pointer to the last of the top of the incoming filters stack πŸ¦‹

main

Get the main request record:

$main_r = $r->main();
  • $r β€” Apache2::RequestRec object
  • returns $main_r β€” an Apache2::RequestRec object. If the current request is a sub-request, this method returns a blessed reference to the main request structure. If the current request is the main request, then this method returns undef
  • since: 2.0.00

To figure out whether you're inside a main request or a sub-request/internal redirect, use $r->is_initial_req 🧚

method

Get/set the current request method (e.g. GET, HEAD, POST, etc.):

$method     = $r->method();
$pre_method = $r->method($new_method);
  • $r β€” Apache2::RequestRec object
  • $new_method (optional, string) β€” a new value
  • returns $method (string) β€” the current method as a string. If $new_method was passed, the previous value is returned
  • since: 2.0.00

method_number

Get/set the HTTP method issued by the client (Apache2::Const::M_GET, Apache2::Const::M_POST, etc.):

$methnum      = $r->method_number();
$prev_methnum = $r->method_number($new_methnum);
  • $r β€” Apache2::RequestRec object
  • $new_methnum (optional, an Apache2::Const :methods constant) β€” a new value
  • returns $methnum (an Apache2::Const :methods constant) β€” the current method as a number. If $new_methnum was passed, the previous value is returned
  • since: 2.0.00

Peep the $r->allowed entry for examples πŸ‘‘

mtime

Last modified time of the requested resource:

$mtime      = $r->mtime();
$prev_mtime = $r->mtime($new_mtime);
  • $r β€” Apache2::RequestRec object
  • $new_mtime (optional, epoch seconds) β€” a new value
  • returns $mtime (epoch seconds) β€” the current value. If $new_mtime was passed, the previous value is returned
  • since: 2.0.00

next

Pointer to the redirected request if this is an external redirect:

$next_r = $r->next();
  • $r β€” Apache2::RequestRec object
  • returns $next_r β€” an Apache2::RequestRec object: a blessed reference to the next (internal) request structure, or undef if there is no next request
  • since: 2.0.00

no_local_copy

There is no local copy of this response:

$status = $r->no_local_copy();
  • $r β€” Apache2::RequestRec object
  • returns $status (integer)
  • since: 2.0.00

Used internally in certain sub-requests to prevent sending Apache2::Const::HTTP_NOT_MODIFIED for a fragment or error documents. For example, check the implementation in modules/filters/mod_include.c πŸ”

Also used internally in $r->meets_conditions β€” if it's set to a true value, the conditions are always met. Periodt.

notes

Get/set text notes for the duration of this request. These notes can be passed from one module to another β€” and not only mod_perl, but modules in any other language too:

$notes      = $r->notes();
$prev_notes = $r->notes($new_notes);
  • $r β€” Apache2::RequestRec object
  • $new_notes (optional, an APR::Table object)
  • returns $notes β€” an APR::Table object: the current notes table. If the $new_notes argument was passed, it returns the previous value
  • since: 2.0.00

If you wanna pass Perl structures, you can use $r->pnotes πŸ’œ

Also see $c->notes

output_filters

okay so this one hands you the first filter in a linked list of request-level output filters πŸ’…

$output_filters      = $r->output_filters();
$prev_output_filters = $r->output_filters($new_output_filters);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $new_output_filters β€” sets a new value
  • ret: $output_filters (Apache2::Filter object) β€” the first filter in the request level output filters chain. If $new_output_filters was passed, it returns the previous value instead ✨
  • since: 2.0.00

So like, instead of using $r->print() to send the response body, you could yeet the data straight into the first output filter. This little function send_response_body() does exactly that:

use APR::Brigade ();
use APR::Bucket ();
use Apache2::Filter ();

sub send_response_body {
    my ($r, $data) = @_;

    my $bb = APR::Brigade->new($r->pool,
                               $r->connection->bucket_alloc);

    my $b = APR::Bucket->new($bb->bucket_alloc, $data);
    $bb->insert_tail($b);
    $r->output_filters->fflush($bb);
    $bb->destroy;
}

And ngl, that's literally what $r->read() does behind the scenes 🫢 β€” except it also knows how to parse HTTP headers passed along with the data, and it implements buffering too, which the function above does not. so like, respect the built-in one.


path_info

get it, set it β€” it's the PATH_INFO, aka whatever's left in the path after the URI β†’ filename translation πŸ¦‹

$path_info      = $r->path_info();
$prev_path_info = $r->path_info($path_info);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $path_info (string) β€” sets a new value
  • ret: $path_info (string) β€” the current value. If the optional $path_info arg was passed, you get the previous value back instead
  • since: 2.0.00

per_dir_config

grab the dir config vector, bestie πŸŽ€

$per_dir_config = $r->per_dir_config();
  • obj: $r (Apache2::RequestRec object)
  • ret: $per_dir_config (Apache2::ConfVector object)
  • since: 2.0.00

For the in-depth lore, go read the Apache Server Configuration Customization in Perl chapter πŸ“–


pool

the pool that's associated with the request 🌸

$p = $r->pool();
  • obj: $r (Apache2::RequestRec object)
  • ret: $p (APR::Pool object)
  • since: 2.0.00

prev

pointer to the previous request β€” but only if this is an internal redirect πŸ‘€

$prev_r = $r->prev();
  • obj: $r (Apache2::RequestRec object)
  • ret: $prev_r (Apache2::RequestRec object) β€” a blessed reference to the previous (internal) request structure, or undef if there's no previous request
  • since: 2.0.00

proto_input_filters

first filter in a linked list of protocol level input filters, let's gooo πŸ”₯

$proto_input_filters      = $r->proto_input_filters();
$prev_proto_input_filters = $r->proto_input_filters($new_proto_input_filters);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $new_proto_input_filters β€” sets a new value
  • ret: $proto_input_filters (Apache2::Filter object) β€” the first filter in the protocol level input filters chain. If $new_proto_input_filters was passed, you get the previous value
  • since: 2.0.00

heads up: $r->proto_input_filters points to the same filter as $r->connection->input_filters ⭐


proto_num

the current request's HTTP protocol version number, as a lil integer πŸ’œ

$proto_num = $r->proto_num();
  • obj: $r (Apache2::RequestRec object)
  • ret: $proto_num (integer) β€” current request's HTTP protocol version number, e.g.: HTTP/1.0 == 1000, HTTP/1.1 = 1001
  • since: 2.0.00

proto_output_filters

first filter in a linked list of protocol level output filters now πŸ’«

$proto_output_filters      = $r->proto_output_filters();
$prev_proto_output_filters = $r->proto_output_filters($new_proto_output_filters);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $new_proto_output_filters β€” sets a new value
  • ret: $proto_output_filters (Apache2::Filter object) β€” the first filter in the protocol level output filters chain. If $new_proto_output_filters was passed, returns the previous value
  • since: 2.0.00

same vibe as before: $r->proto_output_filters points to the same filter as $r->connection->output_filters ✨


protocol

gets you a string identifying the protocol the client speaks πŸ—£οΈ

$protocol = $r->protocol();
  • obj: $r (Apache2::RequestRec object)
  • ret: $protocl (string) β€” typical values are HTTP/1.0 or HTTP/1.1. If the client didn't specify the protocol version, the default is HTTP/0.9

(and yes it's literally spelled $protocl in the docs β€” not me, I would never 😭)

  • since: 2.0.00

proxyreq

get/set the proxyrec request record member, and optionally adjust other related fields πŸ‘‘

$status = $r->proxyreq($val);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $val (integer) β€” PROXYREQ_NONE, PROXYREQ_PROXY, PROXYREQ_REVERSE, PROXYREQ_RESPONSE
  • ret: $status (integer) β€” if $val is defined, the proxyrec member gets set to that value and the previous value comes back to you. If $val is not passed, and $r->proxyreq is not true, and the proxy request is matching the current vhost (scheme, hostname and port), the proxyrec member will be set to PROXYREQ_PROXY and that value will be returned. In addition, $r->uri is set to $r->unparsed_uri and $r->filename is set to "modperl-proxy:".$r->uri. If those conditions aren't true, 0 is returned.
  • since: 2.0.00

so like, to turn a normal request into a proxy request handled on the same server, in the PerlTransHandler phase, run this:

my $real_url = $r->unparsed_uri;
$r->proxyreq(Apache2::Const::PROXYREQ_PROXY);
$r->uri($real_url);
$r->filename("proxy:$real_url");
$r->handler('proxy-server');
⚠️ and remember bestie β€” if you wanna flip a proxy request back into a non-proxy request, it is not enough to just call $r->proxyreq(Apache2::Const::PROXYREQ_NONE); β€” you need to adjust $r->uri and $r->filename too, if you're running that code in the PerlPostReadRequestHandler phase. Because if you don't, mod_proxy's own post_read_request handler will straight up override your settings (it runs after the mod_perl handler, sneaky 😀).

And you may also want to add

$r->set_handlers(PerlResponseHandler => []);

so that any response handlers matching apache directives don't run in addition to the mod_proxy content handler πŸ’…


request_time

time when the request started ⏰

$request_time = $r->request_time();
  • obj: $r (Apache2::RequestRec object)
  • ret: $request_time (epoch seconds).
  • since: 2.0.00

server

the Apache2::Server object for the server that the request $r is running under 🌈

$s = $r->server();
  • obj: $r (Apache2::RequestRec object)
  • ret: $s (Apache2::ServerRec object)
  • since: 2.0.00

status

get/set the reply status for the client request 😌

$status      = $r->status();
$prev_status = $r->status($new_status);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $new_status (integer) β€” if $new_status is passed, the new status is assigned. Normally you'd use some Apache2::Const constant, e.g. Apache2::Const::REDIRECT
  • ret: $newval (integer) β€” the current value. If $new_status is passed, the old value is returned
  • since: 2.0.00

Usually you set this indirectly by returning the status code as the handler's function result. But there are rare instances when you want to trick Apache into thinking the module returned an Apache2::Const::OK status code while actually sending the browser a non-OK status πŸ‘€ This comes in handy when you're implementing an HTTP proxy handler. The proxy handler needs to send the client whatever status code the proxied server returned, while returning Apache2::Const::OK to Apache. like so:

$r->status($some_code);
return Apache2::Const::OK

Also peep $r->status_line β€” if it's set, it overrides $r->status ⭐


status_line

get/set the response status line πŸŽ€ the status line is a string like 200 Document follows, and it takes precedence over the value you set with $r->status() up above.

$status_line      = $r->status_line();
$prev_status_line = $r->status_line($new_status_line);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $new_status_line (string)
  • ret: $status_line (string)
  • since: 2.0.00

When we were talking about $r->status we mentioned that sometimes a handler runs to a successful completion but may need to return a different code β€” which is exactly the proxy server case. Assuming the proxy handler forwards to the client whatever response the proxied server sent, it'll usually use status_line(), like this:

$r->status_line($response->code() . ' ' . $response->message());
return Apache2::Const::OK;

In this example $response could be, for example, an HTTP::Response object, if LWP::UserAgent was used to implement the proxy πŸ’œ

This method is also super handy when you extend the HTTP protocol and add new response codes. For example you could invent a new error code and tell Apache to use it in the response like so:

$r->status_line("499 We have been FooBared");
return Apache2::Const::OK;

Here 499 is the new response code, and We have been FooBared is the custom response message πŸ”₯


subprocess_env

get/set the Apache subprocess_env table β€” or optionally set the value of one named entry πŸ¦‹

               $r->subprocess_env;
$env_table = $r->subprocess_env;

       $r->subprocess_env($key => $val);
$val = $r->subprocess_env($key);
  • obj: $r (Apache2::RequestRec object)
  • opt arg1: $key (string)
  • opt arg2: $val (string)
  • ret: "..."
  • since: 2.0.00

When it's called in VOID context with no arguments, it populates %ENV with special variables (e.g. $ENV{QUERY_STRING}) like mod_cgi does ✨

When it's called in a non-VOID context with no arguments, it returns an APR::Table object.

When the $key argument (string) is passed, it returns the corresponding value (if such exists, or undef). These two lines are equivalent:

$val = $r->subprocess_env($key);
$val = $r->subprocess_env->get($key);

When the $key and the $val arguments (strings) are passed, the value gets set. These two lines are equivalent:

$r->subprocess_env($key => $val);
$r->subprocess_env->set($key => $val);

The subprocess_env "table" is used by Apache2::SubProcess to pass environment variables to externally spawned processes πŸ’… It's also used by various Apache modules, and you should use this table to pass the environment variables. For example if in PerlHeaderParserHandler you do:

$r->subprocess_env(MyLanguage => "de");

you can then deploy mod_include and write in .shtml document:

okay so this part opens with a little language-switcher artifact that was literally just vibing at the top β€” no cap:

          <!--#if expr="$MyLanguage = en" -->
          English
          <!--#elif expr="$MyLanguage = de" -->
          Deutsch
          <!--#else -->
          Sorry
          <!--#endif -->

✨ the_request ✨

First HTTP request header β€” that's the whole vibe, bestie.

$request = $r->the_request();
$old_request = $r->uri($new_request);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $new_request ( string )
  • ret: $request ( string )

For example:

GET /foo/bar/my_path_info?args=3 HTTP/1.0
  • since: 2.0.00

πŸ¦‹ unparsed_uri πŸ¦‹

The URI without any parsing performed β€” it's giving raw and unfiltered, fr fr.

$unparsed_uri = $r->unparsed_uri();
  • obj: $r ( Apache2::RequestRec object )
  • ret: $unparsed_uri ( string )
  • since: 2.0.00

If for example the request was:

GET /foo/bar/my_path_info?args=3 HTTP/1.0

$r->uri returns:

/foo/bar/my_path_info

whereas $r->unparsed_uri returns:

/foo/bar/my_path_info?args=3

🌸 uri 🌸

The path portion of the URI β€” just the path, periodt.

$uri         = $r->uri();
my $prec_uri = $r->uri($new_uri);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $new_uri ( string )
  • ret: $uri ( string )
  • since: 2.0.00

Peep the example in the $r->unparsed_uri section. πŸ’…

πŸ’œ user πŸ’œ

Get the user name, if an authentication process was successful. Or set it. Both? Yes bestie, same method.

$user      = $r->user();
$prev_user = $r->user($new_user);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $new_user ( string ) β€” pass $new_user to set a new value
  • ret: $user ( string ) β€” the current username if an authentication process was successful. If $new_user was passed, the previous value is returned.
  • since: 2.0.00

For example, let's print the username passed by the client:

my ($res, $sent_pw) = $r->get_basic_auth_pw;
return $res if $res != Apache2::Const::OK;
print "User: ", $r->user;

🌈 Unsupported API 🌈

Apache2::RequestRec also provides an auto-generated Perl interface for a few other methods which aren't tested at the moment and therefore their API is a subject to change. These methods will be finalized later as a need arises. If you want to rely on any of the following methods please contact the the mod_perl development mailing list so we can help each other take the steps necessary to shift the method to an officially supported API.

πŸ”₯ allowed_methods πŸ”₯

META: Autogenerated - needs to be reviewed/completed

List of allowed methods

$list = $r->allowed_methods();
  • obj: $r ( Apache2::RequestRec object )
  • ret: $list ( Apache2::MethodList object )
  • since: 2.0.00

META: Apache2::MethodList is not available at the moment

⭐ allowed_xmethods ⭐

META: Autogenerated - needs to be reviewed/completed

Array of extension methods

$array = $r->allowed_xmethods();
  • obj: $r ( Apache2::RequestRec object )
  • ret: $array ( APR::ArrayHeader object )
  • since: 2.0.00

META: APR::ArrayHeader is not available at the moment

πŸŽ€ request_config πŸŽ€

Config vector containing pointers to request's per-server config structures

$ret = $r->request_config($newval);
  • obj: $r ( Apache2::RequestRec object )
  • opt arg1: $newval ( Apache2::ConfVector object )
  • since: 2.0.00

🧚 used_path_info 🧚

META: Autogenerated - needs to be reviewed/completed

Flag for the handler to accept or reject path_info on the current request. All modules should respect the AP_REQ_ACCEPT_PATH_INFO and AP_REQ_REJECT_PATH_INFO values, while AP_REQ_DEFAULT_PATH_INFO indicates they may follow existing conventions. This is set to the user's preference upon HOOK_VERY_FIRST of the fixups.

$ret = $r->used_path_info($newval);
  • obj: $r ( Apache2::RequestRec object )
  • arg1: $newval (integer)
  • since: 2.0.00

πŸ‘€ See Also πŸ‘€

mod_perl 2.0 documentation.

mod_perl 2.0 and its core modules are copyrighted under The Apache Software License, Version 2.0.

πŸ‘‘ Authors πŸ‘‘

The mod_perl development team and numerous contributors.


mwah πŸ’‹ this page is from source/version perl v5.42.3, dated 2023-10-21 β€” docs::a...uestRec(3), iykyk πŸŽ€

πŸ“¦ where this page comes from