问题
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.
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;
}
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;
}
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;
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!
回答1:
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.
The files I want to serve are in a directory called private-dir outside of the document root.
The idea is to modify the request to let nginx know about the mappings:
My new controller:
/**
* @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;
}
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;
}
回答2:
I do the same (check user permission and then serve files from out of document root) but I've not done it using the BinaryFileResponse
before so this answer might not be what you are looking for.
The way I do it is with the IgorwFileServeBundle.
With this you would use the config like..
igorw_file_serve:
factory: sendfile
base_dir: $kernel.root_dir%/../files
And then server up the files like..
return $this->get('igorw_file_serve.response_factory')->create(
$filePath, // Relative to the base_dir
$fileMimeType,
array(
'serve_filename' => $fileName,
'inline' => false,
)
);
来源:https://stackoverflow.com/questions/28757322/serving-protected-files-with-symfony2-and-nginx-x-accel-redirect