views:

92

answers:

3

I have an open environment, no logins, where a number of files can be downloaded. I'm now trying to set up a wait time feature and a bandwidth limit per visitor per period of time type thing (similar to what Rapidshare has if you've ever used them before).

Any ideas how I should go about implementing this? I'm on PHP so all its restrictions/advantages (if any in this case) apply.

Thank you all.

+3  A: 

Without a login system the best you can do is restrict to one download per IP address in a fixed amount of time. I believe this is what Rapidshare does as well.

The easiest way to implement this is to record the time that an IP address starts a download, either in a flat-file format or a database. If the time elapsed from the previous download time is less than the required wait time, then redirect the user to an error page. Otherwise, redirect the user to the download link.

The nifty counter is just a Javascript trick. You can easily write one using Javascript timers but it's just for show. The actual download ability should always be determined serverside (in PHP in your case).

Kai
+1  A: 

Try sleeping the downloader.php file...

http://php.net/manual/en/function.sleep.php (set the headers before setting timeout... the filetype)

It'll force the page to wait... and on the page that links to the download page you can put a javascript counter of sorts to let the user know... it should continue running while the download page is running, or you can put the downloader file in a new page/window, that is automatically intereptered as a downloaded file (x-octet-stream filetype... http://www.vbulletin.com/forum/showthread.php?70959-HTTP-Headers-to-force-file-to-download-rather-than-auto-open&s=f54c68f056a4c7f13762e43bcfe44fdc )

You also can use a session to restrict actually being able to access the download pages in a certain amount of time, but that's more envasive.

CodeJoust
Using sleep() will hold up the entire web page until the script finishes. Sessions are easy to circumvent because the user can force a new session cookie to be requested (ex. restarting the browser).
Kai
+1  A: 

I agree with Kai but one other solution might be to serve the file at a low speed, you can use the following function to do that.

function Doo_Download($path, $speed = null)
{
    if (is_file($path) === true)
    {
     set_time_limit(0);

     while (ob_get_level() > 0)
     {
      ob_end_clean();
     }

     $size = sprintf('%u', filesize($path));
     $speed = (is_null($speed) === true) ? $size : intval($speed) * 1024;

     header('Expires: 0');
     header('Pragma: public');
     header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
     header('Content-Type: application/octet-stream');
     header('Content-Length: ' . $size);
     header('Content-Disposition: attachment; filename="' . basename($path) . '"');
     header('Content-Transfer-Encoding: binary');

     for ($i = 0; $i <= $size; $i = $i + $speed)
     {
      echo file_get_contents($path, false, null, $i, $speed);

      flush();
      sleep(1);
     }

     exit();
    }

    return false;
}
Alix Axel