Nginx, post_action. Как раздавать файлы по уникальному URL и отмечать окончание скачивания.





Условия

Задача возникла при работе над файл-шарой.
Для противодействия недобросовестным пользователям нужно организовать:

  1. уникальную ссылку на файл (что бы ей мог воспользоваться только получивший ее юзер)
  2. учет полного скачивания файла (т.е. отмечать скачивание по его завершению, а не по началу)

Файлы раздает 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;
    }
}




Вам это будет интересно!

  • [памятка] как портить аудио файлы
  • Долгая дорога к кедрам. Окончание.
  • Азербайджан - окончание
  • Партеногенез. Окончание
  • Окончание Рамадана 2009
  • Последние новости

    Слово

    Назови человека свиньей, и он захрюкает. Пословица Проживая данную нам жизнь, мы все время находимся в гуще энергий, как положительных, так и отрицательных. По этическим нормам слово обладает определенной силой, следовательно, когда мы клевещем на человека, судим, обзываем, мы «де...
    Читать далее »

    ЭГРЕГОР

    Энергия эгрегора – квантовая структура, которая сформирована мыслями, знаниями и чувствами всего человечества – бывшего, настоящего и будущего. Эгрегор – это квантово лептонная скоррелированная структура, рожденная похожими мы...
    Читать далее »

    Как открыть свои чакры

    Открытие чакр увеличивает поток энергии в теле и вокруг него и, следовательно, улучшает наше физическое, ментальное и эмоциональное здоровье. Представьте себе каждую чакру по очереди. Они вращаются и становятся больше в размере. Начинайте с 1 – й чакры (пусть они вращаются в любую сторону, обычно они вращаются в разные). В то же ...
    Читать далее »

    Смерть или новая жизнь

    Из разговора двух зародышей в утробе матери: – Как ты думаешь, есть ли жизнь после родов? – Не знаю, оттуда еще никто не возвращался… Сравнительно недавно появились сенсационные сообщения доктора Раймонда А. Моуди о том, что ученые зарегистрировали фа...
    Читать далее »

    Чакры

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

    Три колонны космоса

    Показания: нарушение обменных процессов, снижение иммунитета, обновление сил. Методика исполнения. Средний и сердечный пальцы правой руки кладут на аналогичные пальцы левой руки. Мизинец левой руки кладут возле основания тыльной поверхности среднего и безымянного пальцев правой руки, затем все фиксируется мизинцем правой руки. Кон...
    Читать далее »

    Заключение

    Лучше зажечь свечу, чем проклинать сгущающуюся тьму. Дзенское изречение Вот и написана книга. Мне хочется верить, что вам она обязательно поможет в познании себя, утверждении своего «Я», определении своего места во Вселенной. На ум приходит китайская пословица: «Если не менять направление, мы наверняка достигнем того, к чему идем». А мы идем к Свету, Добру и Счастью. Мы ...
    Читать далее »