Мне нужно было обслуживать очень большие файлы (1 Гб +) с моего веб-сервера, используя PHP
и аутентификация, чтобы только некоторые клиенты имели права на скачивание файлов.
Я не хотел использовать прямые ссылки и использование PHP
Сценарий для обслуживания файлов был недоступен из-за ограничений памяти и времени ожидания.
Мой веб-сервер управляется с Plesk
и работает на Apache
/ CentOS
6.
Выбранное решение состояло в том, чтобы установить mod_xsendfile на сервере Centos, настроить его и отправить файлы с заголовками PHP после аутентификации пользователя.
Установка mod_xsendfile на Centos. Вам нужно включить репозиторий EPEL, чтобы получить xsendfile, после этого просто:
yum update
yum install mod_xsendfile
После этого вы можете проверить, правильно ли установлен модуль, используя:
apachectl -M | grep xsendfile
Конфигурация / Plesk часть. Plesk генерирует каждый файл httpd.conf автоматически, поэтому изменение файлов вручную опасно, поскольку они могут быть перезаписаны любым изменением, выполненным через пользовательский интерфейс Plesk. По умолчанию файл http.conf включает vhost.conf и vhost_ssl.conf, для виртуальных хостов они хранятся в
/var/www/vhosts/system/[yourvhostname]/conf
Вы можете редактировать их через ssh или через интерфейс пользовательского интерфейса Plesk (vhost -> настройки сервера -> дополнительные директивы apache). Для пользователей, не являющихся пользователями Plesk, просто добавьте следующие директивы в правильный раздел vhost вашего httpd.conf
В первый раз у меня были некоторые проблемы, потому что сервер отправлял файлы размером 0 байт, после некоторого теста я нашел правильные директивы:
<Directory "/">
EnableSendfile on
XSendFile on
# Absolute path, no trailing slash!
XSendFilePath "/var/www/vhosts/[yourvhostname]/storage"
</Directory>
Обратите внимание, что если я использую директиву директории, отличную от «/», я получаю пустые файлы и никаких ошибок в любом журнале. Не проверял, что происходит, передавая относительный путь в заголовках.
Потому что я использую Laravel в качестве PHP-фреймворка, затем файл можно отправить пользователю с помощью:
return response(null)
->header('Content-Type' , 'application/octet-stream')
->header('Content-Disposition', 'attachment; '.$filename)
->header('X-Sendfile', $fullfilepath);
Надеюсь, это поможет кому-то избежать многочасовых испытаний.
Комментарий Дарио выше действительно полезен. Я просто хотел добавить то, что использовал для оператора возврата Laravel, чтобы убедиться, что файлы имеют правильные имена:
return response(null)
->header('Content-Type' , 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename="' . $filename . "')
->header('X-Sendfile', $fullfilepath);