динамически установить upload_tmp_dir в apache2 - PullRequest
1 голос
/ 19 апреля 2011

Я работаю над этим часами, и это сводит меня с ума!

, поэтому я думаю, что это действительно сложный вопрос, поэтому подробный вопрос.

Проблема:

  • У меня есть сервер, который принимает отправку файлов с помощью php-скрипта.

  • Данные будут распределены на несколько дисков.

  • Я хочу сохранить файл на нужный диск во время загрузки (файл tmp).

Потому что:

  • Файл долженпозже, и я не хочу, чтобы это заняло много времени (скопируйте из системного каталога tmp на целевой диск)

  • Системный диск - это ssd, который не будет очень счастливкогда столько данных записывается и удаляется на нем.

Эта конфигурация сервера изменяет значение инициализации.во время загрузки можно увидеть временный файл и увидеть, как увеличивается его размер:

Alias /thundercloud /home/thundercloud
<Directory /home/thundercloud>
    php_admin_value upload_tmp_dir /home/thundercloud/locations/42/tmp
</Directory>

Мои скрипты находятся в / home / thundercloud , а в / home есть несколько символических ссылок/ thundercloud / location (по имени 1-n), которые все указывают на соответствующие точки монтирования.

Теперь мне нужно получить число 42 (то есть диск № 42 - нет, есть только14 дисков в сервере, только для тестирования), чтобы быть динамическим.

У меня есть большой контроль над запросом, поэтому мне все равно, определяется ли он именем хоста, переменной get, подкаталогом и т. Д.

Итак, моя первая попытка была такой:

RewriteLock /var/lock/apache2/rewrite.lock
Alias /thundercloud /home/thundercloud
RewriteMap getuplaodlocation prg:/home/thundercloud/uploadloc.php
RewriteEngine On
<Directory /home/thundercloud>
    AllowOverride All
    php_admin_value upload_tmp_dir ${getuplaodlocation:%{THE_REQUEST}}
</Directory>

, соответствующая карта перезаписи была:

#!/usr/bin/php
<?
set_time_limit(0); # forever program!
$keyboard = fopen("php://stdin","r");
while (1) {
    $line = trim(fgets($keyboard)); // dont care for now
    echo '/home/thundercloud/locations/42/tmp'.PHP_EOL;
}

Я жестко закодировал 42. Если бы это работало, я бы проанализировалправильное значение от THE_REQUEST.Это не работает.скрипт был chmod 777 и все.

Моя следующая попытка была:

Alias /thundercloud /home/thundercloud
<Directory /home/thundercloud>
    SetEnvIfNoCase Host lionel\.2x\.to upload=/home/thundercloud/locations/42/tmp
    php_admin_value upload_tmp_dir upload
</Directory>

не повезло.

, поэтому моя последняя попытка была:

Alias /thundercloud /home/thundercloud
<Directory /home/thundercloud>
    php_admin_value upload_tmp_dir /home/thundercloud/locations/%{REMOTE_HOST}/tmp
</Directory>

тоже не повезло.я напечатал ini_get_all () и получил следующий вывод:

["upload_tmp_dir"]=>
  array(3) {
    ["global_value"]=>
    string(47) "/home/thundercloud/locations/%{REMOTE_HOST}/tmp"

так что очевидно, что эта "константа" не доступна, как это в этой области

теперь у меня закончились идеи

я должен управлять, мои аппорации действительно пробные и ошибочные.

anyony может указать мне правильное направление или сказать мне, что это невозможно и оправдать это?

ps: это явно не работаетна php runtime;)

edit:

Хорошо, через несколько часов и полезный комментарий от Marc BI предложил это "решение":

<VirtualHost *:80>
    ServerName 42.thundercloud.lionel.2x.to
    DocumentRoot /home/thundercloud
    php_admin_value upload_tmp_dir /home/thundercloud/locations/42/tmp
</VirtualHost>
<VirtualHost *:80>
    ServerName 43.thundercloud.lionel.2x.to
    DocumentRoot /home/thundercloud
    php_admin_value upload_tmp_dir /home/thundercloud/locations/43/tmp
</VirtualHost>

Просто брутфорсировать собственный контейнер VirtualHost для каждого диска ... это уродливо, и я надеялся избежать этого шага и иметь общую конфигурацию веб-сервера, но кажется, что это единственный путь - по крайней мере, он работает.

Мне все еще интересноесть ли лучший способ, и я думаю, что очень интересно углубиться в конфигурации веб-сервера.Apache невероятно гибок, и он становится действительно интересным, когда вы доводите его до предела (по крайней мере, так я думаю).

Именно поэтому я оставлю этот вопрос открытым и наложу на него вознаграждение.

edit:

После еще одного исследования я думаю, что может быть решение, использующее методы здесь: http://httpd.apache.org/docs/2.0/vhosts/mass.html

что-то вроде:

<VirtualHost *> 
Use CanonicalName off
VirtualDocumentRoot /home/thundercloud/locations/%0/tmp/
php_admin_value open_basedir VIRTUAL_DOCUMENT_ROOT
<VirtualHost>

Это простоидея, еще не проверенная.все еще пытаюсь понять это.Пути в этом случае не верны, но может быть обходной путь с символическими ссылками.Было бы неплохо, если бы кто-нибудь мог указать мне правильное направление.

Ответы [ 2 ]

3 голосов
/ 03 мая 2011

Нет способа использовать подстановку переменных в настройках php_admin_value.Это просто потому, что модули apache могут анализировать только свои собственные директивы config.mod_rewrite поддерживает использование переменных окружения, потому что это встроено в сам mod_rewrite.

Поскольку вы не можете использовать переменные, вам придется установить все возможные значения, используя что-то вроде <Location>.Например:

RewriteEngine on
RewriteRule /upload(\d+)$       /upload.php

php_admin_value upload_tmp_dir /tmp

<Location /upload1>
    php_admin_value upload_tmp_dir /tmp/1
</Location>
<Location /upload2>
    php_admin_value upload_tmp_dir /tmp/2
</Location>
....
<Location /upload100>
    php_admin_value upload_tmp_dir /tmp/100
</Location>

Тогда вы просто публикуете на /upload{$id}.Это явно не так динамично, как было бы, если бы замена была возможна.Есть 2 очевидные альтернативы, чтобы сделать его более аккуратным:

1) Имеется отдельный скрипт сборки, который генерирует файл для добавления в /etc/httpd/conf.d с соответствующими строками для каждого сервера

2) Создайтеуниверсальный конфигурационный файл, который просто имеет, например, 100 правил местоположения.На каждом сервере вам нужно будет просто установить нужные символические ссылки, и PHP, который генерирует форму, решит, на какой том направить загрузку, - в итоге вы получите набор /uploadX URL, которые не будут 'не работает на каждом сервере, но все равно ничего не будет там публиковаться.

Альтернативой является использование mod_macro, который в основном позволяет вам делать то же, что и выше, но с меньшим конфигурационным файлом, генерируя расширенную конфигурацию автоматически, но все жепо сути, просто генерирование большого конфигурационного файла с большим количеством блоков vhost / location.Чтобы сделать это так же хорошо, как вы и просили, вам нужно изменить mod_php.

0 голосов
/ 03 мая 2011

Если я правильно понял вопрос, вы всегда можете использовать ini_set

ini_set ("upload_tmp_dir", "/home/thundercloud/locations/42/tmp"); 
...