PHP stream PDF with fread and readfile produce a damaged pdf - php

Hello guys i have a problem streaming PDF files with php, i'm using this code:
if(file_exists($path))
{
//octet-stream
header("Content-Length: " . filesize ( $path ) );
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=".basename($path));
readfile($path);
}
This is my directory layout (so you can understand where the PDF are stored):
Parent/
verify.php
auth/
pdf/
login.php
If i stream the a pdf from verify.php all works as intended... but if i stream the SAME PDF file from login.php they are corrupted (damaged).
Here my path definition in login.php
$path = "pdf/" . $filename . "_print.pdf";
And here my path definition in verify.php
$path = "auth/pdf/" . $filename . "_print.pdf";
Obviosly path definition is before che stream code.
The average dimension of pdf files are up to 50Kb.
The file exists beacuse pass the if check but i've no clue about why in one place is ok and in the other is damaged. (i've checked the file into the directory are okay).
Sorry for my poor english and thank you in advance.

i fixed the issue editing the code like this:
header("Content-Length: " . filesize ( $path ) );
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=".basename($path));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
ob_clean();
flush();
readfile($path);
The path work in both ways: relative or absolute.
Thanks to:
readfile not working properly

Your current working derictory doesn't change depending on your included script path. So if /var/www/parent/auth/login.php is included by /var/www/parent/index.php your working directory will remain /var/www/parent.
The popular way to deal with this is to define a define('BASEPATH', dirname(__FILE__)); (BASEPATH='/var/www/parent') constant in your main file, and use it everywhere else:
//in verify.php
$path = BASEPATH . "/auth/pdf/" . $filename . "_print.pdf";
//in login.php
$path = BASEPATH . "/auth/pdf/" . $filename . "_print.pdf";

Related

PHP script to download file is downloading itself instead of file

I'm aplying this link in order to develop an easy script to download an Android .apk file. But instead of download file, is downloading itself.
https://stackoverflow.com/a/22605604
Here is my code:
<?php
$filename = shell_exec('ls /var/www/html/app/*.apk');
$contenttype = "application/force-download";
header("Content-Type: " . $contenttype);
header("Content-Disposition: attachment; filename=\"" . basename($filename) . "\";");
readfile($filename);
exit();
?>
Php.info is rendered correctly by Apache.
Thanks.
Your path is not set correctly!
Try to use a real path/filename:
$filename = "/var/www/html/app/nameofyourfile.apk";
And also your content-type is not set correctly, try:
Content-type: application/com.android.package-install
If these two errors are corrected, it would probably force to download your apk file.
Anyway, this should work ->
<?php
$filename = "/var/www/html/app/yourfile.apk";
$contenttype = "application/com.android.package-install";
header("Content-Type: " . $contenttype);
header("Content-Disposition: attachment; filename=$filename);
readfile($filename);
?>

PHP ReadFile Issues with Spaces

Got a bit of a PHP problem I am stuck on at the moment. I have a file called download.php which gives secure access to file downloads which are stored in a private folder on the server. i.e. 1 level above httpd.
The code looks like this.
$Document = new Documents($DID);
$file = $Document->getfilewithdir();
header("Content-Description: File Transfer");
header("Content-length: " . $Document->getfilesize());
header("Content-type: " . $Document->getfiletype());
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-disposition: attachment; filename=\"" . basename($Document->getfilename()) . "\"");
readfile($file);
exit;
Where
$Document->getfilewithdir() returns something like /Applications/MAMP/htdocs/Portal_QCNW/private/portal_files/filename.docx
and
$Document->getfilename() returns something like filename.docx.
Extra code included:
function setfilename($Val)
{
$this->c_Filename = $Val;
}
function getfilename()
{
return $this->c_Filename;
}
function getfilewithdir()
{
$path_parts = pathinfo($this->geturl());
$file_name = $path_parts['basename'];
return FILELOC . $file_name;
}
This is all fine if there file name has no spaces in, but if there are spaces in the file name i.e. file name.docx or filename (1).docx then the readfile statement returns "failed to open stream". What can I do to get round this and deal with spaces in filenames?
I use https://blueimp.github.io/jQuery-File-Upload/ to upload the file, and there could be something there were I remove spaces at the upload stage.
Any thoughts and advice would be great.
Kind Regards
James
Thanks for your help. I reviewed the code and simplified it. Because I was passing a URL file name it was been formatted as a url rather than a string.
All sorted now.
James

php download file: header()

I need some eduction please.
At the end of each month, I want to download some data from my webserver to my local PC.
So, I've written a little script for that, which selects the data from the DB.
Next, I want to download it.
I've tried this:
$file=$month . '.txt';
$handle=fopen($file, "w");
header("Content-Type: application/text");
header("Content-Disposition: attachment, filename=" . $month . '.txt');
while ($row=mysql_fetch_array($res))
{
$writestring = $row['data_I_want'] . "\r\n";
fwrite($handle, $writestring);
}
fclose($handle);
If I run this, then the file is created, but my file doesn't contain the data that I want. Instead I get a dump from the HTML-file in my browser..
What am I doing wrong..
Thanks,
Xpoes
Below script will help you download the file created
//Below is where you create particular month's text file
$file=$month . '.txt';
$handle=fopen($file, "w");
while ($row=mysql_fetch_array($res)){
$writestring = $row['data_I_want'] . "\r\n";
fwrite($handle, $writestring);
}
fclose($handle);
//Now the file is ready with data from database
//Add below to download the text file created
$filename = $file; //name of the file
$filepath = $file; //location of the file. I have put $file since your file is create on the same folder where this script is
header("Cache-control: private");
header("Content-type: application/force-download");
header("Content-transfer-encoding: binary\n");
header("Content-disposition: attachment; filename=\"$filename\"");
header("Content-Length: ".filesize($filepath));
readfile($filepath);
exit;
Your current code does not output a file, it just sends headers.
in order for your script to work add the following code after your fclose statement.
$data = file_get_contents($file);
echo $data;

