Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restriction of 1 download at a time in PHP

Tags:

php

download

I am working on a video site that has different movies and videos which users can stream and download. Now I am being asked to implement a download restriction in such a way that only 1 video can be downloaded at a time. There are two servers: my files and database are on one server and the videos are on the other.

What I am doing for downloading is to send a request from the first server for a file on the other server. If the requested video exists, it is downloaded.

Now I want to restrict the users so that if they are already downloading a video, they cannot download another until the current download completes. Once the current download has completed, the user can download the next video. I have not seen any function that enables a developer to know when the download has completed.

I have a few things in my mind about storing the information of the download time in the database. But storing the time of download is not my requirement.

What is the best way to implement this? Is there an event from which we can detect the download end time? Is there any solution to this? I am using PHP and here is the code that I have used for downloading the file from the second (videos) server. This file sends a request with a file name and full path. The $real_file variable contains the file name along with full path on the second server.

if(file_exists($real_file))
{
    header("Pragma: public"); 
    header("Cache-Control: private"); 
    header("Expires: 0"); 
    header('Cache-Control: no-store, no-cache, must-revalidate');
    header('Cache-Control: pre-check=0, post-check=0, max-age=0');
    header('Content-Transfer-Encoding: binary');
    header('Content-Encoding: none');
    header("Content-Disposition: attachment; filename=".urlencode(basename($real_file)));   
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");
    header("Content-Description: File Transfer");            
    header("Content-Length: " . filesize($real_file));
    header("Accept-Length: ".filesize($real_file));

    $fp = @fopen($real_file, "rb");

    while(!feof($fp))
    {
        $buffer= fread($fp, 8192);
        echo $buffer;
    }

    @flush();
    @ob_flush();
    die();
}
like image 331
Awais Qarni Avatar asked Nov 14 '22 02:11

Awais Qarni


1 Answers

If you stream the file through a php-script, it would maybe be able to obtain a lock for a specific user (logged in of course) before you start to read the file and outputting to the stream:

(pseudocode)

obtain_lock_somehow();
readfile('yourvideofile.mpg');
release_lock();

I don't know how the script would respond to a closed connection, and it might force the script to end prematurely.

Another option would be to read the file and pass on to the stream in "chunks", and in between every chunk you update the status of the visitors "lock", so that you can identify at which last timestamp the visitor actually downloaded something.

(pseudocode)

while(file_is_not_finished) {
    update_lock_status();
    pass_thru_buffer();
}

But do note that streaming huge amount of data in a php-script like this is probably not the best way to go, and you might be better off with a native server module for it.

like image 186
jishi Avatar answered Dec 18 '22 21:12

jishi