Apache2-SSI

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

            "version" : "0",
            "warnings" : "0"
         }
      },
      "test" : {
         "requires" : {
            "Cwd" : "0",
            "Test::More" : "1.302162",
            "Test::Pod" : "1.52",
            "lib" : "0",
            "utf8" : "0"
         }
      }
   },
   "release_status" : "stable",
   "resources" : {
      "bugtracker" : {
         "web" : "https://gitlab.com/jackdeguest/Apache2-SSI/issues"
      },
      "repository" : {
         "type" : "git",

META.yml  view on Meta::CPAN

---
abstract: 'Apache2 Server Side Include'
author:
  - 'Jacques Deguest (jack@deguest.jp)'
build_requires:
  Cwd: '0'
  ExtUtils::MakeMaker: '0'
  Test::More: '1.302162'
  Test::Pod: '1.52'
  lib: '0'
  utf8: '0'
configure_requires:
  ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010'
license: perl
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: '1.4'
name: Apache2-SSI
no_index:

Makefile.PL  view on Meta::CPAN

        'URI::file'     => '5.05',
        'URI::Escape::XS' => 0,
        'URL::Encode::XS' => 0,
    },
    TEST_REQUIRES =>
    {
        'Cwd'           => 0,
        'lib'           => 0,
        'Test::More'    => '1.302162',
        'Test::Pod'     => '1.52',
        'utf8'          => 0,
    },
    LICENSE             => 'perl_5',
    MIN_PERL_VERSION    => 'v5.22.1',
    (MM->can('signature_target') ? (SIGN => 1) : ()),
    dist                => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', DIST_CP => 'cp' },
    clean               => { FILES => 'Apache2-SSI-*' },
    ( eval { ExtUtils::MakeMaker->VERSION(6.46) } ? ( META_MERGE => {
        'meta-spec' => { version => 2 },
        dynamic_config => 1,
        resources => {

README  view on Meta::CPAN


        use Apache2::SSI;
        my $ssi = Apache2::SSI->new(
            ## If running outside of Apache
            document_root => '/path/to/base/directory'
            ## Default error message to display when ssi failed to parse
            ## Default to [an error occurred while processing this directive]
            errmsg => '[Oops]'
        );
        my $fh = IO::File->new( "</some/file.html" ) || die( "$!\n" );
        $fh->binmode( ':utf8' );
        my $size = -s( $fh );
        my $html;
        $fh->read( $html, $size );
        $fh->close;
        if( !defined( my $result = $ssi->parse( $html ) ) )
        {
            $ssi->throw;
        };
        print( $result );

README  view on Meta::CPAN

    See also "apache_filter_handler"

  clone
    Create a clone of the object and return it.

  decode_base64
    Decode base64 data provided. When running under Apache mod_perl, this
    uses "decode" in APR::Base64 module, otherwise it uses "decode" in
    MIME::Base64

    If the decoded data contain utf8 data, this will decoded the utf8 data
    using "decode" in Encode

    If an error occurred during decoding, it will return undef and set an
    "error" object accordingly.

  decode_entities
    Decode html data containing entities. This uses "decode_entities" in
    HTML::Entities

    If an error occurred during decoding, it will return undef and set an

README  view on Meta::CPAN

    "error" object accordingly.

    Example:

        $ssi->decode_uri( 'https%3A%2F%2Fwww.example.com%2F' );
        # https://www.example.com/

  decode_url
    Decode x-www-form-urlencoded encoded data. When using Apache mod_perl,
    this uses "decode" in APR::Request and "decode" in Encode, otherwise it
    uses "url_decode_utf8" in URL::Encode (its XS version) to achieve the
    same result.

    If an error occurred during decoding, it will return undef and set an
    "error" object accordingly.

    Example:

        $ssi->decode_url( 'Tous+les+%C3%83%C2%AAtres+humains+naissent+libres+et+%C3%83%C2%A9gaux+en+dignit%C3%83%C2%A9+et+en+droits.' );
        # Tous les êtres humains naissent libres et égaux en dignité et en droits.

README  view on Meta::CPAN


    would produce:

        [Value Undefined]

  encode_base64
    Encode data provided into base64. When running under Apache mod_perl,
    this uses "encode" in APR::Base64 module, otherwise it uses "encode" in
    MIME::Base64

    If the data have the perl internal utf8 flag on as checked with
    "is_utf8" in Encode, this will encode the data into utf8 using "encode"
    in Encode before encoding it into base64.

    Please note that the base64 encoded resulting data is all on one line,
    similar to what Apache would do. The data is NOT broken into lines of 76
    characters.

    If an error occurred during encoding, it will return undef and set an
    "error" object accordingly.

  encode_entities

README  view on Meta::CPAN


    If an error occurred during encoding, it will return undef and set an
    "error" object accordingly.

    Example:

        $ssi->encode_entities( 'Tous les êtres humains naissent libres et égaux en dignité et en droits.' );
        # Tous les &Atilde;&ordf;tres humains naissent libres et &Atilde;&copy;gaux en dignit&Atilde;&copy; et en droits.

  encode_uri
    Encode uri data. This uses "uri_escape_utf8" in URI::Escape.

    Not to be confused with x-www-form-urlencoded data. For that see
    "encode_url"

    If an error occurred during encoding, it will return undef and set an
    "error" object accordingly.

    Example:

        $ssi->encode_uri( 'https://www.example.com/' );
        # https%3A%2F%2Fwww.example.com%2F

  encode_url
    Encode data provided into an x-www-form-urlencoded string. When using
    Apache mod_perl, this uses "encode" in APR::Request, otherwise it uses
    "url_encode_utf8" in URL::Encode (its XS version)

    If an error occurred during decoding, it will return undef and set an
    "error" object accordingly.

    Example:

        $ssi->encode_url( 'Tous les êtres humains naissent libres et égaux en dignité et en droits.' );
        # Tous+les+%C3%83%C2%AAtres+humains+naissent+libres+et+%C3%83%C2%A9gaux+en+dignit%C3%83%C2%A9+et+en+droits.

  env

README  view on Meta::CPAN


    This file size is 13,316,917 bytes

    The size value before formatting is a Module::Generic::Number and the
    output is formatted using Number::Format by calling "format" in
    Module::Generic::Number

  parse_func_base64
    Returns the arguments provided into a base64 string.

    If the arguments are utf8 data with perl internal flag on, as checked
    with "is_utf8" in Encode, this will encode the data into utf8 with
    "encode" in Encode before encoding it into base64.

    Example:

        <!--#set var="payload" value='{"sub":"1234567890","name":"John Doe","iat":1609047546}' encoding="base64" -->
        <!--#if expr="$payload == 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjA5MDQ3NTQ2fQo='" -->
        Payload matches
        <!--#else -->
        Sorry, this failed
        <!--#endif -->

README  view on Meta::CPAN


    Example:

        <!--#set var="phrase" value="%{ldap:'Tous les êtres humains naissent libres (et égaux) en dignité et\ en\ droits.\n'}" -->
        # Tous les êtres humains naissent libres \28et égaux\29 en dignité et\5c en\5c droits.\5cn

  parse_func_md5
    Hash the string using MD5, then encode the hash with hexadecimal
    encoding.

    If the arguments are utf8 data with perl internal flag on, as checked
    with "is_utf8" in Encode, this will encode the data into utf8 with
    "encode" in Encode before encoding it with md5.

    Example:

        <!--#if expr="md5( $hash_data ) == '2f50e645b6ef04b5cfb76aed6de343eb'" -->
        You're good to go.
        <!--#endif -->

  parse_func_note
    Lookup request note

README  view on Meta::CPAN

  parse_include
    Provided with an hash reference of parameters and this process the ssi
    directive "include", which is arguably the most used.

    It will try to resolve the file to include by calling "find_file" with
    the same arguments this is called with.

    Under Apache, if the previous look up succeeded, it calls "run" in
    Apache2::SubRequest

    Outside of Apache, it reads the entire file, utf8 decode it and return
    it.

  parse_perl
    Provided with an hash reference of parameters and this parse some perl
    command and returns the output as a string.

    Example:

        <!--#perl sub="sub{ print 'Hello!' }" -->

README  view on Meta::CPAN


  sizefmt
    Sets or gets the formatting for file sizes. Value can be either "bytes"
    or "abbrev"

  timefmt
    Sets or gets the formatting for date and time values. The format takes
    the same values as "strftime" in POSIX

Encoding
    At present time, the html data are treated as utf8 data and decoded and
    encoded back as such.

    If there is a need to broaden support for other charsets, let me know.

SSI Directives
    This is taken from Apache documentation and summarised here for
    convenience and clarity to the perl community.

  config
        <!--#config errmsg="Error occurred" sizefmt="abbrev" timefmt="%B %Y" -->

README.md  view on Meta::CPAN


        use Apache2::SSI;
        my $ssi = Apache2::SSI->new(
            ## If running outside of Apache
            document_root => '/path/to/base/directory'
            ## Default error message to display when ssi failed to parse
            ## Default to [an error occurred while processing this directive]
            errmsg => '[Oops]'
        );
        my $fh = IO::File->new( "</some/file.html" ) || die( "$!\n" );
        $fh->binmode( ':utf8' );
        my $size = -s( $fh );
        my $html;
        $fh->read( $html, $size );
        $fh->close;
        if( !defined( my $result = $ssi->parse( $html ) ) )
        {
            $ssi->throw;
        };
        print( $result );

README.md  view on Meta::CPAN


decode\_base64
--------------

Decode base64 data provided. When running under Apache mod\_perl, this
uses [\"decode\" in
APR::Base64](https://metacpan.org/pod/APR::Base64#decode){.perl-module}
module, otherwise it uses [\"decode\" in
MIME::Base64](https://metacpan.org/pod/MIME::Base64#decode){.perl-module}

If the decoded data contain utf8 data, this will decoded the utf8 data
using [\"decode\" in
Encode](https://metacpan.org/pod/Encode#decode){.perl-module}

If an error occurred during decoding, it will return undef and set an
[\"error\"](#error){.perl-module} object accordingly.

decode\_entities
----------------

Decode html data containing entities. This uses [\"decode\_entities\" in

README.md  view on Meta::CPAN

        # https://www.example.com/

decode\_url
-----------

Decode x-www-form-urlencoded encoded data. When using Apache mod\_perl,
this uses [\"decode\" in
APR::Request](https://metacpan.org/pod/APR::Request#decode){.perl-module}
and [\"decode\" in
Encode](https://metacpan.org/pod/Encode#decode){.perl-module}, otherwise
it uses [\"url\_decode\_utf8\" in
URL::Encode](https://metacpan.org/pod/URL::Encode#url_decode_utf8){.perl-module}
(its XS version) to achieve the same result.

If an error occurred during decoding, it will return undef and set an
[\"error\"](#error){.perl-module} object accordingly.

Example:

        $ssi->decode_url( 'Tous+les+%C3%83%C2%AAtres+humains+naissent+libres+et+%C3%83%C2%A9gaux+en+dignit%C3%83%C2%A9+et+en+droits.' );
        # Tous les êtres humains naissent libres et égaux en dignité et en droits.

README.md  view on Meta::CPAN


encode\_base64
--------------

Encode data provided into base64. When running under Apache mod\_perl,
this uses [\"encode\" in
APR::Base64](https://metacpan.org/pod/APR::Base64#encode){.perl-module}
module, otherwise it uses [\"encode\" in
MIME::Base64](https://metacpan.org/pod/MIME::Base64#encode){.perl-module}

If the data have the perl internal utf8 flag on as checked with
[\"is\_utf8\" in
Encode](https://metacpan.org/pod/Encode#is_utf8){.perl-module}, this
will encode the data into utf8 using [\"encode\" in
Encode](https://metacpan.org/pod/Encode#encode){.perl-module} before
encoding it into base64.

Please note that the base64 encoded resulting data is all on one line,
similar to what Apache would do. The data is **NOT** broken into lines
of 76 characters.

If an error occurred during encoding, it will return undef and set an
[\"error\"](#error){.perl-module} object accordingly.

README.md  view on Meta::CPAN

[\"error\"](#error){.perl-module} object accordingly.

Example:

        $ssi->encode_entities( 'Tous les êtres humains naissent libres et égaux en dignité et en droits.' );
        # Tous les &Atilde;&ordf;tres humains naissent libres et &Atilde;&copy;gaux en dignit&Atilde;&copy; et en droits.

encode\_uri
-----------

Encode uri data. This uses [\"uri\_escape\_utf8\" in
URI::Escape](https://metacpan.org/pod/URI::Escape#uri_escape_utf8){.perl-module}.

Not to be confused with x-www-form-urlencoded data. For that see
[\"encode\_url\"](#encode_url){.perl-module}

If an error occurred during encoding, it will return undef and set an
[\"error\"](#error){.perl-module} object accordingly.

Example:

        $ssi->encode_uri( 'https://www.example.com/' );
        # https%3A%2F%2Fwww.example.com%2F

encode\_url
-----------

Encode data provided into an x-www-form-urlencoded string. When using
Apache mod\_perl, this uses [\"encode\" in
APR::Request](https://metacpan.org/pod/APR::Request#encode){.perl-module},
otherwise it uses [\"url\_encode\_utf8\" in
URL::Encode](https://metacpan.org/pod/URL::Encode#url_encode_utf8){.perl-module}
(its XS version)

If an error occurred during decoding, it will return undef and set an
[\"error\"](#error){.perl-module} object accordingly.

Example:

        $ssi->encode_url( 'Tous les êtres humains naissent libres et égaux en dignité et en droits.' );
        # Tous+les+%C3%83%C2%AAtres+humains+naissent+libres+et+%C3%83%C2%A9gaux+en+dignit%C3%83%C2%A9+et+en+droits.

README.md  view on Meta::CPAN

and the output is formatted using
[Number::Format](https://metacpan.org/pod/Number::Format){.perl-module}
by calling [\"format\" in
Module::Generic::Number](https://metacpan.org/pod/Module::Generic::Number#format){.perl-module}

parse\_func\_base64
-------------------

Returns the arguments provided into a base64 string.

If the arguments are utf8 data with perl internal flag on, as checked
with [\"is\_utf8\" in
Encode](https://metacpan.org/pod/Encode#is_utf8){.perl-module}, this
will encode the data into utf8 with [\"encode\" in
Encode](https://metacpan.org/pod/Encode#encode){.perl-module} before
encoding it into base64.

Example:

        <!--#set var="payload" value='{"sub":"1234567890","name":"John Doe","iat":1609047546}' encoding="base64" -->
        <!--#if expr="$payload == 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjA5MDQ3NTQ2fQo='" -->
        Payload matches
        <!--#else -->
        Sorry, this failed

README.md  view on Meta::CPAN


        <!--#set var="phrase" value="%{ldap:'Tous les êtres humains naissent libres (et égaux) en dignité et\ en\ droits.\n'}" -->
        # Tous les êtres humains naissent libres \28et égaux\29 en dignité et\5c en\5c droits.\5cn

parse\_func\_md5
----------------

Hash the string using MD5, then encode the hash with hexadecimal
encoding.

If the arguments are utf8 data with perl internal flag on, as checked
with [\"is\_utf8\" in
Encode](https://metacpan.org/pod/Encode#is_utf8){.perl-module}, this
will encode the data into utf8 with [\"encode\" in
Encode](https://metacpan.org/pod/Encode#encode){.perl-module} before
encoding it with md5.

Example:

        <!--#if expr="md5( $hash_data ) == '2f50e645b6ef04b5cfb76aed6de343eb'" -->
        You're good to go.
        <!--#endif -->

parse\_func\_note

README.md  view on Meta::CPAN

Provided with an hash reference of parameters and this process the ssi
directive `include`, which is arguably the most used.

It will try to resolve the file to include by calling
[\"find\_file\"](#find_file){.perl-module} with the same arguments this
is called with.

Under Apache, if the previous look up succeeded, it calls [\"run\" in
Apache2::SubRequest](https://metacpan.org/pod/Apache2::SubRequest#run){.perl-module}

Outside of Apache, it reads the entire file, utf8 decode it and return
it.

parse\_perl
-----------

Provided with an hash reference of parameters and this parse some perl
command and returns the output as a string.

Example:

README.md  view on Meta::CPAN

timefmt
-------

Sets or gets the formatting for date and time values. The format takes
the same values as [\"strftime\" in
POSIX](https://metacpan.org/pod/POSIX#strftime){.perl-module}

Encoding
========

At present time, the html data are treated as utf8 data and decoded and
encoded back as such.

If there is a need to broaden support for other charsets, let me know.

SSI Directives
==============

This is taken from Apache documentation and summarised here for
convenience and clarity to the perl community.

lib/Apache2/SSI.pm  view on Meta::CPAN

        return( &Apache2::Const::DECLINED );
    }
    my $file = $u->filename;
    my $max_length = int( $r->dir_config( 'Apache2_SSI_Max_Length' ) ) || 0;
    if( -s( $file ) >= $max_length )
    {
        $r->log->error( "HTML data exceeds our size threshold of $max_length. Rejecting the request." );
        $r->status( &Apache2::Const::HTTP_REQUEST_ENTITY_TOO_LARGE );
        return( &Apache2::Const::OK );
    }
    my $html = $u->slurp_utf8;
    if( !length( $html ) )
    {
        $r->status( &Apache2::Const::HTTP_NO_CONTENT );
        return( &Apache2::Const::OK );
    }
    
    # my $addr = $r->useragent_addr;
    my $res = $self->parse( $html );
    if( !defined( $res ) )
    {
        $r->log->error( "${class} is unable to process data: ", $self->error );
        return( &Apache2::Const::DECLINED );
    }
    else
    {
        local $@;
        # try-catch
        $res = eval
        {
            Encode::encode( 'utf8', $res, Encode::FB_CROAK );
        };
        if( $@ )
        {
            $r->log->error( "${class} encountered an error while trying to encode data into utf8: $@" );
            return( &Apache2::Const::DECLINED );
        }
        
        my $len = length( $res );
        # try-catch
        eval
        {
            $r->headers_out->set( 'Content-Length' => $len );
            my $sent = $r->print( $res );
        };

lib/Apache2/SSI.pm  view on Meta::CPAN

    if( $size == 0 )
    {
        $r->log->debug( "${class} [PerlOutputFilterHandler]: Data received is empty. Nothing to do." );
        return( &Apache2::Const::OK );
    }

    local $@;
    # try-catch
    $html = eval
    {
        Encode::decode( 'utf8', $html, Encode::FB_CROAK );
    };
    if( $@ )
    {
        $r->log->error( "${class} [PerlOutputFilterHandler]: Failed to decode data from utf8: $@" );
        return( &Apache2::Const::DECLINED );
    }
    
    #W We just add that the charset is utf-8
    $main->content_type( 'text/html; charset=utf-8' ) unless( $main->content_type =~ /\bcharset\n/i );
    
    my $params =
    {
    apache_filter => $f,
    apache_request => $r,

lib/Apache2/SSI.pm  view on Meta::CPAN

    if( !defined( $res ) )
    {
        $r->log->error( "${class} [PerlOutputFilterHandler]: is unable to process data: ", $self->error );
        return( &Apache2::Const::DECLINED );
    }
    else
    {
        # try-catch
        $res = eval
        {
            Encode::encode( 'utf8', $res, Encode::FB_CROAK );
        };
        if( $@ )
        {
            $r->log->error( "${class} [PerlOutputFilterHandler]: encountered an error while trying to encode data into utf8: $@" );
            return( &Apache2::Const::DECLINED );
        }
        
        # $r->headers_out->unset( 'Content-Length' );
        my $len = length( $res );
        # try-catch
        eval
        {
            $r->headers_out->set( 'Content-Length' => $len );
            my $sent = $f->print( "$res" );

lib/Apache2/SSI.pm  view on Meta::CPAN

        my $v = join( '', @_ );
        if( $self->mod_perl )
        {
            $v = APR::Base64::decode( $v );
        }
        else
        {
            require MIME::Base64;
            $v = MIME::Base64::decode( $v );
        }
        $v = Encode::decode( 'utf8', $v ) if( $self->_has_utf8( $v ) );
        return( $v );
    };
    if( $@ )
    {
        return( $self->error( "Error while decoding base64 data: $@" ) );
    }
    return( $rv );
}

sub decode_entities

lib/Apache2/SSI.pm  view on Meta::CPAN


sub decode_url
{
    my $self = shift( @_ );
    local $@;
    # try-catch
    my $rv = eval
    {
        if( $self->mod_perl )
        {
            return( Encode::decode( 'utf8', APR::Request::decode( @_ ), Encode::FB_CROAK ) );
        }
        else
        {
            # Will use XS version automatically
            require URL::Encode;
            return( URL::Encode::url_decode_utf8( @_ ) );
        }
    };
    if( $@ )
    {
        return( $self->error( "Error while url decoding data: $@" ) );
    }
    return( $rv );
}

sub document_filename { return( shift->uri->filename( @_ ) ); }

lib/Apache2/SSI.pm  view on Meta::CPAN

sub echomsg { return( shift->_set_get_scalar( 'echomsg', @_ ) ); }

sub encode_base64
{
    my $self = shift( @_ );
    local $@;
    # try-catch
    my $rv = eval
    {
        my $v = join( '', @_ );
        $v = Encode::encode( 'utf8', $v, Encode::FB_CROAK ) if( Encode::is_utf8( $v ) );
        if( $self->mod_perl )
        {
            return( APR::Base64::encode( $v ) );
        }
        else
        {
            require MIME::Base64;
            return( MIME::Base64::encode( $v, '' ) );
        }
    };

lib/Apache2/SSI.pm  view on Meta::CPAN


sub encode_md5
{
    my $self = shift( @_ );
    local $@;
    # try-catch
    my $rv = eval
    {
        require Digest::MD5;
        my $v = join( '', @_ );
        $v = Encode::encode( 'utf8', $v, Encode::FB_CROAK ) if( Encode::is_utf8( $v ) );
        return( Digest::MD5::md5_hex( $v ) );
    };
    if( $@ )
    {
        return( $self->error( "Error while encoding data into md5 hex: $@" ) );
    }
    return( $rv );
}

sub encode_uri
{
    my $self = shift( @_ );
    local $@;
    # try-catch
    my $rv = eval
    {
        require URI::Escape::XS;
        # return( URI::Escape::uri_escape_utf8( join( '', @_ ) ) );
        return( URI::Escape::XS::uri_escape( join( '', @_ ) ) );
    };
    if( $@ )
    {
        return( $self->error( "Error while encoding uri: $@" ) );
    }
    return( $rv );
}

sub encode_url
{
    my $self = shift( @_ );
    local $@;
    # try-catch
    my $rv = eval
    {
        if( $self->mod_perl )
        {
            my $v = Encode::encode( 'utf8', join( '', @_ ), Encode::FB_CROAK );
            return( APR::Request::encode( $v ) );
        }
        else
        {
            # Will use XS version automatically
            require URL::Encode;
            return( URL::Encode::url_encode_utf8( join( '', @_ ) ) );
        }
    };
    if( $@ )
    {
        return( $self->error( "Error while url encoding data: $@" ) );
    }
    return( $rv );
}

sub env

lib/Apache2/SSI.pm  view on Meta::CPAN

    unless( $f->code == 200 )
    {
        return( $self->errmsg );
    }
    my $filename = $f->filename;
    if( !-e( "$filename" ) )
    {
        return( $self->errmsg );
    }
    
    # TODO This needs to be improved, as we should not assume the file encoding is utf8
    # It could be binary or some other text encoding like iso-2022-jp
    # So we should slurp it, parse the meta tags if this is an html and decode if the charset attribute is set or default to utf8
    # But this complicates things quite a bit, so for now, it is just utf8 simply
    my $html = $f->slurp_utf8;
    if( !defined( $html ) )
    {
        $self->error( "Unable to get html data of included file \"", $f->filename, "\": ", $f->error );
        return( $self->errmsg );
    }
    my $clone = $self->clone || do
    {
        warn( $self->error );
        return( $self->errmsg );
    };

lib/Apache2/SSI.pm  view on Meta::CPAN

    {
        $self->{suspend}->[0] = 1;
    }
    else
    {
        $self->{suspend}->[0] = !( $self->{if_state}->[0] = !!$cond );
    }
    return( '' );
}

sub _has_utf8
{
    my $self = shift( @_ );
    return( $_[0] =~ /$IS_UTF8/ );
}

sub _interp_vars
{
    # Find all $var and ${var} expressions in the string and fill them in.
    my $self = shift( @_ );
    # Because ssi_echo may change $1, $2, ...

lib/Apache2/SSI.pm  view on Meta::CPAN


    use Apache2::SSI;
    my $ssi = Apache2::SSI->new(
        # If running outside of Apache
        document_root => '/path/to/base/directory'
        # Default error message to display when ssi failed to parse
        # Default to [an error occurred while processing this directive]
        errmsg => '[Oops]'
    );
    my $fh = IO::File->new( "</some/file.html" ) || die( "$!\n" );
    $fh->binmode( ':utf8' );
    my $size = -s( $fh );
    my $html;
    $fh->read( $html, $size );
    $fh->close;
    if( !defined( my $result = $ssi->parse( $html ) ) )
    {
        $ssi->throw;
    };
    print( $result );

lib/Apache2/SSI.pm  view on Meta::CPAN

See also L</apache_filter_handler>

=head2 clone

Create a clone of the object and return it.

=head2 decode_base64

Decode base64 data provided. When running under Apache mod_perl, this uses L<APR::Base64/decode> module, otherwise it uses L<MIME::Base64/decode>

If the decoded data contain utf8 data, this will decode the utf8 data using L<Encode/decode>

If an error occurred during decoding, it will return undef and set an L</error> object accordingly.

=head2 decode_entities

Decode html data containing entities. This uses L<HTML::Entities/decode_entities>

If an error occurred during decoding, it will return undef and set an L</error> object accordingly.

Example:

lib/Apache2/SSI.pm  view on Meta::CPAN


If an error occurred during decoding, it will return undef and set an L</error> object accordingly.

Example:

    $ssi->decode_uri( 'https%3A%2F%2Fwww.example.com%2F' );
    # https://www.example.com/

=head2 decode_url

Decode x-www-form-urlencoded encoded data. When using Apache mod_perl, this uses L<APR::Request/decode> and L<Encode/decode>, otherwise it uses L<URL::Encode/url_decode_utf8> (its XS version) to achieve the same result.

If an error occurred during decoding, it will return undef and set an L</error> object accordingly.

Example:

    $ssi->decode_url( 'Tous+les+%C3%83%C2%AAtres+humains+naissent+libres+et+%C3%83%C2%A9gaux+en+dignit%C3%83%C2%A9+et+en+droits.' );
    # Tous les êtres humains naissent libres et égaux en dignité et en droits.

=head2 document_filename

lib/Apache2/SSI.pm  view on Meta::CPAN

    <!--#echo var="NON_EXISTING" encoding="none" -->

would produce:

    [Value Undefined]

=head2 encode_base64

Encode data provided into base64. When running under Apache mod_perl, this uses L<APR::Base64/encode> module, otherwise it uses L<MIME::Base64/encode>

If the data have the perl internal utf8 flag on as checked with L<Encode/is_utf8>, this will encode the data into utf8 using L<Encode/encode> before encoding it into base64.

Please note that the base64 encoded resulting data is all on one line, similar to what Apache would do. The data is B<NOT> broken into lines of 76 characters.

If an error occurred during encoding, it will return undef and set an L</error> object accordingly.

=head2 encode_entities

Encode data into html entities. This uses L<HTML::Entities/encode_entities>

If an error occurred during encoding, it will return undef and set an L</error> object accordingly.

lib/Apache2/SSI.pm  view on Meta::CPAN


If an error occurred during encoding, it will return undef and set an L</error> object accordingly.

Example:

    $ssi->encode_uri( 'https://www.example.com/' );
    # https%3A%2F%2Fwww.example.com%2F

=head2 encode_url

Encode data provided into an x-www-form-urlencoded string. When using Apache mod_perl, this uses L<APR::Request/encode>, otherwise it uses L<URL::Encode/url_encode_utf8> (its XS version)

If an error occurred during decoding, it will return undef and set an L</error> object accordingly.

Example:

    $ssi->encode_url( 'Tous les êtres humains naissent libres et égaux en dignité et en droits.' );
    # Tous+les+%C3%83%C2%AAtres+humains+naissent+libres+et+%C3%83%C2%A9gaux+en+dignit%C3%83%C2%A9+et+en+droits.

=head2 env

lib/Apache2/SSI.pm  view on Meta::CPAN

would return:

This file size is 13,316,917 bytes

The size value before formatting is a L<Module::Generic::Number> and the output is formatted using L<Number::Format> by calling L<Module::Generic::Number/format>

=head2 parse_func_base64

Returns the arguments provided into a base64 string.

If the arguments are utf8 data with perl internal flag on, as checked with L<Encode/is_utf8>, this will encode the data into utf8 with L<Encode/encode> before encoding it into base64.

Example:

    <!--#set var="payload" value='{"sub":"1234567890","name":"John Doe","iat":1609047546}' encoding="base64" -->
    <!--#if expr="$payload == 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjA5MDQ3NTQ2fQo='" -->
    Payload matches
    <!--#else -->
    Sorry, this failed
    <!--#endif -->

lib/Apache2/SSI.pm  view on Meta::CPAN


Example:

    <!--#set var="phrase" value="%{ldap:'Tous les êtres humains naissent libres (et égaux) en dignité et\ en\ droits.\n'}" -->
    # Tous les êtres humains naissent libres \28et égaux\29 en dignité et\5c en\5c droits.\5cn

=head2 parse_func_md5

Hash the string using MD5, then encode the hash with hexadecimal encoding.

If the arguments are utf8 data with perl internal flag on, as checked with L<Encode/is_utf8>, this will encode the data into utf8 with L<Encode/encode> before encoding it with md5.

Example:

    <!--#if expr="md5( $hash_data ) == '2f50e645b6ef04b5cfb76aed6de343eb'" -->
    You're good to go.
    <!--#endif -->

=head2 parse_func_note

Lookup request note

lib/Apache2/SSI.pm  view on Meta::CPAN

See L</parse_elif> above for example.

=head2 parse_include

Provided with an hash reference of parameters and this process the ssi directive C<include>, which is arguably the most used.

It will try to resolve the file to include by calling L</find_file> with the same arguments this is called with.

Under Apache, if the previous look up succeeded, it calls L<Apache2::SubRequest/run>

Outside of Apache, it reads the entire file, utf8 decode it and return it.

=head2 parse_perl

Provided with an hash reference of parameters and this parse some perl command and returns the output as a string.

Example:

    <!--#perl sub="sub{ print 'Hello!' }" -->

or

lib/Apache2/SSI.pm  view on Meta::CPAN

=head2 sizefmt

Sets or gets the formatting for file sizes. Value can be either C<bytes> or C<abbrev>

=head2 timefmt

Sets or gets the formatting for date and time values. The format takes the same values as L<POSIX/strftime>

=head1 Encoding

At present time, the html data are treated as utf8 data and decoded and encoded back as such.

If there is a need to broaden support for other charsets, let me know.

=head1 SSI Directives

This is taken from Apache documentation and summarised here for convenience and clarity to the perl community.

=head2 config

    <!--#config errmsg="Error occurred" sizefmt="abbrev" timefmt="%B %Y" -->

lib/Apache2/SSI/Common.pm  view on Meta::CPAN

            return( scalar( <$fh> ) );
        }
    };
    if( $@ )
    {
        return( $self->error( "An error occured while trying to open and read file \"$file\": $@" ) );
    }
    return( $rv );
}

sub slurp_utf8
{
    my $self = shift( @_ );
    my $args = {};
    no warnings 'uninitialized';
    $args = Scalar::Util::reftype( $_[0] ) eq 'HASH'
        ? shift( @_ )
        : !( scalar( @_ ) % 2 )
            ? { @_ }
            : {};
    $args->{binmode} = ':utf8';
    my $file = $args->{filename} || $args->{file} || $self->filename;
    return( $self->error( "No filename found." ) ) if( !length( $file ) );
    $args->{filename} = $file;
    return( $self->slurp( $args ) );
}


1;
# NOTE: POD
__END__

lib/Apache2/SSI/Common.pm  view on Meta::CPAN

=over 4

=item I<binmode>

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

=back

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

=head2 slurp_utf8

It returns the content of the file L</filename> utf-8 decoded.

This is equivalent to:

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

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

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

=head1 AUTHOR

Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>

CPAN ID: jdeguest

L<https://gitlab.com/jackdeguest/Apache2-SSI>

lib/Apache2/SSI/File.pm  view on Meta::CPAN

=over 4

=item C<binmode>

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

=back

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

=head2 slurp_utf8

It returns the content of the file L</filename> utf-8 decoded.

This is equivalent to:

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

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

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

=head1 AUTHOR

Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>

CPAN ID: jdeguest

L<https://gitlab.com/jackdeguest/Apache2-SSI>

lib/Apache2/SSI/File/Type.json  view on Meta::CPAN

      "model/vrml",
      []
   ],
   [
      0,
      0,
      15,
      "string",
      null,
      "=",
      "#VRML V2.0 utf8",
      null,
      "model/vrml",
      []
   ],
   [
      0,
      0,
      3,
      "string",
      null,

lib/Apache2/SSI/Notes.pm  view on Meta::CPAN

    ) || die( Apache2::SSI::Notes->error );
    
    $notes->add( key => $val );
    
    $notes->clear;
    
    $notes->do(sub
    {
        # $_[0] = key
        # $_[1] = value
        $_[1] = Encode::decode( 'utf8', $_[1] );
    });
    
    # Or specify the keys to check
    $notes->do(sub
    {
        # $_[0] = key
        # $_[1] = value
        $_[1] = Encode::decode( 'utf8', $_[1] );
    }, qw( first_name last_name location ) );

    my $val = $notes-get( 'name' );

    # Get all as an hash reference
    my $hashref = $notes->get;

    $notes->set( name => 'John Doe' );

    # remove entry. This is different from $notes->set( name => undef() );

lib/Apache2/SSI/Notes.pm  view on Meta::CPAN


Provided with a callback as a code reference, and optionally an array of keys, and this will loop through all keys or the given keys if any, and call the callback passing it the key and its value.

For example:

    $notes->do(sub
    {
        my( $n, $v ) = @_;
        if( $n =~ /name/ )
        {
            $_[1] = Encode::decode( 'utf8', $_[1] );
        }
    });

=head2 get

Provided with a key and this retrieve its corresponding value, whatever that may be.

    my $val = $notes->get( 'name' );

If no key is provided, it returns all the notes as an hash reference.

lib/Apache2/SSI/SharedMem.pm  view on Meta::CPAN

            return( $self->error( "Unable to read data from shared memory address \"$addr\" using memread: $!" ) );
    }
    else
    {
        shmread( $id, $buffer, 0, $size ) ||
            return( $self->error( "Unable to read data from shared memory id \"$id\": $!" ) );
    }
    # Get rid of nulls end padded
    $buffer = unpack( "A*", $buffer );
    my $first_char = substr( $buffer, 0, 1 );
    my $j = JSON->new->utf8->relaxed->allow_nonref;
    my $data;
    local $@;
    # try-catch
    eval
    {
        # Does the value have any typical json format? " for a string, { for an hash and [ for an array
        if( $first_char eq '"' || $first_char eq '{' || $first_char eq '[' )
        {
            $data = $j->decode( $buffer );
        }

lib/Apache2/SSI/SharedMem.pm  view on Meta::CPAN

    return( $self );
}

sub write
{
    my $self = shift( @_ );
    my $data = ( @_ == 1 ) ? shift( @_ ) : join( '', @_ );
    my $id   = $self->id();
    my $size = int( $self->size() ) || SHM_BUFSIZ;
    my @callinfo = caller;
    my $j = JSON->new->utf8->relaxed->allow_nonref->convert_blessed;
    my $encoded;
    local $@;
    # try-catch
    eval
    {
        $encoded = $j->encode( $data );
    };
    if( $@ )
    {
        return( $self->error( "An error occured json encoding data provided: $@" ) );

lib/Apache2/SSI/URI.pm  view on Meta::CPAN

        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;

lib/Apache2/SSI/URI.pm  view on Meta::CPAN


    # 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;

=head1 VERSION

    v0.1.3

=head1 DESCRIPTION

lib/Apache2/SSI/URI.pm  view on Meta::CPAN

=over 4

=item C<binmode>

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

=back

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

=head2 slurp_utf8

It returns the content of the file L</filename> utf-8 decoded.

This is equivalent to:

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

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

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

=head1 AUTHOR

Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>

CPAN ID: jdeguest

L<https://gitlab.com/jackdeguest/Apache2-SSI>

t/39.functions.t  view on Meta::CPAN

    use lib './lib';
    use vars qw( $BASE_URI $DEBUG );
    # use_ok( 'Apache2::SSI' ) || BAIL_OUT( "Unable to load Apache2::SSI" );
    require( "./t/functions.pl" ) || BAIL_OUT( "Unable to find library \"functions.pl\"." );
    our $BASE_URI;
    our $DEBUG = exists( $ENV{AUTHOR_TESTING} ) ? $ENV{AUTHOR_TESTING} : 0;
};

$ENV{QUERY_STRING} = 'q=hello&l=ja-JP';

use utf8;
my $tests =
[
    {
        expect => qr/^[[:blank:]\h\v]*This worked\!/,
        name => 'base64',
        uri => "${BASE_URI}/09.01.functions.html",
        code => 200,
    },
    {
        expect => qr/^[[:blank:]\h\v]*This worked\!/,

t/40.misc.t  view on Meta::CPAN

    use vars qw( $DEBUG );
    use_ok( 'Apache2::SSI' ) || BAIL_OUT( "Unable to load Apache2::SSI" );
    use constant HAS_APACHE_TEST => $ENV{HAS_APACHE_TEST};
    use URI::file;
    our $DEBUG = exists( $ENV{AUTHOR_TESTING} ) ? $ENV{AUTHOR_TESTING} : 0;
};

use strict;
use warnings;

use utf8;
my $doc_root = URI::file->new_abs( './t/htdocs' )->file;
my $ssi = Apache2::SSI->new(
    debug => $DEBUG,
    document_uri => '../index.html?q=something&l=en_GB',
    document_root => $doc_root,
) || BAIL_OUT( Apache2::SSI->error );
$ssi->document_root( $doc_root );
my $doc_root2 = $ssi->document_root;
ok( $doc_root2 eq $doc_root, 'document root' );
my $phrase = 'Tous les êtres humains naissent libres et égaux en dignité et en droits.';

t/60.uri.t  view on Meta::CPAN

    else
    {
        skip( "Apache mod_perl is not enabled, skipping.", scalar( @$tests ) );
    }
};

sub make_request
{
    my $uri = shift( @_ );
    my $resp = GET( $uri );
    my $result = [split( /\n/, Encode::decode( 'utf8', $resp->content ) )];
    return( wantarray() ? ( $result, $resp ) : $result );
}

t/70.file.t  view on Meta::CPAN

    else
    {
        skip( "Apache mod_perl is not enabled, skipping.", scalar( @$tests ) );
    }
};

sub make_request
{
    my $uri = shift( @_ );
    my $resp = GET( $uri );
    my $result = [split( /\n/, Encode::decode( 'utf8', $resp->content ) )];
    return( wantarray() ? ( $result, $resp ) : $result );
}

t/functions.pl  view on Meta::CPAN

                debug => $opts->{debug},
            ) || die( Apache2::SSI::URI->error );
            if( $u->code != 200 && !$def->{fail} )
            {
                warn( "Unable to get the file at uri \"$def->{uri}\". Is it missing or mispelled?\n" );
                fail( $def->{name} );
                next;
            }
            my $file = $u->filepath;
            diag( "Reading file \"$file\" based on uri '$def->{uri}' and document root '$DOC_ROOT'." ) if( $opts->{debug} > 1 );
            $text = $u->slurp_utf8;
        }
        if( !length( $expect ) && !$def->{fail} )
        {
            die( "Missing \"expect\" property for test $def->{type} No $i !\nTest data is: ", $ap->dump( $def ) );
        }
        diag( "Checking uri $def->{uri} with legacy '$opts->{legacy}'" ) if( $opts->{debug} > 1 );
        my $ap = Apache2::SSI->new(
            debug => $opts->{debug},
            #document_root => $doc_root,
            #document_uri  => $doc_uri,

t/functions.pl  view on Meta::CPAN

            {
                $ap->quiet( 1 );
            }
        
            my $result = '';
            my $code;
            if( $opts->{with_apache} )
            {
                my $resp = GET( $def->{uri}, ( scalar( keys( %{$def->{headers}} ) ) ? %{$def->{headers}} : () ) );
                $code = $resp->code;
                $result = Encode::decode( 'utf8', $resp->content );
            }
            else
            {
                $ENV{REQUEST_URI} = $def->{uri};
                $ENV{REQUEST_METHOD} = 'GET';
                $ENV{HTTPS} = 'off';
                $ENV{DOCUMENT_ROOT} = $DOC_ROOT;
                if( exists( $def->{headers} ) && ref( $def->{headers} ) eq 'HASH' && scalar( keys( %{$def->{headers}} ) ) )
                {
                    while( my( $header, $value ) = each( %{$def->{headers}} ) )



( run in 1.147 second using v1.01-cache-2.11-cpan-49f99fa48dc )