Show: Search - Categories - Posts
Posted on Friday the 11th of April 2008 at 4:33 PM
I decided to put to test some of the hotlink protection methods I came up with. I didn't even bother to test my first method, the one that involved using an htaccess to make it appear the images were in a different directory. The second method was obviously the best method and so that is the one I went to work on. Although, I originally didn't know if it would even be possible, it turns out that it was indeed possible and that it was way easier than I had ever thought.

At first I tried to get the htaccess to hand the information over to the PHP file. Information such as which file was trying to be accessed and in what directory. I got that semi-working by doing something like this.

RewriteEngine On
RewriteRule ([\w\d_-]+\.jpe?g|gif|bmp|png)$ test.php?q=$1 [L]

It worked for the most part except that it didn't hand me any information on what directory it was in. So i basically gave up on handing any information over from the htaccess and just based everything solely on PHP while utilizing htaccess only for the purpose of redirecting any image requests to the PHP script. My htaccess ended up looking like this.

RewriteEngine On
RewriteRule ([\w\d_-]+\.jpe?g|gif|bmp|png)$ test.php [L]

The PHP part was fairly straight forward. The only problem was in detecting what the mime type was on the file. It turns out "mime_content_type" has been deprecated and the replacement "fileinfo" only works if you have a certain package installed. Which it turns out I did not and if I do not I'm fairly certain a good portion of others will not. So, it turns out there's no good way to get the mime type of a file in PHP but for now I just needed the mime type of image files and "getimagesize" provides just that. However, this means that I cannot find out the mime type for non-image file types. Of course, being the genius I am, I came up with a method to solve this problem. Although it's rather backasswards the solution is to make a list of mime types and associate that to the file type. Apache has a list somewhere in its configuration files but making a list in the PHP script itself with just the most common filetypes would work just as well.

Well, it seems like I've solved all my problems doesn't it? Well, no. It turns out that when the PHP passes the image information through itself and pretends to be the image there is no way for the browser to properly cache it and in the interest of making it as efficient as possible I cannot allow this. So, my new solution would be to completely obliterate my old method and come up with something new. Which I have already.

My new method involves a PHP script that writes an htaccess file and passes no image information through itself. When a site that is not on the allowed site list is encountered by the htaccess file it then passes through the PHP file where the PHP file makes a note of it and displays it in a control panel. You can decide to allow or deny that site and if it is allowed the PHP script will add that to the htaccess.

You can view my testing grounds at www.saurdo.com/test/hotlink/ and my current PHP for the method that does not cache images looks like this.

     $allowed = array($_SERVER['HTTP_HOST']);
     $reqfile = $_SERVER['REQUEST_URI'];
     $refsite = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
      if(in_array($refsite, $allowed) || !isset($refsite)){
            $size = getimagesize($_SERVER['DOCUMENT_ROOT'].$reqfile);
            $fp = fopen($_SERVER['DOCUMENT_ROOT'].$reqfile, "rb");
            header("Content-type: ".$size['mime']);
            fpassthru($fp);
      }
      else{
           imageCenterString( 450, 25, "The file \"".$reqfile."\" cannot be viewed from ".$refsite, 2 );
     }

The function "imageCenterString" is not shown because it is huge.