Php download from hashed pathfile - php

I'm having trouble with downloading a file from a hashed filepath.
I'm using a MySQL database where I store various data from a HTML form. It is possible to upload up to three different files. These are moved to a uploads folder on the server. I’m using MD5 to prevent duplicate file uploads.
All the data in the database gets called from an other script. There is an amount of download links shown, depending on how much files are uploaded. Im using fileinfo and headers to determine the mimetype and to download the file. But all I get when downloading is some zipfile with random folders and documents or a non-extension file which, giving the right extension, opens with warnings and ultimately shows the correct file.
Here is my download code:
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
print("</br>"); echo finfo_file($finfo, $_GET["fName"]);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= ". $_GET["fName"]);
header("Content-Type: " .$finfo);
finfo_close($finfo);
header("Content-Transfer-Encoding: binary");
// Read the file from disk
readfile($_GET["fName"]);
The $_GET["fName"] is a variable passed by a link which contains the specified pathname(example: ./uploads/hashcode). How can I make this so that I can download the document correctly? As in download the document whole, not some ZIP file or a non-extension file.
I’ve been fighting with this problem for some days now (searched on internet to find something usable) and im getting quite desperate.
Additional note: Most times the file that downloads is the correct file from my server. It has the same name as the hash files in the uploads folder. But it doesnt have any extension.

Let's say $_GET["fName"] is /uploads/randomhash/ABCDEFABCDEFABCDEF.zip
header("Content-Disposition: attachment; filename= ". basename($_GET["fName"]));
This would make the server to name downloadable file as ABCDEFABCDEFABCDEF.zip
If you have saved your files without extension, then you might have a problem.
If you have the orginal filename saved in database maybe you could add extra $_GET['orginalFilename'] to your links and use that to generate right filename with extension.
Also you are setting headers. They aren't being set correctly if you output anything before them. Here you print and finfo_file. You shouldn't do that.
I think you want something like this, but you have to figure out how to get right filename to the filename= part in header.
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= ". basename($_GET["fName"]));
header("Content-Type: " . finfo_file($finfo, $_GET["fName"]));
finfo_close($finfo);
header("Content-Transfer-Encoding: binary");*/
// Read the file from disk
readfile($_GET["fName"]);

Related

PHPWord any way to not write file to disk when downloading file

I'm using PHPWord to generate Word documents, and I'm hoping someone can help on this. The way its set up now, an ajax request is sent to my server from the browser requesting the PHPWord document to be built. The document is built, and stored in a file on the server with this code:
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$fileName = $picklistDetails['file_name'] . ".docx";
$filePath = '../users/' . $userId . "_word_" . $fileName;
$objWriter->save($filePath);
To allow the user to download the file, once the ajax request succeeds i use window.location to send the user to a page that puts the word document together with this (allowing the download to commence):
$fileName = $this->session->word_file_name;
$filePath = $this->session->word_file_path;
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=" . $fileName);
header("Content-Transfer-Encoding: binary");
readfile($filePath);
This all works great, the only problem is i would really rather the file not have to be saved to the server before the download. I've been researching PHPWord and as per this post (Auto download the file attachment using PHPWord) theres some discussion of how you can send the file to php's output stream instead of writing it to disk, but because building the word document is done in ajax and then a separate page is used to download it, i don't think this would work. Am i wrong?
Also in this post (Save Generated File to database PHPWORD) there is a description of how to store it to a DB, but there's still the intermediate step of a file on the server, which i need to avoid.
Is there some way I can modify
$objWriter->save($filePath);
to not write it to disk and instead save it to a variable or something? Then I could maybe store in a database where I could encrypt it.
Any help would be appreciated. I'm kind of a beginner php programmer so detailed help would be much appreciated. have a good day.
Should be as simple as doing $objWriter->save("php://output");:
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$fileName = $picklistDetails['file_name'] . ".docx";
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=" . $fileName);
header("Content-Transfer-Encoding: binary");
$objWriter->save("php://output");
Skip the redirect entirely. Just window.location directly to the above code ^ and the file should download once it's done building.

PHP send file only containing the extension

I have some problems with sending files with PHP. I would like to send a file named .version (Note the dot and nothing infort of it). The file is sent correctly but my browser renames it to version. Therefore the file looses its functionality. The file has to be named like this.
This is the code I use:
<?php
header("Content-Description: File Transfer");
header("Content-Type: text/version");
header("Content-Disposition: attachment; filename=\".version\"");
header("Content-Length: " . filesize($file));
readfile($file);
exit();
?>
$file is the correct internal path to the file.
Other headers like the expires header are set in my server config.
If there is information missing I will add if if you ask for it!

