Apache2-API
view release on metacpan or search on metacpan
lib/Apache2/API/Response.pm view on Meta::CPAN
}
}
sub headers { return( shift->_headers( 'err_headers_out', @_ ) ); }
sub headers_out { return( shift->_headers( 'headers_out', @_ ) ); }
# <https://perl.apache.org/docs/2.0/api/Apache2/SubRequest.html#toc_C_internal_redirect_>
sub internal_redirect
{
my $self = shift( @_ );
my $uri = shift( @_ );
$uri = $uri->path if( Scalar::Util::blessed( $uri ) && $uri->isa( 'URI' ) );
# try-catch
local $@;
eval
{
$self->_request->internal_redirect( $uri );
};
if( $@ )
{
$self->error( "An error occurred while trying to call Apache Request method \"internal_redirect\": $@" );
return( Apache2::Const::HTTP_INTERNAL_SERVER_ERROR );
}
return( Apache2::Const::HTTP_OK );
}
# <https://perl.apache.org/docs/2.0/api/Apache2/SubRequest.html#toc_C_internal_redirect_handler_>
sub internal_redirect_handler
{
my $self = shift( @_ );
my $uri = shift( @_ );
$uri = $uri->path if( Scalar::Util::blessed( $uri ) && $uri->isa( 'URI' ) );
# try-catch
local $@;
eval
{
$self->_request->internal_redirect_handler( $uri );
};
if( $@ )
{
$self->error( "An error occurred while trying to call Apache Request method \"internal_redirect_handler\": $@" );
return( Apache2::Const::HTTP_INTERNAL_SERVER_ERROR );
}
return( Apache2::Const::HTTP_OK );
}
sub is_info { return( Apache2::API::Status->is_info( $_[1] ) ); }
sub is_success { return( Apache2::API::Status->is_success( $_[1] ) ); }
sub is_redirect { return( Apache2::API::Status->is_redirect( $_[1] ) ); }
sub is_error { return( Apache2::API::Status->is_error( $_[1] ) ); }
sub is_client_error { return( Apache2::API::Status->is_client_error( $_[1] ) ); }
sub is_server_error { return( Apache2::API::Status->is_server_error( $_[1] ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive>
sub keep_alive { return( shift->_set_get_one( 'Keep-Alive', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified>
sub last_modified { return( shift->_set_get_one( 'Last-Modified', @_ ) ); }
sub last_modified_date { return( shift->headers( 'Last-Modified-Date', @_ ) ); }
# Number of bytes sent
sub length { return( shift->_try( 'request', 'bytes_sent' ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location>
sub location { return( shift->_set_get_one( 'Location', @_ ) ); }
# <https://perl.apache.org/docs/2.0/api/Apache2/SubRequest.html#toc_C_run_>
sub lookup_uri
{
my $self = shift( @_ );
my $uri = shift( @_ );
$uri = $uri->path if( Scalar::Util::blessed( $uri ) && $uri->isa( 'URI' ) );
# try-catch
local $@;
my $rv = eval
{
my $subr = $self->_request->lookup_uri( $uri, @_ );
# Returns Apache2::Const::OK, Apache2::Const::DECLINED, etc.
return( $subr->run );
};
if( $@ )
{
$self->error( "An error occurred while trying to call Apache Request method \"internal_redirect_handler\": $@" );
return( Apache2::Const::HTTP_INTERNAL_SERVER_ERROR );
}
return( $rv );
}
# make_etag( $force_weak )
# <https://perl.apache.org/docs/2.0/api/Apache2/Response.html#C_make_etag_>
sub make_etag { return( shift->_try( '_request', 'make_etag', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age>
sub max_age { return( shift->_set_get_number( 'Access-Control-Max-Age', @_ ) ); }
sub meets_conditions { return( shift->_try( '_request', 'meets_conditions' ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/NEL>
sub nel { return( shift->_set_get_one( 'NEL', @_ ) ); }
# This adds the following to the outgoing headers:
# Pragma: no-cache
# Cache-control: no-cache
sub no_cache { return( shift->_try( '_request', 'no_cache', @_ ) ); }
sub no_local_copy { return( shift->_try( '_request', 'no_local_copy', @_ ) ); }
sub print { return( shift->_try( '_request', 'print', @_ ) ); }
sub printf { return( shift->_try( '_request', 'printf', @_ ) ); }
sub puts { return( shift->_try( '_request', 'puts', @_ ) ); }
sub redirect
{
my $self = shift( @_ );
# I have to die if nothing was provided, because our return value is the http code. We can't just return undef()
my $uri = shift( @_ ) || die( "No uri provided to redirect\n" );
# Stringify
$self->headers->set( 'Location' => "$uri" );
$self->code( Apache2::Const::HTTP_MOVED_TEMPORARILY );
return( Apache2::Const::HTTP_MOVED_TEMPORARILY );
}
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy>
sub referrer_policy { return( shift->_set_get_one( 'Referrer-Policy', @_ ) ); }
sub request { return( shift->_set_get_object( 'request', 'Apache2::API::Request', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After>
sub retry_after { return( shift->_set_get_one( 'Retry-After', @_ ) ); }
sub rflush { return( shift->_try( '_request', 'rflush' ) ); }
# e.g. send_cgi_header( $buffer )
sub send_cgi_header { return( shift->_try( '_request', 'send_cgi_header', @_ ) ); }
# e.g. sendfile( $filename );
# sendfile( $filename, $offset );
# sendfile( $filename, $offset, $len );
sub sendfile { return( shift->_try( '_request', 'sendfile', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server>
sub server { return( shift->_set_get_one( 'Server', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing>
sub server_timing { return( shift->_set_get_one( 'Server-Timing', @_ ) ); }
# e.g set_content_length( 1024 )
sub set_content_length { return( shift->_try( '_request', 'set_content_length', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie>
sub set_cookie { return( shift->_set_get_one( 'Set-Cookie', @_ ) ); }
sub set_etag { return( shift->_try( '_request', 'set_etag', @_ ) ); }
sub set_keepalive { return( shift->_try( '_request', 'set_keepalive', @_ ) ); }
# <https://perl.apache.org/docs/2.0/api/Apache2/Response.html#toc_C_set_last_modified_>
sub set_last_modified { return( shift->_try( '_request', 'set_last_modified', @_ ) ); }
# Returns a APR::Socket
# See Apache2::Connection manual page
sub socket { return( shift->_try( 'connection', 'client_socket', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/SourceMap>
sub sourcemap { return( shift->_set_get_one( 'SourceMap', @_ ) ); }
sub status { return( shift->_try( '_request', 'status', @_ ) ); }
sub status_line { return( shift->_try( '_request', 'status_line', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security>
sub strict_transport_security { return( shift->_set_get_one( 'Strict-Transport-Security', @_ ) ); }
sub subprocess_env { return( shift->_try( '_request', 'subprocess_env' ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin>
sub timing_allow_origin { return( shift->_set_get_multi( 'Timing-Allow-Origin', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer>
sub trailer { return( shift->_set_get_one( 'Trailer', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding>
sub transfer_encoding { return( shift->_set_get_one( 'Transfer-Encoding', @_ ) ); }
sub unescape { return( URI::Escape::uri_unescape( @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade>
sub upgrade { return( shift->_set_get_multi( 'Upgrade', @_ ) ); }
sub update_mtime { return( shift->_try( '_request', 'update_mtime', @_ ) ); }
sub uri_escape { return( shift->escape( @_ ) ); }
sub uri_unescape { return( shift->unescape( @_ ) ); }
sub url_decode { return( shift->decode( @_ ) ); }
sub url_encode { return( shift->encode( @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary>
sub vary { return( shift->_set_get_multi( 'Vary', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via>
sub via { return( shift->_set_get_multi( 'Via', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Want-Digest>
sub want_digest { return( shift->_set_get_multi( 'Want-Digest', @_ ) ); }
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning>
sub warning { return( shift->_set_get_one( 'Warning', @_ ) ); }
# e.g. $cnt = $r->write($buffer);
# $cnt = $r->write( $buffer, $len );
# $cnt = $r->write( $buffer, $len, $offset );
sub write { return( shift->_try( '_request', 'write', @_ ) ); }
lib/Apache2/API/Response.pm view on Meta::CPAN
name => $name,
value => $some_value,
value => 'sid1234567',
path => '/',
expires => '+10D',
# or alternatively
maxage => 864000
# to make it exclusively accessible by regular http request and not javascript
http_only => 1,
same_site => 'Lax',
# should it be used under ssl only?
secure => 1
);
$resp->cookie_replace( $cookie );
$resp->cookie_set( $cookie );
# Cross-Origin-Embedder-Policy
my $policy = $resp->cross_origin_embedder_policy;
# Cross-Origin-Opener-Policy
my $policy = $resp->cross_origin_opener_policy;
# Cross-Origin-Resource-Policy
my $policy = $resp->cross_origin_resource_policy;
my $cspro = $resp->cspro;
$resp->custom_response( Apache2::Const::AUTH_REQUIRED, "Authenticate please" );
my $decoded = $resp->decode( $string );
# Digest
my $digest = $resp->digest;
my $encoded = $resp->encode( $string );
# APR::Table object
my $env = $resp->env;
my $headers = $resp->err_headers;
my $headers = $resp->err_headers_out;
my $escaped = $resp->escape( $string );
my $etag = $resp->etag;
# Expires
my $expires = $resp->expires;
# Access-Control-Expose-Headers
my $expose_headers = $resp->expose_headers;
$resp->flush;
my $msg = $resp->get_http_message( 429 => 'ja_JP' );
my $string = $resp->get_status_line;
my $content_type = $resp->headers( 'Content-Type' );
# or (since it is case insensitive)
my $content_type = $resp->headers( 'content-type' );
# or
my $content_type = $resp->headers->{'Content-Type'};
$resp->header( 'Content-Type' => 'text/plain' );
# or
$resp->headers->{'Content-Type'} = 'text/plain';
# APR::Table object
my $headers = $resp->headers;
my $headers = $resp->headers_out;
$resp->internal_redirect( $uri );
$resp->internal_redirect_handler( $uri );
my $rv = $resp->is_info(100);
my $rv = $resp->is_success(200);
my $rv = $resp->is_redirect(302);
my $rv = $resp->is_error(400);
my $rv = $resp->is_client_error(401);
my $rv = $resp->is_server_error(500);
# Keep-Alive
my $keep_alive = $resp->keep_alive;
# Last-Modified
my $http_date = $resp->last_modified;
# Last-Modified-Date
my $http_date = $resp->last_modified_date;
# The number of bytes sent. Actually calls bytes_sent()
my $nbytes = $resp->length;
# Location
my $loc = $resp->location;
my $rv = $resp->lookup_uri( $uri );
my $etag = $resp->make_etag( $force_weak );
# Access-Control-Max-Age
my $max_age = $resp->max_age;
my $rv = $resp->meets_conditions;
# NEL
my $nel = $resp->nel;
$resp->no_cache(1);
$resp->no_local_copy(1);
$resp->print( @some_data );
$resp->printf( $template, $param1, $param2 );
my $puts = $resp->puts;
my $rv = $resp->redirect( $uri );
# Referrer-Policy
my $policy = $resp->referrer_policy;
my $r = $resp->request;
# Retry-After
my $retry_after = $resp->retry_after;
$resp->rflush;
$resp->send_cgi_header;
$resp->sendfile( $filename, $offset, $len );
$resp->sendfile( $filename );
# Server
my $server = $resp->server;
my $server_timing = $resp->server_timing;
$resp->set_content_length(1024);
# Set-Cookie
$resp->set_cookie( $cookie );
$resp->set_last_modified;
$resp->set_keepalive(1);
my $socket = $resp->socket;
my $sourcemap = $resp->sourcemap;
my $status = $resp->status;
my $status_line = $resp->status_line;
# Strict-Transport-Security
my $policy = $resp->strict_transport_security;
# APR::Table object
my $env = $resp->subprocess_env;
# Timing-Allow-Origin
my $origin = $resp->timing_allow_origin;
# Trailer
my $trailerv = $resp->trailer;
my $enc = $resp->transfer_encoding;
my $unescape = $resp->unescape( $string );
# Upgrade
my $upgrade = $resp->upgrade;
$resp->update_mtime( $seconds );
my $uri = $resp->uri_escape( $uri );
my $uri = $resp->uri_unescape( $uri );
my $decoded = $resp->url_decode( $uri );
my $encoded = $resp->url_encode( $uri );
# Vary
my $vary = $resp->vary;
# Via
my $via = $resp->via;
# Want-Digest
my $want = $resp->want_digest;
# Warning
my $warn = $resp->warning;
$resp->write( $buffer, $len, $offset );
# WWW-Authenticate
my $auth = $resp->www_authenticate;
# X-Content-Type-Options
my $opt = $resp->x_content_type_options;
# X-DNS-Prefetch-Control
my $proto = $resp->x_dns_prefetch_control;
# X-Frame-Options
my $opt = $resp->x_frame_options;
# X-XSS-Protection
my $xss = $resp->x_xss_protection;
=head1 VERSION
v0.2.0
=head1 DESCRIPTION
The purpose of this module is to provide an easy access to various method to process and manipulate incoming request.
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 C<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...
Fo its alter ego to manipulate outgoing HTTP response, use the L<Apache2::API::Response> module.
=head1 CONSTRUCTORS
=head2 new
lib/Apache2/API/Response.pm view on Meta::CPAN
});
# To prepare a table of 20 elements, but the table can still grow
my $table = APR::Table::make( $resp->pool, 20 );
my $table2 = $resp2->headers;
# overwrite any existing keys in our table $table
$table->overlap( $table2, APR::Const::OVERLAP_TABLES_SET );
# key, value pairs are added, regardless of whether there is another element with the same key in $table
$table->overlap( $table2, APR::Const::OVERLAP_TABLES_MERGE );
my $table3 = $table->overlay( $table2, $pool3 );
See L<APR::Table> for more information.
=head2 headers_out
Returns or sets the C<< 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>
=head2 internal_redirect
Given a C<URI> object or a uri path string, this redirect the current request to some other uri internally.
If a C<URI> object is given, its C<path> method will be used to get the path string.
$resp->internal_redirect( $new_uri );
In case that 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 L<Apache2::Const::OK>. The client will be unaware the a differe...
See L<Apache2::SubRequest> for more information.
=head2 internal_redirect_handler
Identical to L</internal_redirect>, plus automatically sets C<< $resp->content_type >> is of the sub-request to be the same as of the main request, if C<< $resp->handler >> is true.
=head2 is_info
Given a HTTP code integer, this will return true if the code is comprised between C<100> and less than C<200>, false otherwise.
=head2 is_success
Given a HTTP code integer, this will return true if the code is comprised between C<200> and less than C<300>, false otherwise.
=head2 is_redirect
Given a HTTP code integer, this will return true if the code is comprised between C<300> and less than C<400>, false otherwise.
=head2 is_error
Given a HTTP code integer, this will return true if the code is comprised between C<400> and less than C<600>, false otherwise.
=head2 is_client_error
Given a HTTP code integer, this will return true if the code is comprised between C<400> and less than C<500>, false otherwise.
=head2 is_server_error
Given a HTTP code integer, this will return true if the code is comprised between C<500> and less than C<600>, false otherwise.
=head2 keep_alive
Sets or gets the HTTP header field C<Keep-Alive>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive>
=head2 last_modified
Sets or gets the HTTP header field C<Last-Modified>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified>
=head2 last_modified_date
Sets or gets the HTTP header field C<Last-Modified-Date>
=head2 length
Read only.
This returns the number of bytes sent by calling L<Apache2::RequestRec/bytes_sent>
=head2 location
Sets or gets the HTTP header field C<Location>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location>
=head2 lookup_uri
Create a sub request from the given URI, by calling L<Apache2::SubRequest/lookup_uri>
This sub request can be inspected to find information about the requested URI.
$ret = $resp->lookup_uri( $new_uri );
$ret = $resp->lookup_uri( $new_uri, $next_filter );
$ret = $resp->lookup_uri( $new_uri, $next_filter, $handler );
See L<Apache2::SubRequest> for more information.
=head2 make_etag
Provided with a boolean value, this constructs an entity tag from the resource information, by calling L<Apache2::Response/make_etag>
If it is a real file, build in some of the file characteristics.
$etag = $resp->make_etag( $force_weak );
It returns the etag as a string.
=head2 max_age
Sets or gets the HTTP header field C<Access-Control-Max-Age>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age>
=head2 meets_conditions
Implements condition C<GET> rules for HTTP/1.1 specification. This function inspects the client headers and determines if the response fulfills the specified requirements.
$status = $resp->meets_conditions();
lib/Apache2/API/Response.pm view on Meta::CPAN
Parse the header, by calling L<Apache2::Response/send_cgi_header>
$resp->send_cgi_header( $buffer );
This method is really for back-compatibility with mod_perl 1.0. It is very inefficient to send headers this way, because of the parsing overhead.
If there is a response body following the headers it will be handled too (as if it was sent via L</print>).
Notice that if only HTTP headers are included they will not be sent until some body is sent (again the C<send> part is retained from the mod_perl 1.0 method).
See L<Apache2::Response> for more information.
=head2 sendfile
Provided with a file path, an optional offset and an optional length, and this will send a file or a part of it, by calling L<Apache2::RequestIO/sendfile>
$rc = $resp->sendfile( $filename );
$rc = $resp->sendfile( $filename, $offset );
$rc = $resp->sendfile( $filename, $offset, $len );
It returns a L<APR::Const> constant.
On success, L<APR::Const::SUCCESS> is returned.
In case of a failure, a failure code is returned, in which case normally it should be returned to the caller
=head2 server
Sets or gets the HTTP header field C<Server>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server>
=head2 server_timing
Sets or gets the HTTP header field C<Server-Timing>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing>
=head2 set_content_length
Set the content length for this request, by calling L<Apache2::Response/set_content_length>
$resp->set_content_length( $length );
It does not return any value.
=head2 set_cookie
Sets or gets the HTTP header field C<Set-Cookie>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie>
=head2 set_etag
$resp->set_etag;
Set automatically the C<E-tag> outgoing header.
It does not return any value.
=head2 set_keepalive
$ret = $resp->set_keepalive;
Returns the keepalive status for this request, by calling L<Apache2::Response/set_keepalive>
It returns true if keepalive can be set, false otherwise.
=head2 set_last_modified
Sets the C<Last-Modified> response header field to the value of the mtime field in the request structure, rationalized to keep it from being in the future, by calling L<Apache2::Response/set_last_modified>
$resp->set_last_modified( $mtime );
If the C<$mtime> argument is passed, C<< $resp->update_mtime >> will be first run with that argument.
=head2 socket
my $socket = $resp->socket;
my $prev_socket = $resp->socket( $new_socket );
Get or set the client socket and returns a L<APR::Socket> object, by calling L<Apache2::Connection/client_socket>
=head2 sourcemap
Sets or gets the HTTP header field C<SourceMap>
See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/SourceMap>
=head2 status
Get or set the reply status for the client request, 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 ...
$resp->status( $some_code );
return( Apache2::Const::OK );
See also C<< $resp->status_line >>, which. if set, overrides C<< $resp->status >>.
=head2 status_line
my $status_line = $resp->status_line();
my $prev_status_line = $resp->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<< $resp->status() >> described above.
According to the L<Apache2::RequestRec> documentation:
When discussing C<< $resp->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 ...
$resp->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:
$resp->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.
( run in 1.138 second using v1.01-cache-2.11-cpan-df04353d9ac )