How to limit users to download files in PHP??

Discussion in 'PHP' started by funpknet, Oct 10, 2011.

  1. #1
    I want help in the php script that can limit one IP to download only 1 file in 24 hours i.e Visitor can not download more than 1 files in each day (24 hours.)
    Thanks in advance.
     
    funpknet, Oct 10, 2011 IP
  2. ashishkg

    ashishkg Active Member

    Messages:
    233
    Likes Received:
    8
    Best Answers:
    3
    Trophy Points:
    68
    #2
    you can maintain the hit on link for which ip oon database this will help you
     
    ashishkg, Oct 12, 2011 IP
  3. funpknet

    funpknet Guest

    Messages:
    3
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Thanks ashishkg, but i need more detailed help, i could not understand it.
    Thanks.
     
    funpknet, Oct 12, 2011 IP
  4. AliceWonder

    AliceWonder Peon

    Messages:
    41
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #4
    store the IP in a database (don't need a full blown one of this) with a timestamp.
     
    AliceWonder, Oct 12, 2011 IP
  5. ashishkg

    ashishkg Active Member

    Messages:
    233
    Likes Received:
    8
    Best Answers:
    3
    Trophy Points:
    68
    #5
    Store the IP and hot count on database after that check the hit using which IP. that's it.
     
    ashishkg, Oct 12, 2011 IP
  6. NetStar

    NetStar Notable Member

    Messages:
    2,471
    Likes Received:
    541
    Best Answers:
    21
    Trophy Points:
    245
    #6
    The IP won't work. Not everyone has a static IP and I believe (correct me if I'm wrong) there can be hundreds of AOL users who will show the same IP. You could use Cookies but that's an easy workaround. I would force registration which would give you the flexibility you desire to restrict.
     
    NetStar, Nov 29, 2011 IP
  7. proactiv3

    proactiv3 Peon

    Messages:
    55
    Likes Received:
    7
    Best Answers:
    4
    Trophy Points:
    0
    #7
    Imagine the following scenario:

    /home/proactiv3/website.com/ - Where your website's files reside
    
    /home/proactiv3/downloads/ - A folder that your site clients won't be able to access through their browser and where you'll store the files for download
    Code (markup):
    Here's generic code, it should get you on the right track:

    <?php
    /**
     * Quick sample private download class for DigitalPoint.
     */
    class MyDownloader
    {
    	protected $downloadPath = '/home/proactiv3/downloads/';		// The folder where the files reside
    	protected $file;											// The file ID
    	protected $clientIP;										// The client's IP
    	protected $db;												// Dummy database interaction object.
    	
    	protected $fileSize;										// The file size
    	protected $pathParts;										// Associative array returned by pathinfo
    	protected $fileExtension;									// The file extension
    	protected $fullPath;										// Full path to the file
    	
    
    	public function __construct()
    	{
    		$this->file 	= $_GET['file'];				// The file ID to be retrieved
    		$this->clientIP	= $_SERVER['REMOTE_ADDR'];		// The client's IP address
    		$this->db 		= Database::getInstance();		// Dummy database interaction object. Replace by your own.
    	}
    	
    	/**
    	 * Downloads a file.
    	 */
    	public function download()
    	{
    		// Does the client have permission to download the file?
    		if($this->authorizeClient()) {
    			
    			// Get the file information from the database
    			$sql = "SELECT * FROM download_file WHERE file_id = %i LIMIT 1";
    			$qry = $this->db->query($sql, $this->file);
    			$row = $qry->row_array();
    			
    			if(!$row) {
    				$this->showError("File does not exist!");
    			} else {
    			
    				// Set the full path to the file and test if it exists and is readable
    				$this->fullPath = $this->downloadPath . $row['file_name'];
    				
    				if(file_exists($this->fullPath) && is_readable($this->fullPath)) {
    					
    					// Set some basic information about the file
    					$this->fileSize 		= filesize($this->fullPath);
    					$this->pathParts		= pathinfo($this->fullPath);
    					$this->fileExtension	= $row['extension'];
    					
    					// Output header information
    					$this->setHeaders();
    					
    					// Read the file 2048 bytes at a time
    					if($fh = file_open($this->fullPath, 'r')) {
    						while(!feof($fh)) {
    							$buffer = fread($fh, 2048);
    							echo $buffer;
    						}
    					}
    					
    				} else {
    					
    					// The file is stored on the database, but it doesn't exist on the filesystem
    					$this->showError("File doesn't exist!");
    				}
    			}
    		} else {
    			
    			// Not authorized to download...
    			$this->showError("You can only download 1 file every 24 hours. Please try again later");
    		}
    	}
    	
    	
    	/**
    	 * Sets the basic hader information in order
    	 * to tell the browser what kind of file the user is 
    	 * trying to get and to download it.
    	 *
    	 * Its almost certain that needs tweaking.
    	 */
    	protected function setHeaders()
    	{
    		switch($this->extension) {
    			case 'pdf':
    				header('Content-type: application/pdf');
    				header('Content-Disposition: attachement, filename="' . $this->pathParts['basename'] . '"');
    			break;
    			
    			case 'doc':
    				header('Content-type: application/msword');
    				header('Conetnt-Disposition: attachement, filename="' . $this->pathParts['basename'] . '"');
    			break;
    			
    			default:
    				header('Content-type: application/octet-stream');
    				header('Conetnt-Disposition: attachement, filename="' . $this->pathParts['basename'] . '"');
    			break;
    				
    		}
    		
    		header('Content-length: ' . $this->fileSize);
    		header('Cache-control: private');
    	}
    	
    	/**
    	 * Just simple method to show an error.
    	 *
    	 * @param string $message	The error message to be shown.
    	 */
    	protected function showError($message)
    	{
    		die($message);
    	}
    	
    	/**
    	 * Checks against the database if this is the first
    	 * file download for the user on the last 24 hours.
    	 *
    	 * @return boolean	True if no download was made.
    	 */
    	protected function authorizeClient()
    	{
    		$limitDate	= date('Y-m-d H:i:s', strtotime('-1 day'));
    		
    		$sql 		= "SELECT * FROM download_log WHERE log_ip = %s AND log_date >= %s";
    		$qry 		= $this->db->query($sql, $this->clientIP, $limitDate);
    		
    		return $qry->num_rows() > 0 ? false : true;
    	}
    }
    PHP:
    <?php
    require_once mydownloader.php
    $down = new MyDownloader;
    $down->download();
    PHP:
    Take notice that the $db property of the class is purely fictional. It's just there for demonstration purposes - represents an interaction with the database. I've also disregarded the database structure, but by the SQL I think you'll get it.

    The idea is simple - check if the user can download the file (in this case via it's IP address - I think that it's the most reliable way of doing this, although you may want to reinforce it with a cookie check or whatever), then check if the file exists and is readable and finally get the file content and output it to the browser.

    Also, take notice that you should really have a "whitelist" of the downloadable files. In my example I match the argument passed via $_GET (the file ID) against the database and from there retrieve the corresponding filename. If you choose to directly pass the file name as a URI parameter, be aware that it might represent a security hole, as something like this:

    download.php?file=../../etc/passwd
    Code (markup):
    Might actually work.

    Good luck!

    EDIT - Uff, 50 days old thread... Awesome! :rolleyes:
     
    Last edited: Nov 29, 2011
    proactiv3, Nov 29, 2011 IP
  8. kids

    kids Active Member

    Messages:
    411
    Likes Received:
    4
    Best Answers:
    2
    Trophy Points:
    68
    #8
    That's perfect guide. Awesome!
     
    kids, Dec 1, 2011 IP