php get file content of downloadable file - php

Coult not find any similar problem solved on the web, so here's my situation:
I have a .jsp "webpage" that generates a .csv file based on specific parameters.
As an example, if I use my browser to open the site, I type in:
redownloadsubmitter.jsp?id=225&batch_id=2013_11_20&orgshort=NEP
The script then uses the data in the query string and generates the matching .csv file, named: NEP_DETAILS_2013_11_20.csv
Now what I want is to not manually having to use my browser, open the script and download the file to my local harddrive. Instead I want to use a PHP script that grabs the content and then can further format it, based on my needs.
I thought about the following code, but that did not work. Instead it returns nothing, empty website when I try it..
$download = file_get_contents('redownloadsubmitter.jsp?id=225&batch_id=2013_11_20&orgshort=NEP');
echo $download;
Any other ideas?
NOTE: just in case someone has this question: I have no access to the .jsp file and I therefore cannot change how it operates.

file_get_contents() isn't smart and doesn't know that's a URL you're passing in. It's trying to literally open a local file whose name is redownloadsubmitted.jsp.etc......
If you want f_g_c() to do an HTTP operation, then you'll have to include a full-blown URL:
$download = file_get_contents('http://example.com/redownloadsubmitter.jsp etc....');'

Try this code for download file.
<?php
/**
* $filename filename in server
* $downloadname filename when download file
*/
$filename = __FILE__;
$dowloadname = 'PHPDownload.php';
Header("content-type:application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Accept-Length: ".filesize($filename));
Header("Content-Disposition: attachment; filename=".$dowloadname);
if(file_exists($filename) && $fp=fopen($filename,"r")) //file exists and open it
{
echo fread($fp,filesize($filename)); //read write to the browser
fclose($fp);
}
//End_php

Related

How to hide download file path from user using php?

When user want to download file from my web site, user have to click link like below
https://www.example.com/download.php?aaa=111&bbb=222
download.php
<?PHP
session_start();
include("connect.php");
$aaa = mysql_real_escape_string($_GET[aaa]);
$bbb = mysql_real_escape_string($_GET[bbb]);
if(($aaa = '111')&($bbb = '222')) // this line is example for ask stackoverflow //
{
$filePath_try_to_download = 'attachments_files/test.pdf';
if(file_exists($filePath_try_to_download))
{
$fileSize = filesize($filePath_try_to_download);
$fileName = "test.pdf";
header("Cache-Control: private");
header("Content-Type: application/stream");
header("Content-Length: ".$fileSize);
header("Content-Disposition: attachment; filename=".$fileName);
// Output file.
readfile ($filePath_try_to_download);
exit();
}
}
?>
I want to know when user download file from this link https://www.example.com/download.php?aaa=111&bbb=222 user can get my file path on server or not (attachments_files/test.pdf). If user can get my file path, how can i hide it's ? (file in this dir is very importance)
Since I was posting comments from my Phone, they couldn't really explain much, so here goes your answer.
I want to know when user download file from this link https://www.example.com/download.php?aaa=111&bbb=222 user can get my file path on server or not (attachments_files/test.pdf).
No, Users can not see that file path which you are reading via readfile(). They will not be able to find out that file's location at all.
And if you want to eliminate any chances of people guessing the file path simply put those files outside of your web root folder and then readfile() them from there.
$filePath_try_to_download = 'attachments_files/test.pdf';
That path is only known to your PHP code, which is not visible to users hence they have no idea from where did you read the file they are downloading, just eliminate the guesswork chances though :)
And Obviously you have to secure access to this url https://www.example.com/download.php?aaa=111&bbb=222 otherwise what's the point!
No. The user cannot get the file path. He only get the content outputed by PHP script.
Your can do this and the user only get the "Hello" string. So it's your PHP script's role determining which contents the user can get.
<?php
echo "Hello";
?>

PHP link/request to download file then delete it immediately

I face a case I never did, and I dont know how to properly do it.
I have a php script which generate files for clients. At the end of the script, I echo the path for them to download the file, simply.
How can I do to provide the file - or the path or any what - for downloading it, and be sure to delete the file once downloaded.
Widely, I'd like to make the file available for one/unique download only. How to ?
EDIT
I cannot use headers
There are a few components to getting this to work. Without knowing which framework you use, I'll use comments as placeholders.
There is no way to do it without using the header function, though.
Here is the source for a file that outlines the process:
<?php
$fileid = $_GET['fileid'];
$key = $_GET['key'];
// find the file in the database, and store it in $file
if ($keyMatches) {
// it is important for security to only use file paths from the database
$actualPath = $file->getPathOnDisk();
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($fileInfo, $actualPath);
$fp = fopen($actualPath, 'rb');
header("Content-Type: " . $mime);
header("Content-Length: " . filesize($actualPath));
fpassthru($fp);
}
else
{
http_response_code(403); // forbidden
}
You'll use this by linking to download.php?fileid=1234&key=foobar, and generating the URL at the same time you generate the key and store it in the database.
For security, you'll keep the files outside of the web root, meaning they cannot be accessed through the web server without going through a script.
fpassthru is reasonably fast, and will not likely have a performance impact.
You must do a download file gateway, like download.php?id=XXX
Where XXX is the unique ID of each file you will store in DB. And of course, the file to be downloaded.
Then, each time a user will visit the page, you can :
- Check if he has already downloaded the file
- If no, redirect it to the real path of file
- If yes, display 403 message.
When a user download a file, update the DB, generate or copy the file to a new name, you play with headers, and delete file upon download or after a small timeout.

I want to search a directory for multiple files using PHP and start a download them over HTTP

