Мне кажется, я понимаю проблему здесь, потому что я столкнулся (и решил) хотя бы частично с ней сам не так давно.
У меня есть несколько больших mp3 , и я ссылаюсь на них на моем сайте
Несколько проблем
- Мне нужно было установить мой заголовок content-disposition на attachment , чтобы предотвратить автоматическую потоковую передачу файлов при нажатии пользователем кнопки загрузки
- мои файлы находятся на удаленном сервере
- мои файлы большие (100 МБ)
- большие файлы могут связать контроллеры рельсов, если не обработаны должным образом
Теперь Михаил Козьярский советует в этой статье , что лучший способ сохранить ваши процессы rails свободными при обслуживании больших файлов - это создать действие загрузки в вашем контроллере, и сделать что-то вроде этого (обратите внимание на использование x_sendfile => true ):
def download
send_file '/path/to/podcast.mp3', :type => 'application/octet-stream', :disposition => 'attachment', :filename=>'something.mp3', :x_sendfile=>true
end
: x_sendfile указывает apache пропустить файл, не связывая процесс контроллера rails. Остальная часть кода устанавливает имя файла и заголовок расположения содержимого.
Отлично, но я на герою , как и все в наше время . Поэтому я не могу использовать x_sendfile.
Я обнаружил, что не могу изменить файл конфигурации nginx, так как он заблокирован heroku, поэтому невозможно получить x-accel-redirect (эквивалент nginx x-sendfile) ) работает
Итак, я решил добавить скрипт perl (см. Ниже) в cgi-bin на нашем ресурсе-хосте, и этот скрипт устанавливает расположение содержимого на attachment и дает нашему файлу тоже имя.
Вместо того, чтобы делать спокойную загрузку, как это:
link_to "download", download_podcast_path(@podcast.mp3)
мы просто ссылаемся на mp3, чтобы убедиться, что мы проходим через cgi-bin, чтобы скрипт perl вызывался на каждом mp3, который покидает сервер
# I'm using haml
%a{:href=>"http://afmpodcast.com/cgi-bin/download.cgi?ID=#{@podcast.mp3}"}
download
В результате мой контроллер rails больше не вызывается, когда кто-то загружает файл
Я нашел здесь скрипт на Perl и немного порезал его, чтобы он работал для меня:
#!/usr/local/bin/perl -wT
use CGI ':standard';
use CGI::Carp qw(fatalsToBrowser);
my $files_location;
my $ID;
my @fileholder;
$files_location = "../";
$ID = param('ID');
open(DLFILE, "<$files_location/$ID") || Error('open', 'file');
@fileholder = <DLFILE>;
close (DLFILE) || Error ('close', 'file');
print "Content-Type:application/x-download\n";
print "Content-Disposition:attachment;filename=$ID\n\n";
print @fileholder
Мой код находится на github , но, вероятно, у вас возникнут всевозможные проблемы с его использованием на вашем компьютере, поскольку я интенсивно использую переменные ENV, которые я храню в bashrc, и у меня нет документации или тестов ^ скрывает ^