libapa...Request(3pm)

πŸ’– NAME πŸ’–

Apache2::SubRequest β€” the Perl API for Apache subrequests, bestie. It's giving "make a whole other request happen behind the scenes" energy πŸ¦‹


✨ Synopsis ✨

use Apache2::SubRequest ();

# run internal redirects at once
$r->internal_redirect($new_uri);
$r->internal_redirect_handler($new_uri);

# create internal redirect objects
$subr = $r->lookup_uri("/foo");
$subr = $r->lookup_method_uri("GET", "/tmp/bar")
$subr = $r->lookup_file("/tmp/bar");
# optionally manipulate the output through main request filters
$subr = $r->lookup_uri("/foo", $r->output_filters);
# now run them
my $rc = $subr->run;

okay so this is the whole vibe in one code block, no cap 🌈


🌸 Description 🌸

Apache2::SubRequest contains the API for creating and running Apache sub-requests. Like, it literally does the extra request for you πŸ’…

Also important: Apache2::SubRequest is a sub-class of Apache2::RequestRec object. So it inherits the whole family tree, iykyk πŸ‘‘


πŸŽ€ API πŸŽ€

Apache2::SubRequest provides the following functions and/or methods, and yes we're going through every one of them:

🫢 DESTROY

Free the memory associated with a sub request. Say bye bestie πŸ‘‹

undef $subr; # but normally don't do that
  • obj: $subr ( Apache2::SubRequest object ) β€” the sub request to finish πŸ’€
  • ret: no return value
  • since: 2.0.00

DESTROY is called automatically when $subr goes out of scope. So like, it handles itself, main character behavior fr fr ✨

