How to access files outside the document root - php

In a LAMP Webserver PDF help files are stored outside the document root in a given path /var/myFiles/help/. The path is set to read access which was done by the admin. To read and show them on a web page I use this code
define(PDF_PATH,"/var/myFiles/help/");
$file = PDF_PATH.'help.pdf';
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="'.$name.'"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
But finally I get a PDF file NOT FOUND error on the webpage.
What do I do wrong ? Any help is appreciated.
EDIT :
For better understanding I update the question. This is the given path structure
/var
/www
/html
/myFiles
/help
/help.pdf
How to access help.pdf and show it on a webpage ?
EDIT 2: I update the path in the define method to match the above example

I answer the quesion myself
The answer of Anant is correct. I forgot to add #readfile($name) after the header() declaration in the php file. See question above.

Related

Access & Deliver XML File Above Webroot

I'm trying to load an appcast xml file from a php file, The xml contains a file path used to display a changelog.html & gives a download path to a file. Normally, I don't want browsers to be able to access this stuff, so, the xml file, changelog & the file are all together in folder above the web root directory. The php file is inside of the webroot.
Here's my php code:
$filename = "./home/myaccountusername/folder1/folder2/appcast.xml";
if (!file_exists ($filename)) throw new Exception("File not found");
// Set the content type to xml
header('Content-Type: text/xml');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
header('Content-Length: ' . filesize($filename));
// Tell the user-agent (Stacks) not to cache the file
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
// Flush the output buffer
ob_clean();
flush();
// Read the data and send the file
//throw new Exception("FileName: " . $filename);
readfile($filename);
exit;
It's throwing exception: File not found
How do I write the paths to look above the webroot & when passed to my final display interface, allows the changelog.html to be opened & the file to be downloaded?
Note: I've tried the beginning of the path to be /home... and home... & even ../../../folder1/ ...
Is this possible to set up in php? Can't figure it out.
Update1:
Here's a tree of server:
- public_html
- appcastsecure
- productfolder
- appcast.xml
- changelog.html
- productzipfile.zip
- company_folder
- secureappcast
- appcastfile.php (start here for pathing)
I'm using DIR in appcastfile.php which gives path to appcast.xml:
$filename = /home/userdir/public_html/company_folder/secureappcast/../../appcastsecure/productfolder/appcast.xml
My problem is appcast.xml is pushed to clients on their server, so I can't figure out how to set up pathing in appcast.xml so it will point to changelog & productzipfile on my server (all are outside of public_html)
Firstly, the one in your example is trying to access the a folder relative to the current directory...
$filename = "./home/myaccountusername/folder1/folder2/appcast.xml";
The first dot shouldn't be there anyway.
If you want to access a file that is relative to a directory, you can use __DIR__, which gives the directory of the script your currently in. This then depends on where the file your trying to access is relative to the current script. So
$filename = __DIR__."/../appcast.xml";
Is a file in the directory above the one containing this script. You will have to adjust this depending on your particular requirements.

How to hide files in a website

I'm trying to hide my pdf files from users but I want them to be downloadable.
Heres my file structure
+-- index.php
+-- download.php
+-- content
+-- .htaccess
+-- files
+-- pdf.pdf
+-- pdf2.pdf
I tried to block users access to the content folder with .htaccess.
deny from all
But when i download pdf file with this
//download.php
header('Content-Type: application/pdf');
$file = "http://localhost/content/files/pdf2.pdf";
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file) . "\"");
Browser can't load it.
I can't figure out another way to do this
Users can upload files to the site and decide a price for it.
And when you have paid for it you can download it. There will be mysql query before downloading to check if user have bought it
Your download.php file is just setting some headers to tell the browser to download the file. It doesn't actually write the content of the file in the response. You just have to add the following line of code to the end of download.php:
readfile($_SERVER['DOCUMENT_ROOT'] . "/content/files/pdf2.pdf");
NOTE: As gview mentioned in the comments, the proper way to do this would be to move the files outside the document root so they cannot be accessed regardless of your per-directory htaccess file. You can still use my solution, but instead of using $_SERVER['DOCUMENT_ROOT'], you would put the server path. Like this:
readfile("/server/path/to/content/files/pdf2.pdf");

php nginx X-Accel-Redirect headers

i have an issue regarding protecting folder with static files using nginx
so basically i have root folder on nginx setup to :
/home/rise/rises/wwwdir
and the secured folder is :
/home/rise/rises/videop
as we can see i moved that folder outside root folder to prevent/allow only specific to see under criteria
when i first made a search before posting i read some ideas that to access the videop folder outside the root , i need to create alias in nginx conf like this which i made
and access internal
location /videop {
root /home/rise/rises/;
internal;
}
however i have an issue on php side to load the video...
$aliasedFile = '/videop/5_.m3u8';
$filename = '5_.m3u8';
header("Content-Description: File Transfer");
header("Content-Type application/x-mpegURL ");
header('Content-Disposition: attachment; filename='.$filename.'');
header('X-Accel-Redirect: '. $aliasedFile);
readfile($aliasedFile);
i'm missing something ?
Your root directive has a trailing / which will be followed by the leading / of the URL, so use:
location /videop {
root /home/rise/rises;
internal;
}
Your PHP has a badly formed header, which should include a : after Content-Type.
The PHP should should not include a body. The readfile is wrong. The whole purpose of the PHP is to issue an internal redirect which is picked up by nginx. So the PHP should return headers only.

Basename For Dir

$f = $_GET['f'];
//f = filename i.e file.mp3
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($f));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($f));
ob_clean();
flush();
This code works if i have all the mp3 files stored in the root directory but it doesn't if I store them in a separate folder such as /files
I have tried changing the basename and adding a path to $f but no luck
Is there a way i can have this code download the files from a dir instead of root?
Well that would be because basename explicitly strips everything but the file name part of the file path. So basename("foo/bar/baz.mp3") yields "baz.mp3".
And as others have already mentioned the way you have coded your PHP script is a major security flaw, because now someone could do something like "www.example.com/index.php?f=index.php" and your script (assuming it is located at www.example.com/index.php) would serve up its own source. With a bit of creativity, any external file your script can have access to may be downloaded in that way. Not good, you really do need to restrict the files to a whitelist of allowed paths.

linking to files above the root PHP

I recently switched servers. From shared w/ control panel to a VPS
On my old server this PHP worked:
header("Content-disposition: attachment; filename= 'welcome.doc'");
header('Content-type: application/msword');
readfile("/home/abcme/aboveroot/admin/welcome.doc");
The same folder structure exists in the new serve. There is a folder above home named aboveroot and a folder in that called admin and a file in that called welcome.doc
I changed the /home/abcme so that "abcme" is the correct new accountname
Now I get an error saying the file cannot be found. Is there something that needs to be enabled in my server or what else might explain this?
Based on what you said the structure would be like so:
>aboveroot
-home
-admin
-welcome.doc
So your header would say (assuming that /aboveroot is your webroot, which doesn't seem the case given the name):
header("Content-disposition: attachment; filename= 'welcome.doc'");
header('Content-type: application/msword');
readfile("/aboveroot/admin/welcome.doc");

Categories