Page 1 of 1
limit downloads per user using session or cookie (postnuke)
Posted: Sun Feb 20, 2005 8:52 am
by mazmaz
Hi
I am using a postnuke site. I have many pdf files which my members can access. The problem again is people stealing ALL my files in one or two sessions. So I want to limit the number of files each member can download. For example a user can download say 2 files each day.
I am sure it works through sessions somehow but i dont have a clue.
I dont want a massive download program. Just a very simple way of restricting each members downloads at each session.
Any help or advice would be appreciated. I am pretty desperate and I am willing to pay for a bit of code too.
Many thanks
maz
Posted: Sun Feb 20, 2005 8:56 am
by John Cartwright
If the users are required to login simply create a new table in your database, or even use the existing one, and have a column for "num downloads" .... each time they download increment the value and each time they attempt to download check against this value.
Sessions and cookies arn't the best way to go because a) Once the browser is closed the session is closed b) cookies can be easily deleted.
Posted: Sun Feb 20, 2005 11:26 am
by thegreatone2176
phneom's way seems the best way to do it but a person can simply make another account and download again, so maybe record the ip of the person downloading and after checking the username status check the ip status
Posted: Sun Feb 20, 2005 12:04 pm
by smpdawg
You cannot trust IP address.
If a user is behind a firewall, router, etc. the IP address will be the address of the router not the IP address of the computer. While this might not seem like a problem that does mean that there can be more than one computer behind that IP and no way for you to differentiate between them using only an IP. For example, at home I have 3-4 computers online at any given time and you wouldn't know which one it is because we all have the same IP in the real world.
The second scenario is in companies that use proxy servers, bandwidth management tools, multiple routers, etc. In this case a user may have one IP when they browse a page and then a different IP on the next page load because their internal network is sending them through another router.
The session mechanism in PHP does a good job when it comes to dealing with these two problems and you ought to consider using them to store information about a user BUT you should not trust it for doing what you need to do. You should consider doing the following.
Write a script that accepts the ID of some file to download and a valid user ID. Make sure the user ID is valid. Look in the database to see if that ID had downloaded too many files and optionally deny the download. If it is OK to download, update their counter in the database and let them proceed. The file download would be an action of the script - you would not redirect them or present them with a link. If you do it this way, you can store the files off the web root so they cannot be accessed directly and can only be downloaded via the script. Remember - this is ONE script that does everything and try your best to set the path of the files somewhere that is not accessible via the internet but is available to the web server.
Using this scenario you can use cookies and/or session data to only validate the user because it is merely an aid to login and not a way of controlling downloads. This makes the script tolerant of the fact that someone may try to cheat and it would nip it in the bud by denying the download. The only gotcha is that if someone aborts the download, it still counts as a download because the transfer was initiated but that should not happen very often. In this case you could allow them a grace download if they attempt to download a file that they had tried earlier in the day.
BTW - This is not a theory, I have already done it in PHP.
Posted: Sun Feb 20, 2005 12:15 pm
by smpdawg
BTW - Here is some pseudo-code and a fragment that does the actual download. You could put all this code in some file called download.php or something like that. I would highly recommend that you use some sort of file ID rather than a path because that could open the door for someone to download sensitive files from you server if they guess where the file is like /etc/passwd...
Code: Select all
// Step 1. Validate user
// Step 2. See if the download limit was reached.
// Step 3. Make sure the file exists.
// Step 4. Update the download count table to show that a download was begun for that user.
// Step 5. Remember to NEVER USE register_globals.
if ($SomeVariableThatSaysItIsOKToDownload == true) {
// These are the headers to send a file to the browser.
// $FileName is the desired file name - not necessarily the path to an existing file but instead the name of the file as you would like it to be saved.
// Please not the IE doesn't necessarily honor this value.
header("Content-disposition: attachment; filename=" . $FileName . ";" );
header("Content-Type: application/octet-stream");
header("Content-Type: application/force-download");
header("Content-Type: application/download");
header("Pragma: no-cache");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");
// This does a cheap file open of the file specified by $FullFilePath to the standard output. This does the actual download.
readfile($FullFilePath);
} else {
// Obviously you would give an explanation to the user here about why they cannot download the file.
echo "If you are seeing this message, the you couldn't download this file for some reason.";
}
Posted: Sun Feb 20, 2005 12:33 pm
by timvw
http://timvw.madoka.be/programming/php/download.txt
my way of a download script

it's like the one posted here, only it also tries to identify the mimetype...
Posted: Sun Feb 20, 2005 12:54 pm
by smpdawg
Where was your code when I needed it? LOL
Do people throw money? If so, I am going to put my PayPal info up there.
