KPO
KPO

Reputation: 880

How to prevent file location from showing?

I am allowing users to upload documents to the server. However, i don't want them to obviously see where the files are being stored. What can i do that will allow them to still get the file but without seeing the file location.

Upvotes: 0

Views: 152

Answers (3)

Lawrence Cherone
Lawrence Cherone

Reputation: 46620

There are a few ways todo this but i prefer using .htaccess

So my link would look like http://example.com/files/filename.zip extra parameters within the url could be used a username or password like:

 http://example.com/files/bob/filename.zip

 http://example.com/files/18d52c/filename.zip

Then thos could be checked against a database to see if user is allowed to download that specific file, much like you would use for instant downloads after payment.. but a basic method would be like so:

.htaccess

RewriteRule ^files/(.*)$ serve.php?file=$1

serve.php

<?php 
 if(isset($_GET['file'])){
    $file=basename($_GET['file']);
    //Protect the index.php && serve.php
    if(basename($_GET['file'])=='index.php' || basename($_GET['file'])=='serve.php'){
        header("HTTP/1.1 403 Forbidden");die();
    }
    $downloadFolder="original_location/";
    if(file_exists($downloadFolder.$file)){

        $fsize = filesize($downloadFolder.$file);
        $ctype=finfo_file(finfo_open(FILEINFO_MIME_TYPE), $downloadFolder.$file);

        if(ini_get('zlib.output_compression'))
        ini_set('zlib.output_compression', 'Off');

        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private",false);
        if(strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false) {
            header("Content-Type: application/force-download");
            header('Content-Description: File Transfer');
        }else{
            header("Content-Type: $ctype");
        }
        header("Content-Disposition: attachment; filename=\"".basename($file)."\";" );
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".$fsize);

        ob_clean();
        flush();
        readfile('original_location/'.$file);
    }else{
        header("HTTP/1.0 404 Not Found");
    }
    die();
 }
 header("HTTP/1.0 404 Not Found");
?>

original_location/index.php

header("HTTP/1.1 403 Forbidden");

Upvotes: 2

BrandonS
BrandonS

Reputation: 932

You can use a PHP query to accomplish this, lets say you use the following URL:

http://mysite.com/files.php?file=xyz.pdf

In files.php you can check the get variable file and have a hard coded function that retrieves the file. You can do this many ways one by using headers to force a download or read the file into a var and print it's contents to the page. For say like a pdf reading the file and printing it to the page is the same as linking it to the file.

warning though: like with using headers do not print anything to the page except the file. I also recommend declairing you headers still if you read the file and print it so that the end user will not get the gobbly goop that is the source of the file i.e. jpg or pdf.

Oh no, I forgot a header warning, I have been running into a header problem ever since Adobe made the ISO for PDF's open source, depending on the application that produced the PDF and the browser from which the user is uploading the PDF from, the header will be anything from:

'application/pdf', 'application/x-download','application/octet-stream','application/octet','binary/octet-stream'

so be careful hard coding the upload section to a header type, I know this question is about downloads but i just thought i would throw that in there. Also using headers for downloads doesn't matter I would simply use the standard application/pdf there.

Upvotes: 3

Tino Didriksen
Tino Didriksen

Reputation: 2255

Store it using some random unique ID that you can map to the real file, then serve it using a script that does readfile() on the actual file.

The http://php.net/readfile docs also have an example on how to force it being a download.

Upvotes: 1

Related Questions