Master-X
Форум | Новости | Статьи
Главная » Форум » Программинг, Скрипты, Софт, Сервисы » 
Тема: X-Accel-Redirect и internal
цитата
17/08/14 в 11:50
 S_Flash
Пордскажите, обязательно ли блокировать директорию с вне посредством internal:
location /protected/ {
internal;
root /some/path;
}
чтобы отдавать её содержимое через X-Accel-Redirect?
Файлы которые надо отдавать на закачку не должны быть закрыты, на них есть прямые линки. В моём случае, X-Accel-Redirect больше нужен для подмены хедеров, чтоб видео файлы закачивались, а не открывались браузере в плеере и прочих актив-х.

В случае с xsendfile то же надо блокировать диру или можно скармливать произвольный файл?
цитата
17/08/14 в 14:39
 Evial
Чтобы файлы не открывались в браузере, а сразу качались достаточно сделать как-то так, internal при этом не обязательно указывать.

location /protected/ {
if ($query_string ~ "^.*name=(.+\.mp4)$") {set $filename $1;}
add_header Content-Disposition "attachment;filename=$filename";
}

>В случае с xsendfile то же надо блокировать диру или можно скармливать произвольный файл?

xsendfile в nginx это X-Accel-Redirect. Чтобы этот функционал работал нужен локейшен с internal который будет доступен только в случае внутренних редиректов внутри nginx'а
цитата
17/08/14 в 14:53
 S_Flash
Sargas:
Ещё раз попробую донести смысл.
На сервере Apache + NGINX.
Есть дира в которой лежат видео файлы mp4. На эти файлы есть прямые ссылки + эти файлы проигрывааются в плеере. Т.е. глобально для них менять хедеры нельзя.
Надо сделать кнопочку, которая будет гарантировать закачку mp4 файла с хедеором типа header('Content-Type: application/force-download'); Просто есть пользователи, кототрые не догоняют, что можно выбрать в мню браузера "save link as" или подобное. Эти пользователи не могут скачать mp4, так как видео открывается у них в браузере.
Я хочу реализовать закачку через X-Accel-Redirect, либо черз xsendfile. Ессесно первое предпочтительнее, но зачада с тем, что надо лочить диру как internal. Закрывать диру nginx-ом нельзя. Может как-то можно юзать X-Accel-Redirect без закрытия диры с файлами. Но если нельзя, то прийдётся переложить на xsendfile.
цитата
17/08/14 в 16:40
 Glueon
Сейчас проблема в том, что с X-Accel-Redirect файл проигрывается, а не скачивается или что? Несколкьо раз прочитал и не понял.
Или хочется сделать файлы доступными как напрямую, так и через X-Accel-Redirect? Если да, то можно сделать один location и не обязательно internal.
цитата
17/08/14 в 17:29
 Evial
Вроде понял.
Проще всего сделать отдельный location где будет ставится заголовок для принудительного скачивания файла

location ~ ^/download/(.+\.mp4)$ {
types { }
default_type application/octet-stream;
alias /home/account/domain.com/videos/$1;
add_header Content-Disposition "attachment; filename=$1";
}

Итого при запросе например http://domain.com/download/file.mp4 будет качаться файл /home/account/domain.com/videos/file.mp4
Использовать заголовок X-Accel-Redirect или php не нужно )
цитата
17/08/14 в 19:19
 S_Flash
При прямом запросе http://domain.com/download/file.mp4 файл должен открываться в плеере, как обычно. Так же проигрываться во флеш плере с псевдо стримингом nginx.
Но при необходимости юзер должен иметь возможность скачать этот же файл. Т.е. что-то типа http://domain.com/download.php?filename=file.mp4
где в download.php подставляются нужные для закачки (чтоб не открывал браузер) заголовки. Как вариант!

По дефолту сделано примерно вот так в download.php

...
function file_force_download($PATH, $filename) {
   header("Pragma: public");
   header("Expires: 0");
   header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
   header("Cache-Control: public");
   header("Content-Description: File Transfer");
   header("Content-Type: application/force-download");

   $header="Content-Disposition: attachment; filename=".$filename.";";
   header($header );
   header("Content-Transfer-Encoding: binary");
   @readfile($PATH.$filename);
}
file_force_download($dir_path, $_GET['filename']);
...

Но этот способ юзает php, при этом жрёт память вебсервера... Совершенно не юзабельно для файлов больше 200 Мб. Короче, плохо.

Я хочу воспользоваться для кнопки загрузка возможностями NGINX или Apache более красиво нежели привёл в коде. Но перманентно переключать все файлы на закачку мне не надо. Это только как опция для пользователя, поэтому должно работать только через скрипт.
цитата
17/08/14 в 20:50
 Evial
Доступ к видео публичный или нет? Если кто угодно может смотреть/качать видео, то просто сделай отдельный локейшен как я написал выше без стриминга и формируй ссылки для кнопки "скачать"

Локейшен со стримингом оставляй как есть.

Или доступ к видео не публичный и пхп скрипт должен проверять можно ли юзеру его открывать?
цитата
17/08/14 в 22:01
 S_Flash
Sargas писал:

Или доступ к видео не публичный и пхп скрипт должен проверять можно ли юзеру его открывать?

Да, там ещё несколько проверок и статистика.. Надо через php скрипт.
цитата
18/08/14 в 00:21
 Evial
Хотя я скорее всего не правильно понял документацию и наверно можно использовать X-Accel-Redirect и без internal.


Попробуй в скрипте убрать header("Content-Type: application/force-download");

и добавить

header('X-Accel-Redirect: download/file.mp4');
header('Content-Type: application/octet-stream');




и этот кусок тоже по идее не нужен.
Код:
   header("Content-Transfer-Encoding: binary");
   @readfile($PATH.$filename);
}
file_force_download($dir_path, $_GET['filename']);



По итогу вот так
Код:
...
function file_force_download($PATH, $filename) {
   header('X-Accel-Redirect: download/file.mp4');
   header('Content-Type: application/octet-stream');
   header("Pragma: public");
   header("Expires: 0");
   header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
   header("Cache-Control: public");
   header("Content-Description: File Transfer");

   $header="Content-Disposition: attachment; filename=".$filename.";";
   header($header );
}

...
цитата
19/08/14 в 18:17
 Evial
Заработало или не?
цитата
19/08/14 в 21:38
 S_Flash
Догнал. Заработало! Спасибо.


Эта страница в полной версии