Search code examples
symfonynginxx-sendfilex-accel-redirect

How to use Nginx X-Accel with Symfony?


I would want to use Nginx X-Accel with Symfony, for the moment I've this code.

    $request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
    $request->headers->set('X-Accel-Mapping', '/var/www/html/files/=/protected-files/');
    $request->headers->set('X-Accel-Limit-Rate', '1k');

    BinaryFileResponse::trustXSendfileTypeHeader();
    $response = new BinaryFileResponse($file->getAbsolutePath());
    $response->headers->set('Content-Disposition', 'attachment;filename="'.$filename.'"');
    $response->headers->set('Cache-Control', 'no-cache');

    return $response;

And the Nginx Conf:

location /protected-files {
    internal;
    alias /var/www/html/files;
}

To test the code (know if the file is really served by Nginx), I've add a X-Accel-Limit-Rate on 1ko/s, but a 2Mo file is downloaded instantly, then I'm sure, it doesn't work fine.

I've find this part of code on internet, because the Symfony doc, doesn't really explain how to use it... (http://symfony.com/doc/current/components/http_foundation.html#serving-files)

Why I need to return a BinaryResponse with the file, like without Nginx X-Sendfile, and add the X-Sendfile, X-Accel properties in the resuqest ? I just return the response, no the request, how it can work ?


Solution

  • Finally, I move the X-Accel part from $request to $response, and just set X-Accel-Redirect header.

    If we want limit the download speed, we can use $request->headers->set('X-Accel-Limit-Rate', 10000);, it works well, the number is in bytes.

    Then I've change the $response->headers->set('Content-Disposition', 'attachment;filename="'.$filename.'"'); to $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);

    The final code is:

    BinaryFileResponse::trustXSendfileTypeHeader();
    $response = new BinaryFileResponse($file->getAbsolutePath());
    $response->setContentDisposition(
        ResponseHeaderBag::DISPOSITION_ATTACHMENT,
        $filename
    );
    $response->headers->set('X-Accel-Redirect', '/protected-files/path/to/file');
    
    return $response;
    

    And in Nginx:

    location /protected-files/ {
        internal;
        alias /var/www/html/files/;
    }