2

I asked this question a while ago and got an answer that I thought would work but I'm still having an issue. Maybe it's something I'm doing wrong but I still don't have this right.

I want to restrict access to an entire directory. This directory has images and pdf files in it. I need to create a link to the pdf documents and embed in an anchor tag, the images. I was told to use header for this. Using header immediately outputs the content which works great for the pdf document but I have to embed 3 images from the same directory and this doesn't work because header outputs the image before the html and that's correct behavior.

I need a way to assign the image to a variable so that I can embed it where I need it after the html has been outputted. Any ideas?

Here is a link to my last question. How to restrict viewing files within a directory

Community
  • 1
  • 1
tukar
  • 23
  • 1
  • 3
  • Can't you put these images to an other dir? – fabrik Mar 30 '11 at 13:42
  • No fabrik, not at this point. This site is rather large and I'd have a lot of work separating them. – tukar Mar 30 '11 at 13:43
  • @fabrik would it be bad idea to put downloadable things in one separate directory, inaccessible from `http`, but moved to a temporary folder for download and then remove it? – S L Mar 30 '11 at 13:44
  • Can you put this directory outside the DocumentRoot? – fabrik Mar 30 '11 at 13:45
  • Yes Fabrik, that I can do with no issues. – tukar Mar 30 '11 at 13:46
  • Actually, it's my preferred method. – tukar Mar 30 '11 at 13:46
  • @tukar you can hide these files from direct access when you move outside the DocRoot then serve them as i've previously said. – fabrik Mar 30 '11 at 13:50
  • OK but I've tried to do just that but the images are being sent, as they should be by header(). That isn't going to work because I need to assign them (3) to variables. Am I missing something? – tukar Mar 30 '11 at 13:52

1 Answers1

0

Move images outside public Document Root of your host, or restrict access to them with .htaccess like

<FilesMatch "\.(gif|png|jpe?g)$">
  Order Allow,Deny
  Deny from all
</FilesMatch>

And send images with PHP script, that will check user session and send the image only if user is logged in.

//... your session checking routine just like in other scripts
if (!$logged) {
    //show error
    exit();
}

//Simple extention-to-mimetype map:
$mimetypes = array(
    '.jpg' => 'image/jpeg'
    '.jpeg'=> 'image/jpeg'
    '.pdf' => 'application/pdf'
    //add other extensions if needed
);

$file = basename($_GET['file']);    //preventing tricks with ../../anypath/anyfile
$ext = substr($file, strrpos($file, '.'));
if (file_exists($images_dir . $file) && isset($mimetypes[$ext]) ) {
    header('Content-Type: ' . $mimetypes[$ext]);
    echo file_get_contents($images_dir . $file);
} else {
    //show error
}
Slava
  • 2,040
  • 15
  • 15
  • Slava, if I move the images outside of the DocumentRoot, in my php script, how do I call them back? Sorry for being dense but I've never had to put anything outside of it before. Do I just use a link? – tukar Mar 30 '11 at 14:03
  • Slava, I just tried to call one of the images from outside of the DocumentRoot and it doesn't show. What I see is a broken image that shows zero bytes. – tukar Mar 30 '11 at 14:15
  • Well, in that case you just keep your PHP script in normally accessible directory, and pass filename to it, like in example I just provided, and define $images_dir to something like "../private_images/" with path relative to the script, or like "/var/www/yourhost/private_images" with absolute path. – Slava Mar 30 '11 at 14:17
  • I'm using the absolute path already. Alright, let me digest what you wrote above and see if I can understand what your telling me. – tukar Mar 30 '11 at 14:19
  • The point is you make your srcipt render single image per run. And your HTML requests images with urls like `http://www.example.com/getimage.php?file=image_name.jpg` – Slava Mar 30 '11 at 14:21
  • Slava, I think you might be onto something here. :) I see how this can work. Thanks for the URL, that pinned it down for me. – tukar Mar 30 '11 at 14:26