Search code examples
phplaravelnginxdownloadhotlinking

Laravel download response with hotlink protection and low memory usage


I have a file download website and I serve the files through Laravel for hotlink protection, but it seems like downloads keep my php processes alive for a very long time (as some users have bad download speed).

For hotlink protection I create a session when the user enters the download page and check it when they click the download button.

Is there any way to do the hotlink protection or can I just lower memory usage?

This is the code that triggers the download:

if($request->session()->get('file') == $apk->generated_filename) 
        {   
            $headers = array
            (
                'Content-Type' => 'application/vnd.android.package-archive'
            );
            Apk::find($apk->id)->increment('downloads_co');
            return response()->download(config('custom.storage') . $apk->generated_filename, $apk->filename, $headers);
        }

Solution

  • Use X-Accel-Redirect and to an internal location


    The absolute best way is to make use of http://nginx.org/r/internal on the nginx side, and do a response with the HTTP Response Header Field of X-Accel-Redirect on the upstream side for nginx to handle.

    Unless prevented by http://nginx.org/r/proxy_ignore_headers et al, nginx performs special processing of the X-Accel-Redirect upstream HTTP response header — it causes an internal redirect within nginx (which you should do to a location marked with the internal directive, to make sure that the only possible way to access such files directly is exclusively through such an internal redirect).


    The idea here is that your PHP script can still handle authentication and hotlink protection in any way you deem necessary — user authentication, link expiration, individual AI-based blacklisting and all — but then at the end of the day, once the script is done, the actual feeding of the file to the client will be done in the most efficient way possible directly through nginx.

    (Note that using the internal keyword is very important — it ensures that the only way to resume the download, once interrupted for whichever reason, would through contact with your PHP script first. So, with this clever and proven trick from the nginx cookbook, you'll be getting the best of both worlds — complete control over hotlinking and best resource utilisation.)