Контролируемые скачивания в Nginx

Контролируемое скачивание, реализуемое в веб сервере Nginx с использованием заголовка X-Accel-Redirect, подразумевает следующий алгоритм при отдаче контента:

  • Клиент нажимает на ссылку "скачать файл"
  • Запрос передается веб серверу Nginx
  • Nginx в свою очередь передает запрос некоему скрипту на проверку
  • Скрипт, после проверки, например валидности запроса на скачивание, возвращает запрос в Nginx, устанавливая заголовок X-Accel-Redirect
  • Запрос с заголовком X-Accel-Redirect попадает в специальный внутренний location, сервера Nginx, откуда и отдается клиенту

Итак, в данном примере, используются: операционная система FreeBSD 7.1-STABLE amd64, веб сервер Nginx версии 0.7.64 (последний релиз из стабильной ветки на момент написания данного материала). В качестве бакэнда будем использовать PHP в режиме FastCGI сервера, запущенный с помощью утилиты spawn_fcgi.

Корень сайта у нас будет расположен в /home/test/public_html, файлы для скачивания /home/test/public_html/download_files. Для примера набросаем примитивный скрипт down.php и положим в корень сайта а в папку download_files, положим какой-нибудь файл для скачивания, например архив test.zip

  1. <?php 
  2. $path= $_GET['file_name']; 
  3. // принимаем имя файла 
  4. .............. 
  5. // делаем какую-то проверку или обработку 
  6. .............. 
  7. header("X-Accel-Redirect: /internal_files/" . $path); 
  8. // возвращаем запрос с установленным заголовком X-Accel-Redirect 
  9. ?>

Конфигурация Nginx у нас, будет выглядеть следующим образом:

   server {
        listen       192.168.50.20:80;
        server_name  nginx.grt;

        error_log       logs/nginx_error.log error;

        root   /usr/home/test/public_html;

        location / {
            index  index.php index.html index.htm;
        }

        location /downloads/ {
            rewrite ^/downloads/(.*) /down.php?file_name=$1 break;
            fastcgi_pass   unix:/tmp/fastcgi_socket;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

        location /internal_files {
            alias /home/test/public_html/download_files;
            add_header Content-type application/octet-stream;
            internal;
        }

        location ~ \.php$ {
            fastcgi_intercept_errors off;
            fastcgi_pass   unix:/tmp/fastcgi_socket;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

Теперь что происходит при запросе http://nginx.grt/downloads/test.zip. Первоначально, запрос клиента попадает в location /downloads/, здесь, URI-часть запроса переписывается с помощью модуля ngx_http_rewrite_module, принимает вид, /down.php?file_name=test.zip и отправляется на выполнение, на FastCGI сервер. Скрипт, приняв в качестве параметра, путь к файлу, производит какие-то манипуляции и возвращает в Nginx запрос, в виде /internal_files/test.zip, с установленным заголовком X-Accel-Redirect, который в свою очередь будет обработан в location /internal_files.

В location /internal_files, прописана директива alias, указывающая путь на диске, до папки с файлами и заменяющая собой соответствующий location, и ключевое слово, Internal, говорящее, что данный location, обрабатывает только внутренние запросы сервера Nginx и запросы X-Accel-Redirect, то есть внешние запросы в этот location не попадут. В итоге всех этих манипуляций, с диска будет отдан файл /home/test/public_html/download_files/test.zip

Вот собственно и все.

Комментарии

Интересная информация, спасибо.

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Доступны HTML теги: <em> <strong> <code> <ul> <ol> <li>
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

КАПЧА
Регистр имеет значение
   .oooo.      .oooooo.       oooo   ooooo   .oooooo..o  oooooooooooo 
.dP""Y88b d8P' `Y8b `888 `888' d8P' `Y8 `888' `8
]8P' 888 888 888 888 Y88bo. 888
<88b. 888 888 888 888 `"Y8888o. 888oooo8
`88b. 888 888 888 888 `"Y88b 888 "
o. .88P `88b d88b 888 888 oo .d8P 888
`8bd88P' `Y8bood8P'Ybd' o888o o888o 8""88888P' o888o


Введите код, изображенный в стиле ASCII-арт.