Reeksy Posted November 8, 2007 Share Posted November 8, 2007 Hi I'm having trouble! What i ultimately want is for each user on my site to be capped with a (maximum) 2Kb per second download transfer rate and only be able to download one file at a time. Therefore i need to know when a user has a download in progress. So, if they try and download 2 or more files at the same time i can block them. I don't have much idea of how to achieve this with PHP and Apache! Can anyone point me in the right direction. Regards Jon Quote Link to comment Share on other sites More sharing options...
SilveR316 Posted November 8, 2007 Share Posted November 8, 2007 There's a comment on the fread function in the php manual. It shows you how to limit download speed. http://us2.php.net/manual/en/function.fread.php#27016 As for locking the user out from downloading 2 files at the same time, you would have to flag their account someone (in the session maybe) that they are downloading a file. You would flag them before you use the script to send the file, and then unflag them after the download completes. The script runs the whole time the user is downloading, so you can unflag them right before the end of it. Of course, you might want to make it a bit robust and flag the IP address that is downloading or something similar. Using the session they could open 2 browsers and get away with downloading 2 files at the same time. Quote Link to comment Share on other sites More sharing options...
Reeksy Posted November 8, 2007 Author Share Posted November 8, 2007 OK thanks - very helpful. I'll give this method a try. Regards Jon. Quote Link to comment Share on other sites More sharing options...
Reeksy Posted November 9, 2007 Author Share Posted November 9, 2007 Hi again. I have managed to achieve the capping of the download speed. If anyone’s interested I changed the max_execution_time directive at runtime to stop the download from stopping after 30 seconds (due to the loop). 30 seconds if the max_execution_time directive default in the ini file. What I’m unsure of now is how to notify a user that they cannot download another file whilst the current one is in progress. The issue is; when a download is in progress and you try and access the script the page will appear as if it’s timed-out. This is obviously because the loop within the script is still running. Although this affectively does stop someone from downloading two files at the same time it doesn’t look very professional! I ideally want a message saying 'Can’t download as download in progress'. To do this logging the user's IP in a session seems like a good idea. I’ve tried to include this logic within the script, however when you access the page whilst a download is in progress the loop is still active, so the script wont re-run until the download has finished! Thus no message is displayed! I’ve included the script below for reference. Any help would be great // Session start session_start(); session_name('downloadTest'); // Check to see if the user has a download in progress already if (isset($_SESSION[$_SERVER['REMOTE_ADDR']])) { print 'You already have a download in progress'; exit(); } // Check passed, continue to download file... // Set the max_execution_time. 1 year so downloads don't time out! ini_set('max_execution_time', 31536000); // local file that should be send to the client $local_file = 'file2.exe'; // filename that the user gets as default $download_file = 'your-download-name.zip'; // set the download rate limit (=> 2,5 kb/s) $download_rate = 20.5; if(file_exists($local_file) && is_file($local_file)) { // send headers header('Cache-control: private'); header('Content-Type: application/octet-stream'); header('Content-Length: '.filesize($local_file)); header('Content-Disposition: filename='.$download_file); // flush content flush(); // Set the session marker $_SESSION[$_SERVER['REMOTE_ADDR']] = true; // open file stream $file = fopen($local_file, "r"); while(!feof($file)) { // send the current file part to the browser print fread($file, round($download_rate * 1024)); // flush the content to the browser flush(); // sleep one second sleep(1); } // close file stream fclose($file); // Unset session marker as download complete unset($_SESSION[$_SERVER['REMOTE_ADDR']]); }else{ die('Error: The file '.$local_file.' does not exist!'); } Regards. Quote Link to comment Share on other sites More sharing options...
SilveR316 Posted November 9, 2007 Share Posted November 9, 2007 You can set the timeout limit with the set_time_limit() function. Your method will work as well, but this one is a bit easier to remember (for future reference). Are you saying that if the user tries to access the script from another tab/browser the script does not load? They should be able to access the same script from another tab or browser without it timing out. The only time it should timeout is if they refresh the same script, in which case it won't process because it is still running. There are ways to get around this, such as doing ajax calls, but those seem a bit complicated for what youre doing. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.