But! If you want to free the memory earlier than that (say you're running several subrequests and being extra), you can undef the object like:

undef $subr;
⚠️ but never call DESTROY explicitly β€” that results in ap_destroy_sub_req being called more than once, which gives you multiple brain injuries and certain hair loss πŸ˜­πŸ’€ not the hair. do NOT test this.

πŸ¦‹ internal_redirect

Redirect the current request to some other uri internally. Sneaky. Iconic. 🐍

$r->internal_redirect($new_uri);
  • obj: $r ( Apache2::RequestRec object ) β€” the current request
  • arg1: $new_uri ( string ) β€” the URI to replace the current request with
  • ret: no return value
  • since: 2.0.00

So like, if you want some other request to be served as the top-level request instead of what the client requested directly β€” call this method from a handler and then immediately return Apache2::Const::OK. The client will be completely unaware that a different request was served to her behind the scenes. Lowkey gaslighting the browser but make it legal πŸ’…βœ¨

🌈 internal_redirect_handler

Identical to internal_redirect, plus it automatically sets $r->content_type of the sub-request to be the same as of the main request, if $r->handler is true. Same energy, extra steps πŸŽ€

$r->internal_redirect_handler($new_uri);
  • obj: $r ( Apache2::RequestRec object ) β€” the current request
  • arg1: $new_uri ( string ) β€” the URI to replace the current request with.
  • ret: no return value
  • since: 2.0.00

This function is designed for things like actions or CGI scripts, when you're using AddHandler, and you want to preserve the content type across an internal redirect. So like, content_type stays slaying through the whole redirect 😌

πŸ’œ lookup_file

Create a subrequest for the given file. This sub request can be inspected to find information about the requested file. It's giving detective energy πŸ”

$ret = $r->lookup_file($new_file);
$ret = $r->lookup_file($new_file, $next_filter);
  • obj: $r ( Apache2::RequestRec object ) β€” the current request
  • arg1: $new_file ( string ) β€” the file to lookup
  • opt arg2: $next_filter ( Apache2::Filter ) β€” see $r->lookup_uri for details, bestie, it's all over there
  • ret: $ret ( Apache2::SubRequest object ) β€” the sub request record.
  • since: 2.0.00

See $r->lookup_uri for further discussion. (fr, go read it πŸ‘€)

⭐ lookup_method_uri

Create a sub request for the given URI using a specific method. This sub request can be inspected to find information about the requested URI. Method? Specified. Vibe? Immaculate πŸŽ€

$ret = $r->lookup_method_uri($method, $new_uri);
$ret = $r->lookup_method_uri($method, $new_uri, $next_filter);
  • obj: $r ( Apache2::RequestRec object ) β€” the current request
  • arg1: $method ( string ) β€” the method to use in the new sub request (e.g. GET)
  • arg2: $new_uri ( string ) β€” the URI to lookup
  • opt arg3: $next_filter ( Apache2::Filter object ) β€” see $r->lookup_uri for details
  • ret: $ret ( Apache2::SubRequest object ) β€” the sub request record.
  • since: 2.0.00

See $r->lookup_uri for further discussion. (again, yes, go look πŸ’…)

πŸ‘‘ lookup_uri

Create a sub request from the given URI. This sub request can be inspected to find information about the requested URI. The moment we've all been waiting for ⭐

$ret = $r->lookup_uri($new_uri);
$ret = $r->lookup_uri($new_uri, $next_filter);
  • obj: $r ( Apache2::RequestRec object ) β€” the current request
  • arg1: $new_uri ( string ) β€” the URI to lookup
  • opt arg2: $next_filter ( Apache2::Filter object ) β€” the first filter the subrequest should pass the data through. If not specified it defaults to the first connection output filter for the main request $r->proto_output_filters. So if the subrequest sends any output it will be filtered only once. If for example you desire to apply the main request's output filters to the sub-request output as well pass $r->output_filters as an argument.
  • ret: $ret ( Apache2::SubRequest object ) β€” the sub request record
  • since: 2.0.00

Here's an example of a simple subrequest which serves uri /new_uri: πŸ“

sub handler {
    my $r = shift;

    my $subr = $r->lookup_uri("/new_uri");
    $subr->run;

    return Apache2::Const::OK;
}

Now, let's say you have three request output filters registered to run for the main request. Three! A whole squad πŸ«‚

PerlOutputFilterHandler MyApache2::SubReqExample::filterA
PerlOutputFilterHandler MyApache2::SubReqExample::filterB
PerlOutputFilterHandler MyApache2::SubReqExample::filterC

and you wish to run them all, the code needs to become:

    my $subr = $r->lookup_uri("/new_uri", $r->output_filters);

and if you wish to run them all, but not the first one (filterA), the code needs to be adjusted to be:

    my $subr = $r->lookup_uri("/new_uri", $r->output_filters->next);

see that ->next? that's the whole trick. filterA said "not today" πŸ™ˆ

πŸ”₯ run

Run a sub-request. The moment of truth, bestie πŸƒβ™€οΈπŸ’¨

$rc = $subr->run();
  • obj: $subr ( Apache2::RequestRec object ) β€” the sub-request (e.g. returned by lookup_uri)
  • ret: $rc ( integer ) β€” the return code of the handler (Apache2::Const::OK, Apache2::Const::DECLINED, etc.)
  • since: 2.0.00

😭 Unsupported API 😭

Apache2::SubRequest also provides 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. So like, these are the situationship methods β€” no labels, no promises πŸ’€ 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. Teamwork, bestie 🫢

🧚 internal_fast_redirect

META: Autogenerated - needs to be reviewed/completed 🚧

Redirect the current request to a sub_req, merging the pools

$r->internal_fast_redirect($sub_req);
  • obj: $r ( Apache2::RequestRec object ) β€” the current request
  • arg1: $sub_req ( string ) β€” a subrequest created from this request
  • ret: no return value
  • since: 2.0.00

META: httpd-2.0/modules/http/http_request.c declares this function as:

/* XXX: Is this function is so bogus and fragile that we deep-6 it? */

do we really want to expose it to mod_perl users? 😭 like the source code itself is asking "are we sure". not the comment shading its own function πŸ’€

🌸 lookup_dirent

META: Autogenerated - needs to be reviewed/completed 🚧

Create a sub request for the given apr_dir_read result. This sub request can be inspected to find information about the requested file

$lr = $r->lookup_dirent($finfo);
$lr = $r->lookup_dirent($finfo, $subtype);
$lr = $r->lookup_dirent($finfo, $subtype, $next_filter);
  • obj: $r ( Apache2::RequestRec object ) β€” the current request
  • arg1: $finfo ( APR::Finfo object ) β€” the apr_dir_read result to lookup
  • arg2: $subtype ( integer ) β€” what type of subrequest to perform, one of:
Apache2::SUBREQ_NO_ARGS     ignore r->args and r->path_info
Apache2::SUBREQ_MERGE_ARGS  merge  r->args and r->path_info
  • arg3: $next_filter ( integer ) β€” the first filter the sub_request should use. If this is NULL, it defaults to the first filter for the main request
  • ret: $lr ( Apache2::RequestRec object ) β€” the new request record
  • since: 2.0.00

META: where do we take the apr_dir_read result from? πŸ€” honestly girl, good question, the docs don't say


πŸ’… See Also πŸ’…

mod_perl 2.0 documentation. go read it, it's right there ✨


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. shoutout to the whole squad πŸ‘‘πŸ«Ά


and that's the page, bestie!! this was libapa...Request(3pm) from the User Contributed Perl Documentation, riding on perl v5.42.3, dated 2026-08-20 πŸŒˆπŸ’œ slay, go run some subrequests (but do NOT call DESTROY yourself, I'm serious) πŸ’…βœ¨

πŸ“¦ where this page comes from