Search code examples
phpzend-framework.htaccesszend-controller

Control access to files available for download


I have a folder that contains uploaded documents that my ZF application can spit out to logged in users. I want them to be able to use a link like http://server/documents/filename.pdf and download the file, but I want to have a controller DocumentsController that enables the existing user cookies to verify that they are logged in and have permission to download the file. I don't want to have to use URLs like http://server/documents/index/id/1 if I don't have to, though its not a terrible option.


Solution

  • You can use X-SendFile to obtain the best performance. It is supported by Apache (mod_xsendfile), Lighttpd and Nginx. The request is first handled by a php process which put a special header (X-Sendfile or X-Accel-Redirect for Nginx) and when the script end, the web server take over and send the file like a static file. It is faster and use less memory.

    To redirect all the request to your controller, you need to write a custom route in your bootstrap :

    protected function _initRouter()
    {
        $router = Zend_Controller_Front::getInstance()->getRouter();
    
        $documentRoute = new Zend_Controller_Router_Route(
            'document/:filename',
            array(
                'action'     => 'xsendfile',
                'controller' => 'documents'
            ),
            array(
                'filename' => '\..+$'
            )
        );
        $router->addRoute('document', $documentRoute );
    
        return $router;
    }
    

    You can use this action helper to handle the x-sendfile header : http://www.zfsnippets.com/snippets/view/id/27 and you need to had code to check if the user is authenticated.