Динамическая генерация конструкций <Location /> в Apache с использованием mod_perl

Мне нужно, чтобы мой веб-сервер Apache обслуживал множество сайтов через <Location /> структур. Последнее, что я хочу, это массивный файл с каждым <Location /> структура для каждого отдельного сайта (даже не сгенерированного). Я смотрел в mod_rewrite и некоторые модули массового виртуального хостинга, доступные для Apache, но, к сожалению, я не нашел то, что искал.

На днях я смотрел в mod_perl и как я понимаю, я могу использовать mod_perl "скриптовать" веб-сервер Apache. Это заставило меня задуматься, это ли решение, которое я искал? Я искал конкретные примеры для моей проблемы, но я не могу найти что-то конкретное.

У меня вопрос, в какой степени я могу иметь mod_perl генерировать мой <Location /> структуры во время запроса и какие переменные у меня есть доступ при этом?

ОБНОВЛЕНИЕ:

Просто для ясности я хотел бы привести пример того, что я пытаюсь сделать. Я знаю, что следующий пример неверен, но я ищу способ сделать что-то вроде этого (во время запроса):

<Location /$1/$2>
   AuthType Basic
   AuthName "Secure area"
   AuthUserFile /sites/$1/$2/users.file
</location>

Так что я хочу это; Представь это $1 это название отдела и что $2 это название проекта. Если бы я пошел URL mydomain.com/financial/accounts что users.file из каталога /sites/financial/accounts используется. Каждое место имеет свой users.file и если URL не переводится в путь файловой системы, отображается нормальный 404, или он просто не будет работать. Таким образом, я могу создать один <location /> шаблон без необходимости поддерживать большое количество <location />s и необходимость перезагрузить сервер каждый раз, когда я делаю изменения.

3 ответа

Решение

Я не пробовал ваш конкретный вариант использования, но вы можете поэкспериментировать с mod_perl и:

<Perl>
foreach (</sites/*/*/users.file>) {
    my $loc = $_;
    $loc =~ s/^\/sites(.*)\/users\.file/$1/;
    $Location{$loc} = {
        AuthType => "Basic",
        AuthName => "Secure area",
        AuthUserFile => $_,
    };
}
</Perl>

Вам все равно придется перезагружать Apache каждый раз, когда вы добавляете новый "users.file". Если вам действительно нужно сделать это динамически, вместо этого вы должны создать PerlAuthenHandler:

<Location /> # we need for any request to the site
    PerlAuthenHandler MyApache2::DynamicAuthUserFile
    AuthType Basic
    AuthName "Secure area"
</Location>

и MyApache2/DynamicAuthUserFile.pm Сценарий похож на этот:

package MyApache2::DynamicAuthUserFile;

use strict;
use warnings;

use Apache::RequestRec ();
use Apache::Access ();

use Apache::Const -compile => qw(OK DECLINED);

sub handler {
    my $r = shift;
    my ($status, $password) = $r->get_basic_auth_pw;
    return $status if $status != Apache::OK;
    my $user = $r->user;

    my $file = $r->uri;
    $file =~ s|^/sites/([^/]*/[^/])*|$1/users.file|;

    if (open(P, $file)) {
        while (<P>) {
            chomp;
            next if /^#/;
            my ($name,$saved_pw) = split /:/;
            next if $user ne $name;
            if ($saved_pw ne crypt($passwd,$saved_pw)) {
                last;
            }
            return Apache::Const::OK;
        }
        close P;
    }

    return Apache::Const::DECLINED;
}

1;

Вы имели в виду направление HTTP-запросов в соответствии с сайтом в разные DocumentRoot, ScriptAlias ​​и CustomLog, или вам нужно что-то более сложное? Не могли бы вы предоставить более подробную информацию о ваших директивах о местоположении?

Что-то, что стоит попробовать, может быть mod_macro ( http://www.coelho.net/mod_macro/)

Вы уже смотрели на использование <LocationMatch>?

Это регулярное выражение старшего брата <Location>, Если в ваших существующих директивах достаточно структуры, то должно быть возможно сопоставить их с одним регулярным выражением.

Другие вопросы по тегам