The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Apache2::SSI::URI - Apache2 Server Side Include URI Object Class

SYNOPSIS

    # if the global option PerlOptions +GlobalRequest is set in your VirtualHost
    my $r = Apache2::RequestUtil->request
    my $uri = Apache2::SSI::URI->new(
        apache_request => $r,
        document_uri => '/some/uri/file.html',
        document_root => '/home/john/www',
        base_uri => '/',
    ) || die( "Unable to create an Apache2::SSI::URI object: ", Apache2::SSI::URI->error );

    unless( $uri->code == Apache2::Const::HTTP_OK )
    {
        die( "Sorry, the uri does not exist.\n" );
    }
    print( $uri->slurp_utf8 );

    # Changing the base uri, which is used to resolve relative uri
    $uri->base_uri( '/ssi' );

    my $uri2 = $uri->clone;
    $uri2->filename( '/home/john/some-file.txt' );
    die( "No such file\n" ) if( $uri2->finfo->filetype == Apache2::SSI::Finfo::FILETYPE_NOFILE );

    my $dir = $uri->document_directory;

    # Full path to the filename, e.g. /home/john/www/some/dir/file.html
    # Possible dots are resolved /home/john/www/some/dir/../ssi/../dir/./file.html => /home/john/www/some/dir/file.html
    my $filename = $uri->document_filename;

    # The uri without path info or query string
    my $path = $uri->document_path;

    my $doc_root = $uri->document_root;
    
    # The document uri including path info, and query string if any
    my $u = $uri->document_uri;

    my $req_uri = $uri->env( 'REQUEST_URI' );

    # Access to the Apache2::SSI::Finfo object
    my $finfo = $uri->finfo;

    # A new Apache2::SSI::URI object
    my $uri3 = $uri->new_uri( document_uri => '/some/where/about.html', document_root => '/home/john/www' );

    # Returns /some/uri
    my $parent = $uri->parent;

    # The uri is now /some/uri/file.html/some/path
    $uri->path_info( '/some/path' );

    # The uri is now /some/uri/file.html/some/path?q=something&l=ja_JP
    $uri->query_string( 'q=something&l=ja_JP' );

    my $html = $uri->slurp_utf8;
    my $raw = $uri->slurp({ binmode => ':raw' });

    # Same as $uri->document_uri
    my $uri = $uri->uri;

VERSION

    v0.1.0

DESCRIPTION

Apache2::SSI::URI is used to manipulate and query http uri. It is used by Apache2::SSI both for the main query, and also for sub queries like when there is an include directive.

In this case, there would be the main document uri such as /some/path/file.html and containing a directive such as:

    <!--#include virtual="../other.html" -->

An Apache2::SSI::URI object would be instantiated to process the uri ../other.html, flatten the dots and get its underlying filename.

Even if the uri provided does not exist, am Apache2::SSI::URI object would still be returned, so you need to check if the file exists by doing:

    if( $uri->code == 404 )
    {
        die( "Not there\n" );
    }

Or, this would work too:

    if( $uri->finfo->filetype == Apache2::SSI::Finfo::FILETYPE_NOFILE )
    {
        die( "No such file !\n" );
    }

METHODS

new

This instantiate an object that is used to access other key methods. It takes the following parameters:

apache_request

This is the Apache2::RequestRec object that is provided if running under mod_perl.

it can be retrieved from "request" in Apache2::RequestUtil or via "r" in Apache2::Filter

You can get this Apache2::RequestRec object by requiring Apache2::RequestUtil and calling its class method "request" in Apache2::RequestUtil such as Apache2::RequestUtil-request> and assuming you have set PerlOptions +GlobalRequest in your Apache Virtual Host configuration.

Note that there is a main request object and subprocess request object, so to find out which one you are dealing with, use "is_initial_req" in Apache2::RequestUtil, such as:

    use Apache2::RequestUtil (); # extends Apache2::RequestRec objects
    my $r = $r->is_initial_req ? $r : $r->main;
base_uri

This is the base uri which is used to make uri absolute.

For example, if the main document uri is /some/folder/file.html containing a directive:

    <!--#include virtual="../other.html" -->

One would instantiate an object using /some/folder/file.html as the base_uri like this:

    my $uri = Apache2::SSI::URI->new(
        base_uri => '/some/folder/file.html',
        apache_request => $r,
        document_uri => '../other.html',
        # No need to specify document_root, because it will be derived from 
        # the Apache2::RequestRec provided with the apache_request parameter.
    );
document_root

This is only necessary to be provided if this is not running under Apache mod_perl. Without this value, Apache2::SSI has no way to guess the document root and will not be able to function properly and will return an "error".

document_uri

This is only necessary to be provided if this is not running under Apache mod_perl. This must be the uri of the document being served, such as /my/path/index.html. So, if you are using this outside of the rim of Apache mod_perl and your file resides, for example, at /home/john/www/my/path/index.html and your document root is /home/john/www, then the document uri would be /my/path/index.html

apache_request

Sets or gets the Apache2::RequestRec object. As explained in the "new" method, you can get this Apache object by requiring the package Apache2::RequestUtil and calling "request" in Apache2::RequestUtil such as Apache2::RequestUtil-request> assuming you have set PerlOptions +GlobalRequest in your Apache Virtual Host configuration.

