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

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

问题描述:

我的配置是带有nginx的php-fpm 5.4.我需要提供一些受保护的文件.因此,我与Symfony一起检查了用户是否具有正确的权限,然后我希望Nginx使用X-accel-redirect标头提供文件(swf).

My config is php-fpm 5.4 with nginx. I need to serve some protected files. So I check with Symfony if the user has the correct rights and then I would like nginx to serve the file (a swf) using the X-accel-redirect header.

symfony中的控制器:

Controller in 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目录(文件)之外的目录中.

And my nginx config: (http://wiki.nginx.org/XSendfile). The files are in a directory outside of the web directory (files).

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

它可以工作(我是说文件已经送达),但是我不认为它使用了XSendfile.如果我理解正确,nginx将在标头中提供文件

It works (I mean the file is served) but I don't think it makes use of XSendfile. If I understand correctly, nginx will serve a file if the header

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

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

is present. But the BinaryFileResponse use a path on the disk to find my file and does not know that this header should be set as above.

有人可以教我一个例子吗? 谢谢!

Can someone show me an example of how to that? Thanks!

因此,我阅读了BinaryFileResponse代码源,试图弄清楚如何进行.我想我已经了解了,但是有人可以确认这是正确的吗?至少,它似乎按预期工作.

So, I read the BinaryFileResponse code source to try to figure out how to proceed. I think I have understood but could anyone confirm this is correct? At least, it seems to works as expected.

我要提供的文件位于文档根目录之外的名为 private-dir 的目录中.

The files I want to serve are in a directory called private-dir outside of the document root.

这个想法是修改请求以让Nginx知道映射:

The idea is to modify the request to let nginx know about the mappings:

我的新控制器:

/**
 * @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:

Later the BinaryFileResponse will parse these headers to substitute the real path of the file to the private URI as it appears in the nginx website conf:

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