Just to start, I'm a PHP noob.
I have an Apache server which hosts my files. I have a device which can only point to one PHP file. What I need it to do is have my PHP file read in the name of the file I want to download, and point it towards the directory it is stored. Currently, I have it pointing to one file, but I need it to be able to point to multiple. Is this possible in PHP?
Here's what I have so far:
<?php
$file_name = 'file.img';
$size = filesize($file_name);
$file_url = 'http://192.168.0.5/' . $file_name;
header("Content-length: $size");
header("Content-Type: text/plain");
header("Content-Transfer-Encoding: binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);?>
Edit:
The commands I want to input in order to download the file are close enough to as follows:
cmd=download+-a+$$.img+altimage
cmd=download+-a+$$.conf+altconfig
and the download directory is the .php file. I am open to other suggestions in how to do this.
Edit2:
Here's what an exact sample URL is:
myserver.com/cgi-bin/va/cmd?hdl+fullconfig.ini+altconfig
the hdl is a predefined function which points to the download directory, in order to download the file from the server, so the layout of what you mean isn't exactly the same.
I have trouble understanding what exactly you're trying to do, but I guess that you want a user to be able to download multiple files. If that is correct, here is one way to achieve this:
You can let PHP create a ZIP archive using the ZIP extension. For it to work, you have to load the extension php_zip.dll inside your php.ini.
$ZIP = new ZipArchive();
// Use the current time as the filename to prevent two users to use the same file
$ZIPName = microtime().".zip";
// Create a new ZIP file
$ZIP->open($ZIPName, ZIPARCHIVE::CREATE);
// Loop through all files - $Files needs to be an array with the names of the files you want to add, including the paths
// basename() will prevent the creation of folders inside the ZIP
foreach ($Files as $File) {
$ZIP->addFile($File, basename($File));
}
// Close the archive
$ZIP->close();
// Send the archive to the browser
readfile($ZIPName);
I hope this is what you were looking for.

How to dynamically present an on the fly zipfile to users

I'm editing an ancient script that zips several images and presents them dynamically to the user.
I have rewritten almost all of the code, but I can't find a way to way to output the contents of the zipfile. Writing it to the server is very undesirable.
I create the file with:
$z = new ZipArchive();
I can add content with:
$z->addFromString("filename",$string);
And I want to present it dynamically with:
header("Content-Type: application/zip;");
header("Content-Disposition: attachment; filename=file.zip;");
// I need a function to read the contents of the zipfile here. Something like:
echo $z->filecontent();
I can't find out what function to use for this.
You would open the file, creating it most likely with temp name. Something like this:
$name = tempnam('/tmp','zip');
$z->open($name, ZIPARCHIVE::CREATE)
After you finish adding all your files, you would close it.
$z->close();
Now when you are ready to send the data you would do this:
readfile($name);
After you are done, you want to clean up the temp file with:
unlink($name);
If you read the documentation, look at the close() method to actually save the file physically to the filesystem. Then you can use readfile() on the saved file

PHP to protect PDF and DOC

I am trying to provide .pdf and .doc files to authorized users on a website. The user can only see the file selection page when logged in but this doesn't prevent an unauthorized user from viewing the documents if they have knowledge of the full URL.
How can I prevent unauthorized users from accessing these files?
the answer is quite simple,
#Jonnix has posted this as I was typing but I will explain a little more for you
one put your files outside of your public HTML directory if your unable to do this look at #Andri answer for an alternative
E.G cpanel setup
user/public_html
/public_html/download.php
user/documents/
/documents/file.doc
/documents/file.pdf
#dhh has posted a basic download.php php file however as your wanting to force download their things you can do like finding and supplying the correct mime type here is an extension on to his code as to the best way to 1 force download of a file, and 2 allow different file types
download.php
//check users is loged in and valid for download if not redirect them out
// YOU NEED TO ADD CODE HERE FOR THAT CHECK
// array of support file types for download script and there mimetype
$mimeTypes = array(
'doc' => 'application/msword',
'pdf' => 'application/pdf',
);
// set the file here (best of using a $_GET[])
$file = "../documents/file.doc";
// gets the extension of the file to be loaded for searching array above
$ext = explode('.', $file);
$ext = end($ext);
// gets the file name to send to the browser to force download of file
$fileName = explode("/", $file);
$fileName = end($fileName);
// opens the file for reading and sends headers to browser
$fp = fopen($file,"r") ;
header("Content-Type: ".$mimeTypes[$ext]);
// this header tells the browser this is a download and not to try and render if it is able to E.G images
header('Content-Disposition: attachment; filename="'.$fileName.'"');
// reads file and send the raw code to browser
while (! feof($fp)) {
$buff = fread($fp,4096);
echo $buff;
}
// closes file after whe have finished reading it
fclose($fp);
P.S here is a big list of mime types if you want to add support for other files
https://www.freeformatter.com/mime-types-list.html
What you can do, is provide the equivalent of a PHP proxy for the files.
Put the files outside of the webroot, then write a script that checks the user is allowed access. If not, redirect them, if they do, set the appropriate headers and output the file data.
You should store all downloads outside your public / user-accessable doc root (but inside your basedir, of course) and add a download script for sending the download if the user is authorized.
Here's some example of how to "send" a file for downloading it.
$file = "ireland.jpg";
$fp = fopen($file,"r") ;
header("Content-Type: image/jpeg");
while (! feof($fp)) {
$buff = fread($fp,4096);
print $buff;
}
This did the job for me: I placed a .pdf and a .htaccess file with the following code in it in a normal folder (i named it "docs") on my apache webserver.
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
<Files /index.php>
Order Allow,Deny
Allow from all
</Files>
Then i took the code from Martin Barkers answer above, changed the filepath to "docs/sample.pdf", and pasted it into a .php file in my root directory. That's it. You can't access the file per url now, but you can download it if you run test.php.

Categories