Автор: Алексей Штоль
Рекомендации, приведенные в данной статье, предназначены в первую очередь для пользователей, имеющих опыт работы с операционной средой Unix и обладающих достаточными знаниями для применения предложенных решений на сервере.
Предположим, у вас есть задача: разместить на сервере ряд файлов большого размера и организовать ограниченный доступ пользователей к этим файлам. Однако, при попытке использовать скрипт download_private.php происходит перегрузка сервера по объему используемой оперативной памяти, что приводит к неустойчивой работе сервера (даже под управлением двухуровневой системой Front/Back end (NGINX + Apache). Создание же простой HTTP-авторизации является нецелесообразным, поскольку CMS Bitrix позволяет оперативно управлять правами доступа к файлам без использования дополнительных инструментов. Рекомендации, приведенные в данном документе, помогут вам найти верное решение в подобной ситуации.
Предполагается, что некоторое количество файлов большого размера будет размещено на сервере. Доступ к этим файлам должен быть предоставлен широкому числу авторизованных в системе пользователей (т.е. пользователям, относящимся к определенной группе(ам).
Необходимо обеспечить приемлемую (низкую) нагрузку на сервер, а также предусмотреть невозможность скачивания файлов по прямой ссылке в обход процедуры авторизации.
Поставленная задача может быть решена с помощью специального скрипта download_private.php, поставляемого с CMS Bitrix. Однако, узким местом такого решения является то, что весь поток запрашиваемых пользователем данных сначала считывается в память сервера, а только потом отдается пользователю (при этом неважно, выполняется ли запрос через прокси-сервер или напрямую). В результате оказывается занят большой объем памяти, а сервер не обладает безграничным ресурсом памяти! В ходе анализа сложившейся ситуации было принято решение о пересмотре процесса работы скрипта download_private.php и его переработке с учетом особенностей прокси-сервера NGINX 0.3.15.
<? |
Важно! Обратите внимание на переменную $SELF_SCRIPT_DIR. Так как при работе с данной переменной используются регулярные выражения, то символы ^$/.[]?{}* должны отображаться с использованием обратного слэша, например \?.
Комментарии ведущих разработчиков компании «Битрикс»: В приведенном выше примере файла download_private.php описывается вариант работы с переменной $SELF_SCRIPT_DIR с использованием регулярных выражений: $SELF_SCRIPT_DIR = "\/public_private"; Однако, в данной ситуации лучше использовать способ, исключающий использование регулярных выражений, что позволит повысить скорость обработки запросов пользователей на доступ к файлам: $SELF_SCRIPT_DIR = "/public_private"; Также в файле download_private.php, приведенном в качестве примера, не предусматривается учет событий в модуле Статистики, поэтому нет необходимости в использовании функции initialize_params. Если же события должны учитываться в модуле Статистики, то в текст файла нужно добавить соответствующий код. Пример текста файла с использованием кода, отвечающего за учет событий в модуле Статистики, приводится ниже: <? | ||
ErrorDocument 404 /public_private/download_private.php
location /download/private/ {
alias /home/www/denied/;
}
location /private_download/ {
alias /home/www/download/private/;
internal;
}
Описание данных изменений должно быть размещено до определения основного пути к серверу.
Директива internal в настройках NGINX означает, что данный редирект выполняется только в том случае, если запрос на редирект приходит с локальной машины. В нашем случае эту директиву выполняет сервер Apache, установленный на той же машине, что и NGINX.
При попытке обратиться к файлу /download/private/file.zip напрямую будет выполнен редирект в папку /home/www/denied/. Так как данная папка не содержит файл file.zip, то получим Ошибку 404.
Поскольку запрос пришел «извне» (т.е. по прямой ссылке), то директива alias выполнена не будет и запрос будет перенаправлен в папку /home/www/private_download/, которая также не содержит требуемый файл. В результате получим Ошибку 404.
Обратите внимание на этот фрагмент скрипта:
$DIR_ASKED = preg_replace("/^({$SELF_SCRIPT_DIR}\/{0,1})/i","",$DIR);
if (!empty($DIR_ASKED)) $DIR_ASKED = "/" . $DIR_ASKED;
Так как больше нет потребности в создании внутренней папки /files/, вы сможете управлять структурой дерева каталогов в соответствии с вашими потребностями. Т.е. структура дерева каталогов для скачивания и хранения файлов с ограниченным доступом может быть любая. Например:
/download/private/docs/file.zip
/download/private/audio/file.mp3
…
Соответственно, публичные ссылки на файлы должны быть:
/public_private/docs/file.zip
/public_private/audio/file.mp3
…
Таким образом, вы можете создать единую папку для хранения приватных файлов. Выдача прав на доступ к файлам может осуществляться как с использованием средств CMS Bitrix, так и с помощью вашего собственного скрипта. Запрос на доступ к закрытым файлам обрабатывается сервером так же, как и запрос на показ обычной HTML страницы. Кроме того, событие доступа к закрытым файлам может регистрироваться в модуле Статистики системы Bitrix.
Некоторые директивы NGINX имеют свойство меняться от версии к версии. Поэтому настоятельно рекомендуется перед внесением изменений в настройки NGINX обратиться к официальной документации по адресу:
Автор статьи и реализация решения: Алексей Штоль, CEO, MediaTwins s.r.o., Чешская Республика.
Автор идеи: Евгений Круглов, компания CIFNet Inc., USA