Обслуживание защищенных файлов с помощью Symfony2 и Nginx X-accel-redirect
Мой конфиг php-fpm 5.4 с nginx. Мне нужно обслуживать некоторые защищенные файлы. Поэтому я проверяю с Symfony, есть ли у пользователя правильные права, и затем я бы хотел, чтобы nginx обслуживал файл (swf), используя заголовок X-accel-redirect.
Контроллер в Symfony:
/**
* @Route("/protected/swf")
*/
public function sendFileAction()
{
// [...]
// user rights are ok, serve the file
$fileName = 'myfile.swf';
$filePath = $this->get('kernel')->getRootDir() . '/../files/' . $fileName;
$response = new BinaryFileResponse($filePath);
$response->trustXSendfileTypeHeader();
return $response;
}
И мой конфиг nginx: ( http://wiki.nginx.org/XSendfile). Файлы находятся в каталоге за пределами веб-каталога (файлы).
location /files/ {
internal;
root /path/to/folder;
}
Это работает (я имею в виду файл обслуживается), но я не думаю, что он использует XSendfile. Если я правильно понимаю, nginx будет обслуживать файл, если заголовок
X-Accel-Redirect: /files/myfile.swf;
настоящее. Но BinaryFileResponse использует путь на диске для поиска моего файла и не знает, что этот заголовок должен быть установлен, как указано выше.
Может кто-нибудь показать мне пример того, как это сделать? Спасибо!
2 ответа
Итак, я прочитал исходный код BinaryFileResponse, чтобы попытаться выяснить, как действовать дальше. Я думаю, что понял, но кто-нибудь может подтвердить, что это правильно? По крайней мере, кажется, работает как ожидалось.
Файлы, которые я хочу обслуживать, находятся в каталоге с именем private-dir вне корня документа.
Идея состоит в том, чтобы изменить запрос, чтобы nginx знал о сопоставлениях:
Мой новый контроллер:
/**
* @Route("/protected/swf")
*/
public function sendFileAction()
{
// [...]
// user rights are ok, serve the file
$fileName = 'myfile.swf';
$filePath = $this->get('kernel')->getRootDir() . '/../private-dir/' . $fileName;
$this->getRequest()->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
$this->getRequest()->headers->set('X-Accel-Mapping', '/private_dir/=/path/to/private-dir');
BinaryFileResponse::trustXSendfileTypeHeader();
$response = new BinaryFileResponse($filePath);
return $response;
}
Позже BinaryFileResponse проанализирует эти заголовки, чтобы заменить реальный путь файла к частному URI, как это показано на веб-сайте nginx conf:
location /private_dir {
alias /path/to/private-dir;
internal;
}
Я делаю то же самое (проверяю разрешение пользователя и затем обслуживаю файлы из корня документа), но я не сделал это, используя BinaryFileResponse
раньше, поэтому этот ответ может быть не тем, что вы ищете.
То, как я делаю это с IgorwFileServeBundle
,
При этом вы будете использовать конфиг, как..
igorw_file_serve:
factory: sendfile
base_dir: $kernel.root_dir%/../files
А затем сервер файлы, как..
return $this->get('igorw_file_serve.response_factory')->create(
$filePath, // Relative to the base_dir
$fileMimeType,
array(
'serve_filename' => $fileName,
'inline' => false,
)
);