Servindo grandes arquivos protegidos em PHP / Apache

Eu preciso exibir arquivos grandes (> 2gb) de um servidor web Apache. Os arquivos são downloads protegidos, então eu preciso de algum tipo de maneira de autorizar o usuário. O CMS que estou usando usa cookies verificados em um database MySQL para verificar o usuário. No servidor, não tenho controle sobre o max_execution_time e controle limitado sobre memory_limit.

Minha técnica tem trabalhado para pequenos arquivos. Depois que o usuário foi autorizado em PHP (pelo CMS), eu uso readfile () para servir o arquivo, que está armazenado acima da raiz do documento para impedir o access direto. Eu li sobre técnicas para baixar o download ou usar fpassthru para contornar o limite de memory do PHP. Mas não encontrei uma técnica para contornar o limite de max_execution_time.

Pensei em armazenar o arquivo dentro da raiz do documento, para que possamos ignorar o PHP completamente. Mas o que não consigo descobrir é como restringir o access com o htaccess. Eu preciso verificar o usuário contra o database antes que eu possa atendê-lo no arquivo.

Obrigado.

A solução mais legal na minha opinião: instale o mod_xsendfile no seu Apache, mod_xsendfile que o script PHP autorize o usuário e, no sucesso, envie uma resposta com um header X-Sendfile apontando para o local do arquivo protegido. A partir desse momento, o Apache faz o trabalho de servir o arquivo ao cliente; não PHP.

E quanto ao uso de links simbólicos? Se você tiver um exemplo de pasta:

 userfacingfiles/ md5_of_order_id1 --> protected-file.exe md5_of_order_id2 --> protected-file.exe protectedfiles/ .htaccess (contains deny from all) protected-file.exe 

Exemplo básico:

 $salt = 'canttouchthis'; function create_symlink($order_id, $salt, $protected_file) { $info = pathinfo('protectedfiles/'.$protected_file); symlink('protectedfiles/'.$protected_file, 'userfacingfiles/'.md5($order_id.$salt).'.'.$info['extension']); } function get_file($order_id, $salt, $extension) { header('Location: userfacingfiles/'.md5($order_id.$salt).'.'.$extension); exit(); } 

uso:

Quando o usuário paga:

 create_symlink(1, 'secureSALT', 'ebook.pdf'); 

Quando o usuário deseja baixar seu ebook

 get_file(1, 'secureSALT'); 

Este pode não ser o método mais portátil, mas porque você está redirecionando o usuário, o servidor da Web está gerenciando os downloads.