You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by "John A." <jo...@ankarstrom.se> on 2021/04/16 17:27:31 UTC

Fixing Apache::ReadConfig limitations

Presently, Apache::ReadConfig doesn't seem to provide a way to represent
the order of directives, which limits its usefulness when used with
modules like mod_rewrite that rely on the order of certain directives:

<VirtualHost "*:80">
    ServerName example.com
    DirectoryRoot /www
    <Directory "/www">
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule (.*) cgit.cgi/$1 [END,QSA]
    </Directory>
</VirtualHost>

This piece of configuration is (AFAIK?) impossible to create using
Apache::ReadConfig, because %VirtualHost and %Directory are unordered
hashes.

Assuming I'm correct about the problem, what could be done to fix it?

My personal idea is to create an additional module created
Apache::ReadConfig::Full (or something), which allows the following:

$Config->push(['VirtualHost', '*:80'] => block(
    ServerName => 'example.com',
    DirectoryRoot => '/www',
        ['Directory', '/www'] => block(
        RewriteEngine => On,
        RewriteCond => '%{REQUEST_FILENAME} !-f',
        RewriteCond => '%{REQUEST_FILENAME} !-d',
        RewriteRule => '(.*) cgit.cgi/$1 [END,QSA]'
    )
);

The `block' function creates an object that amounts to an ordered,
multi-value hash a la Hash::MultiValue. (The global $Config variable is
the same type of object.)

Before I start looking into the possibility of creating such an
interface, I thought I'd ask here whether my assumptions about
Apache::ReadConfig's limitations are correct.

Best regards
John


Re: Fixing Apache::ReadConfig limitations

Posted by "John A." <jo...@ankarstrom.se>.
Den 2021-04-16 kl. 23:30 skrev John A.:
> Den 2021-04-16 kl. 20:42 skrev Mithun Bhattacharya:
>> Doesnt it accept array of array refs for this purpose ?
> 
> Could you give an example? I'm not sure I follow.

Replying to myself with an update, as I seem to have figured it out!

I saw Tie::IxHash mentioned somewhere and then found a note in the
mod_perl Developer's Cookbook about Tie::DxHash, which provides ordered,
multi-value hashes.

And indeed, the following code appears to work perfectly:

use Tie::DxHash;

sub block {
        my %hash;
        tie %hash, 'Tie::DxHash';
        %hash = @_;
        return \%hash;
}

$VirtualHost{'*:80'} = {
        ServerName => 'git.ankarstrom.se',
        DocumentRoot => '/usr/local/www/git/data',
        Directory => {
                '/usr/local/www/git/data' => block(
                        DirectoryIndex => 'cgit.cgi',
                        Options => 'FollowSymLinks ExecCGI',
                        RewriteEngine => 'On',
                        RewriteCond => '%{REQUEST_FILENAME} !-f',
                        RewriteCond => '%{REQUEST_FILENAME} !-d',
                        RewriteRule => '(.*) cgit.cgi/$1 [END,QSA]',
                        Require => 'all granted'
                )
        }
};

Neat!


Re: Fixing Apache::ReadConfig limitations

Posted by "John A." <jo...@ankarstrom.se>.
Den 2021-04-16 kl. 20:42 skrev Mithun Bhattacharya:
> Doesnt it accept array of array refs for this purpose ?

Could you give an example? I'm not sure I follow.

After experimenting a bit, it seems that the following method, with an
array of hash refs, is accepted:

    Directory => {
        '/www' => [
            {DirectoryIndex => 'cgit.cgi'},
            {RewriteEngine => 'On'},
            {RewriteCond => '%{REQUEST_FILENAME} !-f'},
            {RewriteCond => '%{REQUEST_FILENAME} !-d'},
            {RewriteRule => ['(.*) cgit.cgi/$1 [END,QSA]']},
        ]
    }

but the RewriteConds still don't work the way they should. The
RewriteRule applies regardless of the RewriteConds.

I'd love to find a way for this to work.


Re: Fixing Apache::ReadConfig limitations

Posted by Mithun Bhattacharya <mi...@gmail.com>.
Doesnt it accept array of array refs for this purpose ?

On Fri, Apr 16, 2021 at 1:10 PM John A. <jo...@ankarstrom.se> wrote:

> Presently, Apache::ReadConfig doesn't seem to provide a way to represent
> the order of directives, which limits its usefulness when used with
> modules like mod_rewrite that rely on the order of certain directives:
>
> <VirtualHost "*:80">
>     ServerName example.com
>     DirectoryRoot /www
>     <Directory "/www">
>         RewriteEngine On
>         RewriteCond %{REQUEST_FILENAME} !-f
>         RewriteCond %{REQUEST_FILENAME} !-d
>         RewriteRule (.*) cgit.cgi/$1 [END,QSA]
>     </Directory>
> </VirtualHost>
>
> This piece of configuration is (AFAIK?) impossible to create using
> Apache::ReadConfig, because %VirtualHost and %Directory are unordered
> hashes.
>
> Assuming I'm correct about the problem, what could be done to fix it?
>
> My personal idea is to create an additional module created
> Apache::ReadConfig::Full (or something), which allows the following:
>
> $Config->push(['VirtualHost', '*:80'] => block(
>     ServerName => 'example.com',
>     DirectoryRoot => '/www',
>         ['Directory', '/www'] => block(
>         RewriteEngine => On,
>         RewriteCond => '%{REQUEST_FILENAME} !-f',
>         RewriteCond => '%{REQUEST_FILENAME} !-d',
>         RewriteRule => '(.*) cgit.cgi/$1 [END,QSA]'
>     )
> );
>
> The `block' function creates an object that amounts to an ordered,
> multi-value hash a la Hash::MultiValue. (The global $Config variable is
> the same type of object.)
>
> Before I start looking into the possibility of creating such an
> interface, I thought I'd ask here whether my assumptions about
> Apache::ReadConfig's limitations are correct.
>
> Best regards
> John
>
>