Writing into txt file return empty on IE

I have a code that save the data of a form into a TXT file and it seems like Internet Explorer can't read the file once it is closed.
The file is successfully saved in my folder and when I load it from the FTP I can see my values, but when I do readfile() on the "submit", the donwloadable file is empty from data.
Here is my code :
$fp = fopen("plan_de_concepts/". $nom_du_fichier, "w");
$savestring = "$sujet=*|*=$concept1=*|*=$concept2=*|*=$concept3=*|*=$c1mc1=*|*=$c1mc2=*|*=$c1mc3=*|*=$c1mc4=*|*=$c1mc5=*|*=$c2mc1=*|*=$c2mc2=*|*=$c2mc3=*|*=$c2mc4=*|*=$c2mc5=*|*=$c3mc1=*|*=$c3mc2=*|*=$c3mc4=*|*=$c3mc5=*|*=$c4mc1=*|*=$c4mc2=*|*=$c4mc3=*|*=$c4mc5=*|*=$c5mc1=*|*=$c5mc2=*|*=$c5mc3=*|*=$c5mc3=*|*=$c5mc4=*|*=$c5mc5=*|*=$c6mc1=*|*=$c6mc2=*|*=$c6mc3=*|*=$c6mc4=*|*=$c6mc5";
fwrite($fp, $savestring);
fclose($fp);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Length: ". filesize($nom_du_fichier));
header("Content-Disposition: attachment; filename=". $nom_du_fichier);
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
readfile('plan_de_concepts/'.$nom_du_fichier);
Works great on Firefox and Chrome but IE return empty.. Is there any ways I could force to donwload the "uploaded" version of the file?
You use filesize($nom_du_fichier) and readfile('plan_de_concepts/'.$nom_du_fichier) (note the folder-prefix). I expect only one of the files exists.
It looks like IE is actually using the Content-Length-header where FF is silently ignoring it.
My Content-length was different of the file exact path. Internet Explorer could not find the file to read it.
It should be noted that in the example:
header('Content-Length: ' . filesize($file));
$file should really be the full path to the file. Otherwise content
length will not always be set, often resulting in the dreaded "0 byte
file" problem.
Source : PHP readfile returns zero length file

Force download file that's not placed on the server

I'm trying to force download a pdf file that I'm generating. I don't need the pdf file to be actually saved on the server.
So when I generate my pdf file, I get the file content. I then encode it with base64. Now the problem is that I need to force download it. I've looked all over the web, but I haven't found any search results that tells me how to do this without the file actually being placed on the site.
I've tried the following code:
header("Content-type: application/pdf");
header("Content-disposition: attachment; filename=\"invoice.pdf\"");
header("Content-Length: ".filesize($pdffile));
readfile(base64_decode($pdffile));
But, it's giving me a corrupt pdf file, (1 kb). The actual file should be around 50kb.
Any ideas, as to what I can try?
readfile trying to output content from file, but you have only data string. Try this instead:
header("Content-type: application/pdf");
header("Content-disposition: attachment; filename=\"invoice.pdf\"");
echo base64_decode($pdffile);
I also suggest rename $pdffile to $pdfcontent for even better clarification.

Mime-type of downloading file

i'm trying to create downloadable video-files. In my site there is a list of files.
All videos are in .flv-format (flash). There is exact link to the file for the all videos.
But in all browsers after clicking content is loading to the browser`s window. I needn't in this. As i understand i should create redirect-page wich contains mime-type of the download file. What exactly should i do?
Language: php
The recommended MIME type for that is application/octet-stream:
The "octet-stream" subtype is used to indicate that a body contains arbitrary binary data. […]
The recommended action for an implementation that receives an "application/octet-stream" entity is to simply offer to put the data in a file, with any Content-Transfer-Encoding undone, or perhaps to use it as input to a user-specified process.
Create a PHP page with the following:
<?php
$filepath = "path/to/file.ext";
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$filepath");
header("Content-Type: mime/type");
header("Content-Transfer-Encoding: binary");
// UPDATE: Add the below line to show file size during download.
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
?>
Set $filepath to the path of the file to be downloaded, and set Content-Type to the mime type of the file being downloaded.
Point the "download" link to this page.
For multiple files of the same type:
<?php
$filepath = $_GET['filepath'];
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$filepath");
header("Content-Type: mime/type");
header("Content-Transfer-Encoding: binary");
// UPDATE: Add the below line to show file size during download.
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
?>
Replace the information as specified above, and point the "download" link to this page with a GET parameter named "filepath" containing the file path.
For example, if you name this php file "download.php", point the download link for a file named "movie.mov" (in the same directory as download.php) to "download.php?filepath=movie.mov".

Categories