I have some ebooks on my server, that I want people to be able to download. I uploaded them and when I download them via my ftp tool then everything is perfect. when I use my script for the user to download it, then I get the following error in calibre:
MobiError: Unknown book type: '\x00\x00\x00BOOKM'
my script that handles the output of the file is as follows:
$file_url = ABSPATH . $file['file'];
$basename = $story->post_title . $subtitle . '.' . $_POST['type'];
$filename = basename(mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $basename));
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=\"" . $filename . "\"");
readfile($file_url);
die();
Then all mobi readers I got say, that there is a problem with the file. I don't know what is going wrong. Also when I open the files in a text editor they are both different type. The one from my php script looks as follows:
the one that works from my ftp tool looks like this:
Anyone who can help me to find what I am doing wrong? The .epub files by the way are no problem with my script.
I solved this problem by outputting the file as follows:
ob_clean();
flush();
readfile($path);
exit;
Related
I am having a problem with my webpage. I am building a report tool for downloading data as .csv - I have a php skript which aggregates the data and builds a csv from it. The skript is invoked with the exec() command, detailed code is below. The skript itself uses file_put_contents() to generate the file, which is then stored in my /tmp/ folder until its downloaded (I am working in a dockerized environment and our filter rules delete the file at the next request, but I could store the file permanently somewhere else if that would be neccessary). I am then checking if the file is present with file_exists() and proceed to invoke my download function. In Firefox I get the desired result, a file with the correct content of only the csv data.
My main Problem is: When I download the csv in Chrome I get the csv data followed by the html source of my page - so starting with <!doctype html> in the first line after the csv data, then <html lang="de">in the next line of te csv and so on..
Let me show you some code:
In my skript:
private function writeToFile($csv)
{
$fileName = '/path/to/file' '.csv';
echo "\n" . 'Write file to ' . $fileName . "\n";
file_put_contents($fileName, $csv);
}
In my page class:
$filePath = '/path/to/finished/csv/'
exec('php ' . $skriptPath . $skriptParams);
if (file_exists($filePath)) {
$this->downloadCsv($filePath);
} else {
$pageModel->addMessage(
new ErrorMessage('Error Text')
);
}
My download function in the same class:
private function downloadCsv($filePath)
{
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
}
The shown above is working in Firefox, but not in Chrome. I already tried to clear the output buffer with ob_clean() or send and disable it with ob_end_flush() but nothing worked for Chrome.
I also tried something like this in my download function:
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
$fp =fopen($filePath, 'rw');
fpassthru($fp);
fclose($fp);
This produces the same results in Firefox and Chrome - I get the csv data followed by the html sourcecode mixed into the same file.
I am working within a Symfony framework if that could be from help, I saw there are some helper functions for file downloads but I so far I could not use them with success..
Until now my target is only to get the download working in Chrome to have a working mvp which can go into production - it is supposed to be for internal use only, so I don't have to care about IE or some other abominations because our staff is told to use a normal browser... But when someone sees flaws in the general concept feel free to tell me!
Thanks in advance :)
So I managed to get it working, I was on the wrong track with the output buffer, but a simple exit()after my readfile()was enough to stop parts of the html ending up in the csv file.
Code:
private function downloadCsv($filePath)
{
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit;
}
$file_name = $_GET['name'];
$file_url = $_GET['file-url'] . $file_name;
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
I'm using this code to download files in my site fetching from another web servers.
It works if my url looks like this:-
https://www.example.com/file_download.php?name=video_song.mp4&file-url=http://www.googlevideo.com/video/play/221589
So, it starts downloading by fetching the file from http://www.googlevideo.com/video/play/221589 in my site. Now, though it downloads the file correctly, it does allow the downloader to see the actual size of the file. So, downloaders having problems with it (e.g. Time Remaining, Download Percentage etc.).
So what header should I use to solve this thing? Please explain it by coding.
You may try this:
header("Content-Length: " . $filesize);
I'm having a bad time with the readfile function on php. I'm setting up a web file server, but many of the users have problems with the downloads.
Basically, I'm using Chrome on my computer and everything works fine. Some of the users have problems on Android browser: they get a .bin file instead og .doc, or get a correct .doc file, but they can't open it. Also, someone gets a corrupted .doc file on the computer.
I have read many questions on this site but they weren't so helpful.
Since I have tried many solutions, I will post a shortened code snippet to give an idea of what I am trying to accomplish. I am using apache2, couldn't it be a configuration problem?
Does someone have my problems too?
<?php
//here I take the user, the pwd and the file RELATIVE path
//there are no errors here
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: attachment; filename="' . $name . '"');
readfile($file);
?>
EDIT: full code
<?php
session_start();
$data = $_SESSION['data'];
$name = $_GET['name'];
if (isset($data)) {
//private file
$file = "path/".$data."/".$name;
} else {
//public file
$file = "path/public/".$name;
}
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . $name . "\"");
readfile($file);
?>
I'm currently having some problems with forcing a file download on a Wordpress site I'm making. On my localhost it works fine but when I try it to the live server all file downloads are broken. For instance, images are not displaying, video and audio files don't play etc.
This is my code:
$title = $query[0]->post_title;
$mimetype = $query[0]->post_mime_type;
$guid = $query[0]->guid;
$filepath = str_replace(home_url().'/wp-content/uploads/', '', $guid);
$download = ABSPATH.'/wp-content/uploads/' . $filepath;
$filesize = filesize($download);
//Download file
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.$title);
header('Content-Type: '.$mimetype);
header('Content-Transfer-Encoding: '.$mimetype);
header('Content-Length: '.$filesize);
ob_clean();
flush();
readfile($download);
exit();
If I inspect the response in Chrome it says "Failed to load response data" both in the preview and response tab.
Any ideas? any help is appreciated.
Would add this as a comment but can't. It will be using ABSPATH that's giving you grief. I'd echo out your $download path and make sure it is correct. Look here - ABSPATH or __FILE__?
<?php
header('Content-disposition: attachment; filename=Booking.pdf');
header('Content-type: application/pdf');
readfile('http://mysite.com/Booking.pdf');
?>
why is the Booking.pdf file downloaded empty!??
mac and windows both say:
The file “Booking.pdf” could not be opened because it is empty.
checked google and stackoverflow, can't find relative info... has anyone experienced this before?
ps: I only found this forum post:'The online issue is a bit off topic I think, but is generally due to loading the PDF to a server in the ASCII mode of FTP rather than binary. That creates a corrupt file. Be sure to turn on binary transmission', but this is not true in this case as i can display the same pdf file in an iframe and it is not blank/empty.
You need to change
readfile('http://mysite.com/Booking.pdf');
To
readfile(__DIR__ . '/Booking.pdf');
Example
$file = __DIR__ . '/test.pdf' ;
header('Content-disposition: attachment; filename=Booking.pdf');
header('Content-type: application/pdf');
header("Content-length: ".filesize($file));
readfile($file);