Динамическая генерация конструкций <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>
, Если в ваших существующих директивах достаточно структуры, то должно быть возможно сопоставить их с одним регулярным выражением.