Nginx, post_action. Как раздавать файлы по уникальному URL и отмечать окончание скачивания.
Условия
Задача возникла при работе над файл-шарой.
Для противодействия недобросовестным пользователям нужно организовать:
- уникальную ссылку на файл (что бы ей мог воспользоваться только получивший ее юзер)
- учет полного скачивания файла (т.е. отмечать скачивание по его завершению, а не по началу)
Файлы раздает nginx, а шифрует-дешифрует ссылки и учитывает раздачу бэк-енд сервер.
Схема работы:
- сервер генерит ссылку, шифруя в ней ИД файла и IP юзера
- по ссылке запрос пользователя попадает в лапы nginx'у
- nginx перенаправляет запрос на бэк-енд сервер
- бэк-енд расшифровывает ссылку и возвращает нгинксу путь к файлу
- нгинкс раздает файл и по завершению отправляет отчет на бэк-енд.
Подробнее:
Создание ссылки пропускаю — тут все просто.
Что бы отдать файл, нгинкс должен знать его настоящий путь. Для этого передаем запрос бэк-енду с помощью директивы proxy_pass:
proxy_pass http://127.0.0.1:8888/nginxds/linkDecoder?domain=$host&path=$request_uri;
proxy_set_header X-Real-IP $remote_addr;
Бэк-енд получив шифрованную ссылку и ИП юзера, получает из нее ИД файла, узнает путь к нему и возвращает в виде хттп-хедера X-Accel-Redirect:
String link = httpRequest.getParameter("path");
File file = decryptLink(link);
httpResponse.addHeader("X-Accel-Redirect", file.getPath());
Получив такой хедер, нгинкс переходит к соотв. location'у, который и отдает файл.
В этом же локейшыне нужно прописать директиву post_action @postDownload. Она выполнится по окончанию отдачи файла. В локейшыне @postDownload передаем запрос бэк-енду (с помощью proxy_pass).
Внимание, особенность!!! Если proxy_pass содержит переменные запроса ($uri, $host и т.п.) и отдача файла занимает некоторое время, то proxy_pass не срабатывает! Видимо запрос в нгинксе столько не живет. Т.е. обращения к бэк-енду не происходит. Лечится это «запоминанием» нужных данных запроса в переменные (в предыдущем локейшыне).
Не правильно. При передаче больших файлов proxy_pass не сработает.
# В этот локейшн переходим по хедеру X-Accel-Redirect от бэк-енда.
# (предполагается, что все раздаваемые файлы лежат в папке /storage)
location /storage {
post_action @postDownload;
root /;
internal;
}
# с такими параметрами proxy_pass на больших файлах не сработает
location @postDownload {
proxy_pass http://127.0.0.1:8888/nginxds/postDownload?domain=$host&uri=$uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header BytesSent $body_bytes_sent;
}
Правильно. Сохраним нужные данные запроса в переменные.
# В этот локейшн переходим по хедеру X-Accel-Redirect от бэк-енда.
# (предполагается, что все раздаваемые файлы лежат в папке /storage)
location /storage {
set $postURI $uri;
set $postIP $remote_addr;
set $postHOST $host;
post_action @postDownload;
root /;
internal;
}
location @postDownload {
proxy_pass http://127.0.0.1:8888/nginxds/postDownload?domain=$postHOST&uri=$postURI;
proxy_set_header X-Real-IP $postIP;
proxy_set_header BytesSent $body_bytes_sent;
}
Пост-запрос выполняется даже в случае досрочного завершения скачивания. По этому нужно передать бэк-енду сколько байт было реально отдано (proxy_set_header BytesSent $body_bytes_sent;)
На бэк-енде, учитывая хедеры BytesSent, range и реальный размер файла можно определить окончание скачивания.
Конфиг нгинкса
limit_zone lim $binary_remote_addr 10m;
server {
listen 80;
server_name www.example.com;
# Здесь обрабатывается запрос на скачивание файла.
# урл имеет вид http://example.com/download/-encrypted-file-id-
location /download {
set $limit_rate 10k;
limit_conn lim 1;
# передаем запрос бэк-енду на расшифровку. В ответе ожидаем хедер X-Accel-Redirect
proxy_pass http://127.0.0.1:8888/nginxds/linkDecoder?domain=$host&path=$request_uri;
proxy_set_header X-Real-IP $remote_addr;
add_header Content-Length $content_length;
add_header Content-Disposition attachment;
}
# В этот локейшн переходим по хедеру X-Accel-Redirect от бэк-енда (см. предыдущий локейшн)
# Предполагается, что все раздаваемые файлы лежат в папке /storage
location /storage {
set $postURI $uri;
set $postIP $remote_addr;
set $postHOST $host;
post_action @postDownload;
root /;
internal;
}
# по завершению скачивания файла передаем на бэк-енд переменные установленные
# в предыдущем локейшыне и отданный объем (в байтах)
location @postDownload {
proxy_pass http://127.0.0.1:8888/nginxds/postDownload?domain=$postHOST&uri=$postURI;
proxy_set_header X-Real-IP $postIP;
proxy_set_header BytesSent $body_bytes_sent;
}
}
Вам это будет интересно!
Последние новости
Слово
Назови человека свиньей, и он захрюкает. Пословица Проживая данную нам жизнь, мы все время находимся в гуще энергий, как положительных, так и отрицательных. По этическим нормам слово обладает определенной силой, следовательно, когда мы клевещем на человека, судим, обзываем, мы «де...Читать далее »
ЭГРЕГОР
Энергия эгрегора – квантовая структура, которая сформирована мыслями, знаниями и чувствами всего человечества – бывшего, настоящего и будущего. Эгрегор – это квантово лептонная скоррелированная структура, рожденная похожими мы...Читать далее »
Как открыть свои чакры
Открытие чакр увеличивает поток энергии в теле и вокруг него и, следовательно, улучшает наше физическое, ментальное и эмоциональное здоровье. Представьте себе каждую чакру по очереди. Они вращаются и становятся больше в размере. Начинайте с 1 – й чакры (пусть они вращаются в любую сторону, обычно они вращаются в разные). В то же ...Читать далее »
Смерть или новая жизнь
Из разговора двух зародышей в утробе матери: – Как ты думаешь, есть ли жизнь после родов? – Не знаю, оттуда еще никто не возвращался… Сравнительно недавно появились сенсационные сообщения доктора Раймонда А. Моуди о том, что ученые зарегистрировали фа...Читать далее »
Чакры
Чакры являются основными энергетическими органами биополя. Они контролируют нашу деятельность во внешнем мире, а каждая из чакр несет ответственность за определенную сферу деятельности. Основное предназначение их заключается в том, что они несут ответственность за поддержание энергообмена живого организма с окружающей средой через специальные каналы связи. Таким образом, при нарушении процесса энергообмена у нас возникают болезни и проблемы...Читать далее »
Три колонны космоса
Показания: нарушение обменных процессов, снижение иммунитета, обновление сил. Методика исполнения. Средний и сердечный пальцы правой руки кладут на аналогичные пальцы левой руки. Мизинец левой руки кладут возле основания тыльной поверхности среднего и безымянного пальцев правой руки, затем все фиксируется мизинцем правой руки. Кон...Читать далее »
Заключение
Лучше зажечь свечу, чем проклинать сгущающуюся тьму. Дзенское изречение Вот и написана книга. Мне хочется верить, что вам она обязательно поможет в познании себя, утверждении своего «Я», определении своего места во Вселенной. На ум приходит китайская пословица: «Если не менять направление, мы наверняка достигнем того, к чему идем». А мы идем к Свету, Добру и Счастью. Мы ...Читать далее »