try to download file and getting invalid file in response in core php

I download a file but it gives invalid file in return.
Here's my download_content.php
<?php
$filename = $_GET["filename"];
$buffer = file_get_contents($filename);
/* Force download dialog... */
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
/* Don't allow caching... */
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
/* Set data type, size and filename */
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . strlen($buffer));
header("Content-Disposition: attachment; filename=$filename");
/* Send our file... */
echo $buffer;
?>
download file link:
Download
$r['file'] contains the file name to be downloaded.
The complete path of the folder which contain the file is:
localhost/ja/gallery/downloads/poster/large/'.$r['file'].'
ja is the root folder in htdocs.
I don't know what the actual problem is, can anyone help me out please?
<?php
header( "Content-Type: application/vnd.ms-excel" );
header( "Content-disposition: attachment; filename=spreadsheet.xls" );
// print your data here. note the following:
// - cells/columns are separated by tabs ("\t")
// - rows are separated by newlines ("\n")
// for example:
echo 'First Name' . "\t" . 'Last Name' . "\t" . 'Phone' . "\n";
echo 'John' . "\t" . 'Doe' . "\t" . '555-5555' . "\n";
?>
As said in the other question, this way looks better:
$filename = $_GET["filename"];
// Validate the filename (You so don't want people to be able to download
// EVERYTHING from your site...)
// For example let's say that you hold all your files in a "download" directory
// in your website root, with an .htaccess to deny direct download of files.
// Then:
$filename = './download' . ($basename = basename($filename));
if (!file_exists($filename))
{
header('HTTP/1.0 404 Not Found');
die();
}
// A check of filemtime and IMS/304 management would be good here
// Google 'If-Modified-Since', 'If-None-Match', 'ETag' with 'PHP'
// Be sure to disable buffer management if needed
while (ob_get_level()) {
ob_end_clean();
}
Header('Content-Type: application/download');
Header("Content-Disposition: attachment; filename=\"{$basename}\"");
header('Content-Transfer-Encoding: binary'); // Not really needed
Header('Content-Length: ' . filesize($filename));
Header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
readfile($filename);
That said, what does "invalid file" mean? Bad length? Zero length? Bad file name? Wrong MIME type? Wrong file contents? The meaning may be clear to you with everything under your eyes, but from our end it's far from obvious.
UPDATE: apparently the file is not found, which means that the filename= parameter to the PHP script is wrong (refers a file that's not there). Modified the code above to allow a directory to contain all files, and downloading from there.
Your $filename variable contains whole path as below
header("Content-Disposition: attachment; filename=$filename");
Do like this
$newfilename = explode("/",$filename);
$newfilename = $newfilename[count($newfilename)-1];
$fsize = filesize($filename);
Then pass new variable into header
header("Content-Disposition: attachment; filename=".$newfilename);
header("Content-length: $fsize");
//newline added as below
ob_clean();
flush();
readfile($filename);

Need help getting this auto-download header to show the right path

I have a page with mp3s that are playable from a player, and there are also links to download the songs. When the user clicks on the download link, it needs to open the download dialog instead of opening a media player, so it was recommended to me to use this header script:
includes/auto-download.php:
<?php
$path = $_GET['path'];
header('Content-Disposition: attachment; filename=' . basename($path));
readfile($path);
?>
And then on my main page, the link looks like this:
Song Name
I seem to be doing something wrong with my paths, as when I click the link, the download box opens, and I can download a file with the correct name, but it doesn't contain any information.
To elaborate on my file structure, I've got this:
/Patrons (where my main index.php page is with my link
/Patrons/includes (where my auto-download.php script is)
/Patrons/Media/Audio/Date/ (this is where all the songs are)
Any help would be greatly appreciated!
Either change HTML code to this:
Song Name
OR change PHP code to this:
readfile('../'.$path);
$path needs to be the relative path to the file from the web root. with no leading slash. If the files are outside the web root you should use a fullpath (/home/webuser/song_files/song.mp3).
For example $path = 'song_files/'. $_GET['name_of_the_file'];
You should also check if the file does not exist and exit with an error.
Here is an example I made in codeigniter.
function _begin_download($document_data) {
basepath = 'uploads/';
$filepath = basepath . $document_data->filename;
if (file_exists($filepath)) {
header("Content-type: " . $document_data->mimetype);
header("Content-length: " . filesize($filepath));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-disposition: attachment; filename="' . $document_data->filename . '"');
readfile($filepath);
exit();
} else {
exit('File not found.');
}
}

Categories