I am about to take a web application I've been working on live and am now, of course, updating code to make things that worked perfectly on my localhost work on the secure server. One of the tasks this application performs is generating and downloading files. All of the files are being generated and written to the server, but the .xls, .csv, and .json files download with no data even though the data is in the files on the server. The .xml, .zip, and .sql files do download with accurate data. An .xls or .json file that is contained within a .zip file is fine. This problem is not IE specific as I am using Chrome. Also tried Safari with the same results.
Here is what I'm doing to download the Excel:
$excel_content = file_get_contents($download_file_name);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$file_name);
header("Content-Transfer-Encoding: binary");
header("Pragma: no-cache");
header("Expires: 0");
print chr(255).chr(254).mb_convert_encoding($excel_content, 'UTF-16LE', 'UTF-8');
Here is what I'm doing to download the XML:
$xml_content = file_get_contents($download_file_name);
header("Content-Type: application/xml");
header("Content-Disposition: attachment; filename=\"".$file_name);
header("Content-Transfer-Encoding: UTF-8");
header("Pragma: no-cache");
header("Expires: 0");
print $xml_content;
Can anyone see why the Excel works on my localhost, but not on my server through https protocol? If it matters, I do have openssl enabled as verified with an info.php file on the server.
Related
I'm trying to create a simple download page, which currently works in Firefox but not entirely in Chrome and Edge. The file to download is an mp3, located in a private directory on the server.
When I download the file in Firefox it works as intended. If I download it using Chrome or Edge the file still downloads, but it doesn't recognize the file type and just saves it as an extensionless file. If I add the .mp3 extension manually to the downloaded file it's fine and I can play the track.
These are the headers:
header("Cache-Control: private");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Length: " . filesize($filePath));
//Force download
readfile($filePath);
Changing the 'Content-type' to 'audio/mpeg' also doesn't work.
can you try:
header("Content-Disposition: attachment; filename=\"$title\".mp3");
to see if the title does not contain the extension
I am trying to set up a PHP script which can pull files (for validated users) from a folder outside of the live webroot. The problem is that when doing this, even if I use a proper "Content-Type" header, the file is downloaded as application/octet-stream. This has security implications if the user later tries to re-upload the downloaded file as it will be detected as an application even when it is really a pdf (my application only allows certain mime-types to be uploaded).
This is what I am using to pull the file into the browser:
$secret_file = "../attach/1/test.pdf";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: ".mime_content_type($secret_file));
header("Content-Disposition: inline; filename=\"test.pdf\";");
header("Content-Transfer-Encoding: binary");
readfile($secret_file);
Interestingly, if I download the file this way through a browser and view its properties in linux, it shows up as "application/pdf". However, if I check the same file using PHP's mime_content_type() function, it reads as application/octet-stream.
I did confirm that checking the original file this way (before it is pulled through readfile) shows it as application/pdf.
Is there any way to use readfile() without changing mime types? Or, is there perhaps a better alternative?
EDIT
Answering some questions from the comments:
Developer Tools in Firefox reports that the inline file has a Content-Type: application/pdf header.
sha256sum of downloaded file does not match the original file. But how could readfile() (or similar) be used without changing the file?
This might be a duplicate but I have searched for the solution for so long and I still could not solve my problem. I have a localhost server where it stored some pdf files for download.
I implemented the following function to force the download:
if(isset($_POST['dlPDF']))
{
$file = $_SERVER['DOCUMENT_ROOT'] .'/Upload/'.$pdfName;
header("Content-Type: application/pdf");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$pdfName");
header("Content-Transfer-Encoding: binary");
// read the file from disk
readfile($file);
}
However I could not open the pdf file properly since it says "the pdf file is not correctly encoded".
FYI, the downloaded pdf file is always a few Kb larger than the original file.
Please kindly let me know if there is anything I can do to make the pdf readable and I appreciate your help.
I have a PHP that scans the files in a remote NAS Hard Disk via FTP protocol, generates a json file and then via javascript I list those files in the browser.
When the user click a link to a mp4, jpg and many browser-known formats, the browser opens te content instead of downloading it.
Now, I know that with PHP or .htaccess I can change the headers to force the browser to download the file but the file is in a remote location and can only be access via FTP so I can't run PHP or .htaccess in it.
I tried this header variations in PHP:
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=\"$file\"");
or
header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$file\"");
or
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Type: application/image");
header("Content-Transfer-Encoding: binary");
all ending with:
header("Location: $url");
(url being ftp://user:password#dyndns.org/folder/file.mp4)
but it always opens the file in the browser instead of downloading (on recognized file extensions of course)
Any ideas? Thanks
The previous headers may not work when using a redirect. Instead, you better serve them via PHP instead of redirecting:
header("Content-type: octet/stream");
header("Content-disposition: attachment; filename=".$file);
header("Content-Length: ".filesize($file));
readfile($file);
But note, that this WILL use your own bandwidth. However, there isn't any way to force a behavior on a remote host.
I have a php page running on an apache server and a ftp server that stores the files, on a different machine. The ftp server is not accessible from outside.
I would like that when the user clicks a button on my webpage, the php server connects to the ftp server, retrieves a file, and displays a save as dialog, so that the user can store it.
Any help is appreciated,
Radu
Here you Go.. in download.php write this
$file = 'location/of/your/file.ext';
readfile($file);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".$file);
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
This should work :)