When running under Apache mod_perl this is set automatically from the special "handler" method, such as:

    my $r = $f->r; # $f is the Apache2::Filter object provided by Apache

base_uri

Sets or gets the base reference uri. This is used to render the "document_uri" provided an absolute uri.

clone

Create a clone of the object and return it.

code

Sets or gets the http code for this uri.

    $uri->code( 404 );

collapse_dots

Provided with an uri, and this will resolve the path and removing the dots, such as . and .. and return an URI object.

This is done as per the RFC 3986 section 5.2.4 algorithm

    my $uri = $ssi->collapse_dots( '/../a/b/../c/./d.html' );
    # would become /a/c/d.html
    my $uri = $ssi->collapse_dots( '/../a/b/../c/./d.html?foo=../bar' );
    # would become /a/c/d.html?foo=../bar
    $uri->query # foo=../bar

document_directory

Returns an Apache2::SSI::URI object of the current directory of the "document_uri" provided.

This can also be called as $uri-document_dir>

document_filename

This is an alias for "filename" in Apache2::SSI::URI

document_path

Sets or gets the uri path to the document. This is the same as "document_uri", except it is striped from "query_string" and "path_info".

document_root

Sets or gets the document root.

Wen running under Apache mod_perl, this value will be available automatically, using "document_root" in Apache2::RequestRec method.

If it runs outside of Apache, this will use the value provided upon instantiating the object and passing the document_root parameter. If this is not set, it will return the value of the environment variable DOCUMENT_ROOT.

document_uri

Sets or gets the document uri, which is the uri of the document being processed.

For example:

    /index.html

Under Apache, this will get the environment variable DOCUMENT_URI or calls the "uri" in Apache2::RequestRec method.

Outside of Apache, this will rely on a value being provided upon instantiating an object, or the environment variable DOCUMENT_URI be present.

The value should be an absolute uri.

env

Sets or gets environment variables that are distinct for this uri.

    $uri->env( REQUEST_URI => '/some/path/file.html' );
    my $loc = $uri->env( 'REQUEST_URI' );

If it is called without any parameters, it returns all the environment variables as a hash reference:

    my $all_env = $uri->env;
    print $all_env->{REQUEST_URI};

Setting an environment variable using "env" does not actually populate it. So this would not work:

    $uri->env( REQUEST_URI => '/some/path/file.html' );
    print( $ENV{REQUEST_URI};

It is the equivalent of "subprocess_env" in Apache2::RequestRec. Actually it uses "subprocess_env" in Apache2::RequestRec if running under Apache/mod_perl, other wise it uses a private hash reference to store the values.

filename

This returns the system file path to the document uri as a string.

finfo

Returns a Apache2::SSI::Finfo object. This provides access to "stat" in perlfunc information as method, taking advantage of APR::Finfo when running under Apache, and an identical interface otherwise. See Apache2::SSI::Finfo for more information.

new_uri

A short-hand for Apache2::SSI::URI-new>

parent

Returns the parent of the document uri, or if there is no parent, it returns the current object itself.

    my $up = $uri->parent;
    # would return /some/path assuming the document uri was /some/path/file.html

path_info

Sets or gets the path info for the current uri.

Example:

    my $string = $ssi->path_info;
    $ssi->path_info( '/my/path/info' );

The path info value is also set automatically when "document_uri" is called, such as:

    $ssi->document_uri( '/some/path/to/file.html/my/path/info?q=something&l=ja_JP' );

This will also set automatically the PATH_INFO environment variable.

query_string

Set or gets the query string for the current uri.

Example:

    my $string = $ssi->query_string;
    $ssi->query_string( 'q=something&l=ja_JP' );

or, using the URI module:

    $ssi->query_string( $uri->query );

The query string value is set automatically when you provide an document_uri upon instantiation or after:

    $ssi->document_uri( '/some/path/to/file.html?q=something&l=ja_JP' );

This will also set automatically the QUERY_STRING environment variable.

root

Returns an object representation of the root uri, i.e. /

slurp

It returns the content of the "filename"

it takes an hash reference of parameters:

binmode
    my $content = $uri->slurp({ binmode => ':utf-8' });

It will return undef and sets an "error" in Module::Generic if there is no "filename" value set or if the file cannot be opened.

slurp_utf8

It returns the content of the file "filename" utf-8 decoded.

This is equivalent to:

    my $content = $uri->slurp({ binmode => ':utf8' });

:utf8 is slightly a bit more lax than :utf-8, so it you want strict utf8, you can do:

    my $content = $uri->slurp({ binmode => ':utf-8' });

AUTHOR

Jacques Deguest <jack@deguest.jp>

CPAN ID: jdeguest

https://git.deguest.jp/jack/Apache2-SSI

SEE ALSO

Apache2::SSI::File, Apache2::SSI::Finfo, Apache2::SSI

mod_include, mod_perl(3), APR::URI, URI https://httpd.apache.org/docs/current/en/mod/mod_include.html, https://httpd.apache.org/docs/current/en/howto/ssi.html, https://httpd.apache.org/docs/current/en/expr.html https://perl.apache.org/docs/2.0/user/handlers/filters.html#C_PerlOutputFilterHandler_

COPYRIGHT & LICENSE

Copyright (c) 2020-2021 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.