使用Symfony2和Nginx X-accel-redirect提供受保护的文件

时间:2015-02-27 04:04:03

标签: symfony nginx x-accel-redirect

我的配置是带有nginx的php-fpm 5.4。我需要提供一些受保护的文件。所以我查看了Symfony,如果用户拥有正确的权限,那么我希望nginx使用X-accel-redirect头来提供文件(swf)。

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)。这些文件位于Web目录(文件)之外的目录中。

location /files/ {
     internal;
     root   /path/to/folder;
}

它可以工作(我的意思是文件服务),但我不认为它使用XSendfile。如果我理解正确,nginx将提供一个文件,如果标题

X-Accel-Redirect: /files/myfile.swf;

存在。但是BinaryFileResponse使用磁盘上的路径来查找我的文件,并且不知道应该如上设置此标头。

有人能告诉我一个如何做的例子吗? 谢谢!

2 个答案:

答案 0 :(得分:1)

因此,我阅读了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将解析这些标头,以将文件的真实路径替换为nginx网站conf中出现的私有URI:

location /private_dir {
    alias /path/to/private-dir;
    internal;
}

答案 1 :(得分:0)

我也这样做(检查用户权限,然后从文档根目录中提供文件),但我之前没有使用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,
    )
);