Apache2-API
view release on metacpan or search on metacpan
lib/Apache2/API/Request.pm view on Meta::CPAN
# -*- perl -*-
##----------------------------------------------------------------------------
## Apache2 API Framework - ~/lib//mnt/src/perl/Apache2-API/lib/Apache2/API/Request.pm
## Version v0.4.2
## Copyright(c) 2026 DEGUEST Pte. Ltd.
## Author: Jacques Deguest <jack@deguest.jp>
## Created 2023/05/30
## Modified 2026/06/17
## All rights reserved
##
##
## This program is free software; you can redistribute it and/or modify it
## under the same terms as Perl itself.
##----------------------------------------------------------------------------
package Apache2::API::Request;
BEGIN
{
use strict;
use warnings;
warnings::register_categories( 'Apache2::API' );
use parent qw( Module::Generic );
use vars qw( $ERROR $VERSION $SERVER_VERSION );
use utf8 ();
use version;
use Apache2::Access;
use Apache2::Const -compile => qw( :common :methods :http );
use Apache2::Connection ();
use Apache2::Log ();
use Apache2::Request;
use Apache2::RequestRec ();
use Apache2::RequestUtil ();
use Apache2::ServerUtil ();
use Apache2::RequestIO ();
use Apache2::Log;
use APR::Pool ();
use APR::Request ();
use APR::Socket ();
use APR::SockAddr ();
use APR::Request::Cookie;
use APR::Request::Apache2;
# For subnet_of() method
use APR::IpSubnet ();
use Apache2::API::Request::Params;
use Apache2::API::Request::Upload;
use Apache2::API::DateTime;
use Apache2::API::Query;
use Apache2::API::Status;
use Cookie::Jar;
use DateTime::Lite;
use Encode ();
use File::Which ();
use HTTP::AcceptLanguage;
use JSON ();
use Module::Generic::HeaderValue;
use Scalar::Util;
use URI;
use URI::Escape;
our $VERSION = 'v0.4.2';
our( $SERVER_VERSION, $ERROR );
};
use strict;
use warnings;
my $methods_bit_to_name =
{
Apache2::Const::M_GET() => 'GET',
Apache2::Const::M_POST() => 'POST',
Apache2::Const::M_PUT() => 'PUT',
Apache2::Const::M_DELETE() => 'DELETE',
Apache2::Const::M_OPTIONS() => 'OPTIONS',
Apache2::Const::M_TRACE() => 'TRACE',
Apache2::Const::M_CONNECT() => 'CONNECT',
(Apache2::Const->can('M_PATCH') ? (Apache2::Const::M_PATCH() => 'PATCH') : ()),
(Apache2::Const->can('M_PROPFIND') ? (Apache2::Const::M_PROPFIND() => 'PROPFIND') : ()),
(Apache2::Const->can('M_PROPPATCH') ? (Apache2::Const::M_PROPPATCH() => 'PROPPATCH') : ()),
(Apache2::Const->can('M_MKCOL') ? (Apache2::Const::M_MKCOL() => 'MKCOL') : ()),
(Apache2::Const->can('M_COPY') ? (Apache2::Const::M_COPY() => 'COPY') : ()),
(Apache2::Const->can('M_MOVE') ? (Apache2::Const::M_MOVE() => 'MOVE') : ()),
(Apache2::Const->can('M_LOCK') ? (Apache2::Const::M_LOCK() => 'LOCK') : ()),
(Apache2::Const->can('M_UNLOCK') ? (Apache2::Const::M_UNLOCK() => 'UNLOCK') : ()),
};
my $json_ctypes_re = qr{\Aapplication/(?:[a-zA-Z][\w\-]+\+)?json\z}i;
sub init
{
my $self = shift( @_ );
my $r;
$r = shift( @_ ) if( @_ % 2 );
$self->{request} = $r;
$self->{checkonly} = 0;
$self->SUPER::init( @_ ) || return( $self->pass_error );
$r ||= $self->{request};
$self->{accept_charset} = undef;
$self->{auth} = undef;
$self->{charset} = undef;
$self->{client_api_version} = undef;
$self->{_server_version} = undef;
# Which is an Apache2::Request, but inherits everything from Apache2::RequestRec and APR::Request::Apache2
unless( $self->{checkonly} )
{
return( $self->error( "No Apache2::RequestRec was provided." ) ) if( !$r );
return( $self->error( "Apache2::RequestRec provided ($r) is not an object!" ) ) if( !Scalar::Util::blessed( $r ) );
return( $self->error( "I was expecting an Apache2::RequestRec, but instead I got \"$r\"." ) ) if( !$r->isa( 'Apache2::RequestRec' ) );
$self->{request} = $r;
# Important as few other methods rely on this
$self->{apr} = APR::Request::Apache2->handle( $r );
my $headers = $self->headers;
lib/Apache2/API/Request.pm view on Meta::CPAN
# No Content-Length: stream until read() returns 0
elsif( defined( $ctype ) &&
lc( $ctype ) eq 'application/json' )
{
my $total = 0;
while(1)
{
# try-catch
local $@;
my $chunk = '';
my $n = eval{ $r->read( $chunk, 8192 ); };
# APR::Error
if( $@ )
{
return( $self->error( "Error trying to read 8192 bytes from the APR::Bucket: $@" ) );
}
last unless( $n );
$payload .= $chunk;
$total += $n;
if( $max_size && $total > $max_size )
{
return( $self->error({
code => Apache2::Const::HTTP_REQUEST_ENTITY_TOO_LARGE,
message => "Total payload submitted ($total bytes) exceeds configured limit ($max_size)."
}) );
}
}
}
# try-catch
local $@;
eval
{
# This is set during the init() phase
my $charset = $self->charset;
if( defined( $charset ) && $charset )
{
$payload = Encode::decode( $charset, $payload, Encode::FB_CROAK );
}
# We only UTF-8 decode it if it is a pure text file.
# If no $ctype is defined, the default should be application/octet-stream
elsif( defined( $ctype ) && $ctype =~ m,^text/,i )
{
$payload = Encode::decode_utf8( $payload, Encode::FB_CROAK );
}
};
if( $@ )
{
return( $self->error({
code => Apache2::Const::HTTP_BAD_REQUEST,
message => "Error while decoding payload received from http client: $@"
}) );
}
# Cache the request body so other handlers can access it too.
$self->pnotes( REQUEST_BODY => $payload );
$self->pnotes( REQUEST_BODY_PROCESSED => 1 );
return( $payload );
}
sub datetime { return( Apache2::API::DateTime->new( debug => shift->debug ) ); }
sub decode
{
my $self = shift( @_ );
return( APR::Request::decode( shift( @_ ) ) );
}
sub discard_request_body { return( shift->_try( 'request', 'discard_request_body' ) ); }
# Do not track: 1 or 0
sub dnt { return( shift->env( 'HTTP_DNT', @_ ) ); }
sub document_root { return( shift->_try( 'request', 'document_root', @_ ) ); }
sub document_uri { return( shift->env( 'document_uri', @_ ) ); }
sub encode
{
my $self = shift( @_ );
return( APR::Request::encode( shift( @_ ) ) );
}
sub env
{
my $self = shift( @_ );
my $r = $self->request;
if( @_ )
{
if( scalar( @_ ) == 1 )
{
my $v = shift( @_ );
if( ref( $v ) eq 'HASH' )
{
foreach my $k ( sort( keys( %$v ) ) )
{
$r->subprocess_env( $k => $v->{ $k } );
}
}
else
{
return( $r->subprocess_env( $v ) );
}
}
else
{
my $hash = { @_ };
foreach my $k ( sort( keys( %$hash ) ) )
{
$r->subprocess_env( $k => $hash->{ $k } );
}
}
}
else
{
$r->subprocess_env;
}
}
sub err_headers_out { return( shift->_headers( 'err_headers_out', @_ ) ); }
lib/Apache2/API/Request.pm view on Meta::CPAN
my $self = shift( @_ );
# my $vers = $self->server_version;
my $serv = $self->request;
# http://httpd.apache.org/docs/2.4/developer/new_api_2_4.html
# We have to prepend the version with 'v', because it will faill when there is a dotted decimal with 3 numbers,
# e.g. 2.4.16 > 2.2 will return false !!
# but v2.4.16 > v2.2 returns true :(
# Already contacted the author about this edge case (2019-09-22)
# if( version->parse( "v$vers" ) > version->parse( 'v2.2' ) )
# {
# my $ip;
# # try-catch
# local $@;
# eval
# {
# $ip = $serv->useragent_ip;
# };
# if( $@ )
# {
# warn( "Unable to get the remote ip with the method useragent_ip: $@\n" );
# }
# $ip = $self->env( 'REMOTE_ADDR' ) if( !CORE::length( $ip ) );
# return( $ip ) if( CORE::length( $ip ) );
# return;
# }
# else
# {
# return( $self->connection->remote_addr->ip_get );
# }
my $c = $self->connection;
my $coderef = $c->can( 'client_ip' ) // $c->can( 'remote_ip' );
# try-catch
local $@;
my $rv = eval
{
$coderef->( $c, shift( @_ ) ) if( @_ );
my $ip = $coderef->( $c );
$ip = $self->env( 'REMOTE_ADDR' ) if( !CORE::length( $ip ) );
return( $ip ) if( CORE::length( $ip ) );
return( '' );
};
if( $@ )
{
warn( "Unable to get the remote addr with the method ", ( $c->can( 'client_ip' ) ? 'client_ip' : 'remote_ip' ), ": $@\n" );
return;
}
return( $rv );
}
sub remote_port { return( shift->env( 'REMOTE_PORT', @_ ) ); }
sub request { return( shift->_set_get_object_without_init( 'request', 'Apache2::Request', @_ ) ); }
sub request_scheme { return( shift->env( 'REQUEST_SCHEME', @_ ) ); }
# sub request_time { return( shift->request->request_time ); }
sub request_time
{
my $self = shift( @_ );
my $t = $self->request->request_time;
my $dt = DateTime::Lite->from_epoch( epoch => $t );
# An Apache2::API::DateTime object
my $fmt = $self->datetime;
$dt->set_formatter( $fmt );
return( $dt );
}
sub request_uri { return( shift->env( 'REQUEST_URI', @_ ) ); }
sub requires { return( shift->_try( 'request', 'requires' ) ); }
sub satisfies { return( shift->_try( 'request', 'satisfies' ) ); }
sub script_filename { return( shift->env( 'SCRIPT_FILENAME', @_ ) ); }
sub script_name { return( shift->env( 'SCRIPT_NAME', @_ ) ); }
# Example: https://example.com/cgi-bin/prog.cgi/path/info
sub script_uri { return( URI->new( shift->env( 'SCRIPT_URI', @_ ) ) ); }
# Example: /cgi-bin/prog.cgi/path/info
sub script_url { return( shift->env( 'SCRIPT_URL', @_ ) ); }
# Return Apache2::ServerUtil object
sub server { return( shift->request->server ); }
sub server_addr { return( shift->env( 'SERVER_ADDR', @_ ) ); }
sub server_admin { return( shift->_try( 'server', 'server_admin', @_ ) ); }
sub server_hostname { return( shift->_try( 'server', 'server_hostname', @_ ) ); }
sub server_name { return( shift->_try( 'request', 'get_server_name' ) ); }
sub server_port { return( shift->_try( 'request', 'get_server_port' ) ); }
# Example: HTTP/1.1
sub server_protocol { return( shift->env( 'SERVER_PROTOCOL', @_ ) ); }
sub server_signature { return( shift->env( 'SERVER_SIGNATURE', @_ ) ); }
sub server_software { return( shift->env( 'SERVER_SOFTWARE', @_ ) ); }
# Or maybe the environment variable SERVER_SOFTWARE, e.g. Apache/2.4.18
# sub server_version { return( version->parse( Apache2::ServerUtil::get_server_version ) ); }
sub server_version
{
my $self = shift( @_ );
$self->{_server_version} = $SERVER_VERSION if( !CORE::length( $self->{_server_version} ) && CORE::length( $SERVER_VERSION ) );
$self->{_server_version} = shift( @_ ) if( @_ );
return( $self->{_server_version} ) if( $self->{_server_version} );
my $vers = '';
if( $self->mod_perl )
{
# try-catch
local $@;
eval
{
my $desc = Apache2::ServerUtil::get_server_description();
if( $desc =~ /\bApache\/([\d\.]+)/ )
{
$vers = $1;
lib/Apache2/API/Request.pm view on Meta::CPAN
# 200kb
$req->max_size(204800);
my $http_method = $req->method;
my $meth_num = $req->method_number;
# mod_perl/2.0.11
my $mod_perl = $req->mod_perl;
my $vers = $req->mod_perl_version;
my $seconds = $req->mtime;
my $req2 = $req->next;
$req->no_cache(1);
# APR::Table object
my $notes = $req->notes;
my $notes = $req->pnotes;
my $filters = $req->output_filters;
my $val = $req->param( $name );
my $hash_ref = $req->params;
my $dt = $req->parse_date( $http_date_string );
my $path = $req->path;
my $path_info = $req->path_info;
# for JSON payloads
my $hash_ref = $req->payload;
my $val = $req->per_dir_config( $my_config_name );
# APR::Pool object
my $pool = $req->pool;
my $best_lang = $req->preferred_language( $lang_array_ref );
my $req0 = $req->prev;
my $proto = $req->protocol;
$req->proxyreq( Apache2::Const::PROXYREQ_PROXY );
$req->push_handlers( $name => $code_ref );
# get hash reference from the query string using Apache2::API::Query instead of APR::Body->args
# To use APR::Body->args, call args() instead
my $hash_ref = $req->query;
my $string = $req->query_string;
my $nbytes = $req->read( $buff, 1024 );
my $notes = $req->redirect_error_notes;
my $qs = $req->redirect_query_string;
my $status = $req->redirect_status;
my $url = $req->redirect_url;
my $referrer = $req->referer;
# APR::SockAddr object
my $addr = $req->remote_addr;
my $host = $req->remote_host;
my $string = $req->remote_ip;
my $port = $req->remote_port;
$req->reply( Apache2::Const::FORBIDDEN => { message => "Get away" } );
# Apache2::RequestRec
my $r = $req->request;
my $scheme = $req->request_scheme;
# DateTime::Lite object
my $dt = $req->request_time;
my $uri = $req->request_uri;
my $filename = $req->script_filename;
my $name = $req->script_name;
my $uri = $req->script_uri;
# Apache2::ServerUtil object
my $server = $req->server;
my $addr = $req->server_addr;
my $admin = $req->server_admin;
my $hostname = $req->server_hostname;
my $name = $req->server_name;
my $port = $req->server_port;
my $proto = $req->server_protocol;
my $sig = $req->server_signature;
my $software = $req->server_software;
my $vers = $req->server_version;
$req->set_basic_credentials( $user => $password );
$req->set_handlers( $name => $code_ref );
my $data = $req->slurp_filename;
# Apache2::Connection object
my $socket = $req->socket;
my $status = $req->status;
my $line = $req->status_line;
my $dt = $req->str2datetime( $http_date_string );
my $rc = $req->subnet_of( $ip, $mask );
# APR::Table object
my $env = subprocess_env;
my $dir = $req->temp_dir;
my $r = $req->the_request;
my $dt = $req->time2datetime( $time );
say $req->time2str( $seconds );
# text/plain
my $type = $req->type;
my $raw = $req->unparsed_uri;
# Apache2::API::Request::Params
my $uploads = $req->uploads;
my $uri = $req->uri;
my $decoded = $req->url_decode( $url );
my $encoded = $req->url_encode( $url );
my $user = $req->user;
my $agent = $req->user_agent;
=head1 VERSION
v0.4.2
=head1 DESCRIPTION
The purpose of this module is to provide an easy access to various methods designed to process and manipulate incoming requests.
This is designed to work under modperl.
Normally, one would need to know which method to access across various Apache2 mod perl modules, which makes development more time consuming and even difficult, because of the scattered documentation and even sometime outdated.
This module alleviate this problem by providing all the necessary methods in one place. Also, at the contrary of L<Apache2> modules suit, all the methods here are die safe. When an error occurs, it will always return undef() and the error will be abl...
lib/Apache2/API/Request.pm view on Meta::CPAN
See also L</type> to retrieve only the content type, i.e without other information such as charset.
See also L</client_api_version> which would contain the requested api version, if any.
See also L<charset> for the charset provided, if any. For example C<utf-8>
=head2 cookie
Returns the current value for the given cookie name, which may be C<undef> if nothing is found.
This works by calling the L</cookies> method, which returns a L<cookie jar object|Cookie::Jar>.
=head2 cookies
Returns a L<Cookie::Jar> object acting as a jar with various methods to access, manipulate and create cookies.
=head2 data
This method reads the data sent by the client. It can be used as an accessor, and it will return a cached data, if any, or read the data from L<APR::Bucket>, or it can be used as a mutator to artificially set a payload.
Internally it uses L<Apache2::RequestUtil/pnotes> to cache the processed request body and stores it in C<REQUEST_BODY>, and set the shared property C<REQUEST_BODY_PROCESSED> to C<1>. Thus, the processed raw request body is always for other handlers w...
It takes an optional hash or hash reference of the following options:
=over 4
=item * C<data>
When provided, this will set the request body to the value provided.
=item * C<max_size>
The maximum size of the data that can be transmitted to us over HTTP. By default, there is no limit.
=back
Finally, if a charset is specified, this will also decode it from its encoded charset into perl internal utf8.
This is specifically designed for C<JSON> payload.
It returns a string of data upon success, or sets an L<error|Module::Generic/error> and return C<undef> or an empty list depending on the context.
You can also set a maximum size to read by setting the attribute C<PAYLOAD_MAX_SIZE> in Apache configuration file.
For example:
<Directory /home/john/www>
PerlOptions +GlobalRequest
SetHandler modperl
# package inheriting from Apache2::API
PerlResponseHandler My::API
# 2Mb upload limit
PerlSetVar PAYLOAD_MAX_SIZE 2097152
</Directory>
This is just an example and not a recommandation. Your mileage may vary.
=head2 datetime
Returns a new L<Apache2::API::DateTime> object, which is used to parse and format dates for HTTP.
See L<Apache2::API/parse_datetime> and L<Apache2::API/format_datetime>
=head2 decode
Given a url-encoded string, this returns the decoded string, by calling L<APR::Request/decode>
This uses L<APR::Request> XS method.
See also L<rfc3986|https://datatracker.ietf.org/doc/html/rfc3986>
=head2 discard_request_body
my $rc = $req->discard_request_body;
In C<HTTP/1.1>, any method can have a body. However, most C<GET> handlers would not know what to do with a request body if they received one. This helper routine tests for and reads any message body in the request, simply discarding whatever it recei...
Returns C<Apache2::Const::OK> upon success.
use Apache2::API;
my $rc = $req->discard_request_body;
return( $rc ) if( $rc != Apache2::Const::OK );
This method calls L<Apache2::RequestIO/discard_request_body>
=head2 dnt
Sets or gets the environment variable C<HTTP_DNT> using L<Apache2::RequestRec/subprocess_env>. See L</env> below for more on that.
This is an abbreviation for C<Do not track>
If available, typical value is a boolean such as C<0> or C<1>
=head2 document_root
Sets or retrieve the document root for this server.
If a value is provided, it sets the document root to a new value only for the duration of the current request.
See L<Apache2::RequestUtil> for more information.
=head2 document_uri
Get the value for the environment variable C<DOCUMENT_URI>.
=head2 encode
Given a string, this returns its url-encoded version
This uses L<APR::Request> XS method.
=head2 env
my $val = $req->env( $name );
$req->env( $name, $value );
Using the Apache C<subprocess_env> table, this sets or gets environment variables. This is the equivalent of this:
$req->subprocess_env;
$env_table = $req->subprocess_env;
lib/Apache2/API/Request.pm view on Meta::CPAN
my $table3 = $table->overlay( $table2, $pool3 );
See L<APR::Table> for more information.
=head2 header_only
This is the same as L</is_header_only>
=head2 headers_as_hashref
Returns the list of headers as an hash reference, by calling L<Apache2::RequestRec/headers_in>
Since the call to L<Apache2::RequestRec> returns a L<APR::Table> object, we may get 2 or more same key name, and in that case, the hash with that key will have as a value an array reference.
=head2 headers_as_json
Returns the list of headers as a json data, by retrieving the hash from L</headers_as_hashref> and encode it with L<JSON>
=head2 headers_in
Returns the list of the headers as special hash, which is actually an L<APR::Table> object.
If a header name is provided, you can retrieve its value like so:
my $cookie = $req->headers_in->{Cookie} || '';
=head2 headers_out
This is identical to L</headers_in>, as it returns a L<APR::Table> object.
Returns or sets the key => value pairs of outgoing HTTP headers, only on 2xx responses.
See also L</err_headers_out>, which allows to set headers for non-2xx responses and persist across internal redirects.
More information at L<Apache2::RequestRec/headers_out>
=head2 hostname
Retrieve or set the HTTP server host name, such as C<www.example.com>, by calling L<Apache2::RequestRec/hostname>
This is not the machine hostname.
More information at L<Apache2::RequestRec>
=head2 http_host
Returns an C<URI> object of the HTTP host being accessed. This is created during object initiation phase.
This calls the method C<host> on the L<URI> object returned by L</uri>
=head2 id
Returns the connection id; unique at any point in time, by calling L<Apache2::Connection/id>.
See L<Apache2::Connection> for more information.
This is the same as L</connection_id>
=head2 if_modified_since
Returns the value of the HTTP header If-Modified-Since as a L<DateTime::Lite> object.
If no such header exists, it returns C<undef> or an empty list depending on the context.
=head2 if_none_match
Sets or gets the value of the HTTP header C<If-None-Match>
See also L</headers>
=head2 input_filters
Get or sets the first filter in a linked list of request level input filters. It returns a L<Apache2::Filter> object.
$input_filters = $req->input_filters();
$prev_input_filters = $req->input_filters( $new_input_filters );
According to the L<Apache2::RequestRec> documentation:
For example instead of using C<< $req->read() >> to read the C<POST> data, one could use an explicit walk through incoming bucket brigades to get that data. The following function C<read_post()> does just that (in fact that's what C<< $req->read() >>...
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( $req->pool,
$req->connection->bucket_alloc );
my $data = '';
my $seen_eos = 0;
do {
$req->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;
}
lib/Apache2/API/Request.pm view on Meta::CPAN
Get or sets text notes for the duration of this request by calling L<Apache2::RequestUtil/pnotes>. These notes can be passed from one module to another (not only mod_perl, but modules in any other language).
If a new value was passed, returns the previous value.
The returned value is a L<APR::Table> object by calling L<Apache2::RequestUtil/notes>
=head2 output_filters
my $output_filters = $req->connection->output_filters();
my $prev_output_filters = $req->output_filters( $new_output_filters );
Set or get the first filter in a linked list of request level output filters by calling L</output_filters>. It returns a L<Apache2::Filter> object.
If a new output filters was passed, returns the previous value.
According to the L<Apache2::RequestRec> documentation:
For example instead of using C<< $req->print() >> to send the response body, one could send the data directly to the first output filter. The following function C<send_response_body()> does just that:
use APR::Brigade ();
use APR::Bucket ();
use Apache2::Filter ();
sub send_response_body
{
my( $req, $data ) = @_;
my $bb = APR::Brigade->new( $req->pool,
$req->connection->bucket_alloc );
my $b = APR::Bucket->new( $bb->bucket_alloc, $data );
$bb->insert_tail( $b );
$req->output_filters->fflush( $bb );
$bb->destroy;
}
In fact that's what C<< $req->read() >> does behind the scenes. But it also knows to parse HTTP headers passed together with the data and it also implements buffering, which the above function does not.
=head2 param
Provided a name, this returns its equivalent value, using L<Apache2::API::Request::Params/param>.
If C<$name> is an upload field, ie part of a multipart post data, it returns an L<Apache2::API::Request::Upload> object instead.
If a value is provided, this calls L<Apache2::API::Request::Param/param> providing it with the name ane value. This uses L<APR::Request::Param>.
=head2 params
Get the request parameters (using case-insensitive keys) by mimicing the OO interface of L<CGI::param>.
It can take as argument, only a key and it will then retrieve the corresponding value, or it can take a key and value pair to set them using L<Apache2::API::Request::Params/param>
If the value is an array, this will set multiple entry of the key for each value provided.
This uses Apache L<APR::Table> and works for both C<POST> and C<GET> methods.
If the methods received was a C<GET> method, this method returns the value of the L</query> method instead.
=head2 parse_date
Alias to L<Apache2::API::DateTime/parse_date>
=head2 path
Get the value for the environment variable C<PATH>
See also L</env>
=head2 path_info
my $path_info = $req->path_info();
my $prev_path_info = $req->path_info( $path_info );
Get or set the C<PATH_INFO>, what is left in the path after the C<< URI --> filename >> translation, by calling L<Apache2::RequestRec/path_info>
Return a string as the current value.
=head2 payload
Returns the JSON data decoded into a perl structure. This is set at object initiation phase and calls the L</data> method to read the incoming data and decoded it into perl internal utf8.
=head2 per_dir_config
Get the dir config vector, by calling L<Apache2::RequestRec/per_dir_config>. Returns a L<Apache2::ConfVector> object.
For an in-depth discussion, refer to the Apache Server Configuration Customization in Perl chapter.
=head2 pnotes
Share Perl variables between Perl HTTP handlers, using L<Apache2::RequestUtil/pnotes>.
# to share variables by value and not reference, $val should be a lexical.
$old_val = $req->pnotes( $key => $val );
$val = $req->pnotes( $key );
$hash_ref = $req->pnotes();
Note: sharing variables really means it. The variable is not copied. Only its reference count is incremented. If it is changed after being put in pnotes that change also affects the stored value. The following example illustrates the effect:
my $v = 1; my $v = 1;
$req->pnotes( 'v'=> $v ); $req->pnotes->{v} = $v;
$v++; $v++;
my $x = $req->pnotes('v'); my $x = $req->pnotes->{v};
=head2 pool
Returns the pool associated with the request as a L<APR::Pool> object of the L<Apache2 connection|Apache2::Connection>. If you rather want access to the pool object of the Apache2 request itself, use L</request>, such as:
# $rest being a Apache2::API object
my $request_pool = $req->pool;
$request_pool->cleanup_register( \&cleanup );
=head2 preferred_language
Given an array reference of supported languages, this method will get the client accepted languages by calling L</accept_language> and derive the best match, ie the client preferred language, using L<HTTP::AcceptLanguage>,.
It returns a string representing a language code.
Note that it does not matter if the array reference of supported language use underscore or dash, so both of the followings are equivalent:
my $best_lang = $req->preferred_language( [qw( en_GB fr_FR ja_JP ko_KR )] );
lib/Apache2/API/Request.pm view on Meta::CPAN
my $remote_host = $req->remote_host();
my $remote_host = $req->remote_host( $type );
my $remote_host = $req->remote_host( $type, $dir_config );
If C<$type> is provided, it must be a C<:remotehost> constant (see L<Apache2::Const>):
=over 4
=item C<Apache2::Const::REMOTE_DOUBLE_REV>
Will always force a DNS lookup, and also force a double reverse lookup, regardless of the "HostnameLookups" setting. The result is the (double reverse checked) hostname, or C<undef> if any of the lookups fail.
=item C<Apache2::Const::REMOTE_HOST>
Returns the hostname, or C<undef> if the hostname lookup fails. It will force a DNS lookup according to the C<HostnameLookups> setting.
=item C<Apache2::Const::REMOTE_NAME>
Returns the hostname, or the dotted quad if the hostname lookup fails. It will force a DNS lookup according to the C<HostnameLookups> setting.
=item C<Apache2::Const::REMOTE_NOLOOKUP>
Is like C<Apache2::Const::REMOTE_NAME> except that a DNS lookup is never forced.
If C<$dir_config> is provided, this is the directory config vector from the request. It is needed to find the container in which the directive C<HostnameLookups> is set. To get one for the current request use C<< $req->per_dir_config >>.
By default, C<undef> is passed, in which case it is the same as if C<HostnameLookups> was set to C<Off>.
=back
Default value is C<Apache2::Const::REMOTE_NAME>
=head2 remote_ip
my $remote_ip = $req->connection->remote_ip();
my $prev_remote_ip = $req->connection->remote_ip( $new_remote_ip );
Sets or gets the ip address of the client, ie remote host making the request, by calling L<Apache2::Connection/client_ip> or L<Apache2::Connection/remote_ip>
It returns a string representing an ip address,
=head2 remote_port
It returns the value for the environment variable C<REMOTE_PORT> or set its value with the argument provided if any.
$req->remote_port( 51234 );
print( "Remote port is: ", $req->remote_port, "\n" );
=head2 request
Returns the embedded L<Apache2::RequestRec> object provided initially at object instantiation.
=head2 request_scheme
Gets or sets the environment variable C<REQUEST_SCHEME>
=head2 request_time
Read-only.
Returns the time when the request started as a L<DateTime::Lite> object with L<Apache2::API::DateTime> as the formatter.
=head2 request_uri
This returns the current value for the environment variable C<REQUEST_URI>, or set its value if an argument is provided.
The uri provided by this environment variable include the path info if any.
For example, assuming you have a cgi residing in C</cgi-bin/prog.cgi> and it is called with the path info C</some/value>, the value returned would then be C</cgi-bin/prog.cgi/some/value>
=head2 requires
$requires = $req->requires;
Retrieve information about all of the requires directives for this request, by calling L<Apache2::Access/requires>
It returns an array reference of hash references, containing information related to the C<require> directive.
For example if the configuration had the following require directives:
Require user goo bar
Require group bar tar
<Limit POST>
Require valid-user
</Limit>
this method will return the following datastructure:
[
{
method_mask => -1,
requirement => 'user goo bar'
},
{
method_mask => -1,
requirement => 'group bar tar'
},
{
method_mask => 4,
requirement => 'valid-user'
}
];
The requirement field is what was passed to the "Require" directive. The method_mask field is a bitmask which can be modified by the C<Limit> directive, but normally it can be safely ignored as it's mostly used internally.
See also L<https://httpd.apache.org/docs/2.4/en/howto/access.html>
=head2 satisfies
my $satisfy = $req->satisfies;
Get the applicable value of the C<Satisfy> directive, by calling L<Apache2::Access/satisfies>
It returns one of the L<Apache2::Const> C<:satisfy> constants:
=over 4
=item * C<Apache2::Const::SATISFY_ANY>
Any of the requirements must be met.
lib/Apache2/API/Request.pm view on Meta::CPAN
$ok = $req->set_handlers( $hook_name => [] );
$ok = $req->set_handlers( $hook_name => undef );
=head2 slurp_filename
Slurp the contents of C<< $req->filename >>:
This returns a scalar reference instead of the actual string. To get the string, use L</content>
Note that if you assign to C<$req->filename> you need to update its stat record.
=head2 socket
Get or sets the client socket and returns a L<APR::Socket> object.
This calls L<Apache2::Connection/client_socket> package.
=head2 status
my $status = $req->status();
my $prev_status = $req->status( $new_status );
Get or set thes reply status for the client request, which is an integer, by calling L<Apache2::RequestRec/status>
Normally you would use some L<Apache2::Const> constant, e.g. L<Apache2::Const::REDIRECT>.
From the L<Apache2::RequestRec> documentation:
Usually you will set this value indirectly by returning the status code as the handler's function result. However, there are rare instances when you want to trick Apache into thinking that the module returned an C<Apache2::Const:OK> status code, but ...
$req->status( $some_code );
return( Apache2::Const::OK );
See also C<< $req->status_line >>, which. if set, overrides C<< $req->status >>.
=head2 status_line
my $status_line = $req->status_line();
my $prev_status_line = $req->status_line( $new_status_line );
Get or sets the response status line. The status line is a string like C<200 Document follows> and it will take precedence over the value specified using the C<< $req->status() >> described above.
According to the L<Apache2::RequestRec> documentation:
When discussing C<< $req->status >> we have mentioned that sometimes a handler runs to a successful completion, but may need to return a different code, which is the case with the proxy server. Assuming that the proxy handler forwards to the client w...
$req->status_line( $response->code() . ' ' . $response->message() );
return( Apache2::Const::OK );
In this example C<$response> could be for example an L<HTTP::Response> object, if L<LWP::UserAgent> was used to implement the proxy.
This method is also 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 that in the response like so:
$req->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.
=head2 str2datetime
Alias to L<Apache2::API::DateTime/str2datetime>
=head2 str2time
Alias to L<Apache2::API::DateTime/str2time>
=head2 subnet_of
Provided with an ip address (v4 or v6), and optionally a subnet mask, and this will return a boolean value indicating if the current connection ip address is part of the provided subnet.
The mask can be a string or a number of bits.
It uses L<APR::IpSubnet> and performs the test using the object from L<APR::SockAddr> as provided with L</remote_addr>
my $ok = $req->subnet_of( '127.0.0.1' );
my $ok = $req->subnet_of( '::1' );
my $ok = $req->subnet_of( '127.0.0.1', '255.0.0.0' );
my $ok = $req->subnet_of( '127.0.0.1', 15 );
if( !$req->subnet_of( '127.0.0.1' ) )
{
print( "Sorry, only local connections allowed\n" );
}
=head2 subprocess_env
Get or sets the L<Apache2::RequestRec> C<subprocess_env> table, or optionally set the value of a named entry.
From the L<Apache2::RequestRec> documentation:
When called in void context with no arguments, it populate C<%ENV> with special variables (e.g. C<$ENV{QUERY_STRING}>) like mod_cgi does.
When called in a non-void context with no arguments, it returns an C<APR::Table object>.
When the $key argument (string) is passed, it returns the corresponding value (if such exists, or C<undef>. The following two lines are equivalent:
$val = $req->subprocess_env( $key );
$val = $req->subprocess_env->get( $key );
When the $key and the $val arguments (strings) are passed, the value is set. The following two lines are equivalent:
$req->subprocess_env( $key => $val );
$req->subprocess_env->set( $key => $val );
The C<subprocess_env> C<table> is used by L<Apache2::SubProcess>, to pass environment variables to externally spawned processes. It is also used by various Apache modules, and you should use this table to pass the environment variables. For example i...
$req->subprocess_env( MyLanguage => "de" );
you can then deploy C<mod_include> and write in C<.shtml> document:
<!--#if expr="$MyLanguage = en" -->
English
<!--#elif expr="$MyLanguage = de" -->
Deutsch
<!--#else -->
Sorry
<!--#endif -->
=head2 temp_dir
my $dir = $req->temp_dir;
$req->temp_dir( $dir );
Get or set the spool directory for uploads which exceed the configured brigade_limit.
=head2 the_request
my $request = $req->the_request();
my $old_request = $req->uri( $new_request );
Get or set the first HTTP request header as a string by calling L<Apache2::RequestRec/the_request>. For example:
GET /foo/bar/my_path_info?args=3 HTTP/1.0
=head2 time2datetime
Alias to L<Apache2::API::DateTime/time2datetime>
=head2 time2str
Alias to L<Apache2::API::DateTime/time2str>
=head2 type
Returns the content type of the request received. This value is set at object initiation phase.
So for example, if the HTTP request C<Content-type> is
Content-Type: application/json; charset=utf-8
Then, L</type> would return C<application/json>
=head2 unparsed_uri
The URI without any parsing performed.
If for example the request was:
GET /foo/bar/my_path_info?args=3 HTTP/1.0
C<< $req->uri >> returns:
/foo/bar/my_path_info
whereas C<< $req->unparsed_uri >> returns:
/foo/bar/my_path_info?args=3
=head2 uploads
Returns an L<array object|Module::Generic::Array> of L<Apache2::API::Request::Upload> objects.
=head2 uri
Returns a L<URI> object representing the full uri of the request.
This is different from the original L<Apache2::RequestRec> which only returns the path portion of the URI.
So, to get the path portion using our L</uri> method, one would simply do C<< $req->uri->path() >>
This L<URI> object is built using L<Apache2::RequestUtil/get_server_name> for the C<host>, L<Apache2::RequestUtil/get_server_port> for the port number, and the scheme is C<https> if the port is C<443>, otherwise C<http>. It is followed then by the pa...
=head2 url_decode
This is merely a convenient pointer to L</decode>
=head2 url_encode
This is merely a convenient pointer to L</encode>
=head2 user
Get the user name, if an authentication process was successful. Or set it, by calling L<Apache2::RequestRec/user>
For example, let's print the username passed by the client:
my( $res, $sent_pw ) = $req->get_basic_auth_pw;
return( $res ) if( $res != Apache2::Const::OK );
print( "User: ", $req->user );
=head2 user_agent
( run in 0.425 second using v1.01-cache-2.11-cpan-524268b4103 )