Downloads Stops At 2GB For Some Users - php

I have a website that offer downloads of some large files, up to 10gb.
There is an issue with the downloads that doesn't happen to me, and actually doesn't happen to most of my users, but I keep getting messages from some users that their downloads stop at 2gb, and the file is larger that that.
I serve the downloads using nginx XSendfile with php:
header('X-Accel-Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $this->getFileSize() );
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Accept-Ranges: bytes');
header('X-Accel-Buffering: yes');
header('X-Accel-Redirect: ' . $this->getServeDownloadLocation());
Running on CentOS 6.6, php 5.5.22, nginx 1.6.2.
Notice: the users don't use old browsers, they use modern browsers like Google Chrome.

Related

How to force download file in php server with mobile?

if(file_exists($file_name)) {
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.basename($file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
exit;
}
I'm trying to force download files in php server. I've provided my code and it works well when browsed with desktop browsers. I face downloading issues when I try to download files with mobile browser. In mobile, chrome browser throws me an error saying 'server problem' while firefox browser downloads the file with .htm extension. Although my default mobile browser downloads the file successfully. How can I achieve the functionality successfully irrespective of the browsers ?

php header issue when downloading zip

I'm trying to make php download a .zip file using this code:
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: ' . filesize($file));
readfile($file);
$file is right.
I have two problem with this script:
If I use header('Content-Length: ' . filesize($file)); the download is corrupt with 0 bytes file.
If I comment this line, the download looks good on ubuntu.
If I use mac OS to download this file, after opening the .zip it extracts .cpgz file (for what I read is when the zip is corrupt)
I've tried all kind of headers to make this work, but the problem is always on that header.
My question is: how can I make this work on all OS?
I use this for the purpose of downloading any kind of file using one generic PHP-script:
$base = "/path/to/downloadable/files";
$file = "myArchive.zip"; // or anything else
if(file_exists($base.$file)){
header('Content-Description: Download');
header('Content-Type: '.mime_content_type($base.$file));
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Length: ' . filesize($base.$file));
echo file_get_contents($base.$file);
}
This works fine for me with almost every kind of file (including .zip).

How to prevent documents from direct access

Hi we have a web application with document repository in php and web server is apache. How can I prevent access to these documents file directly using url, so that only our users can acceess the documents after login. The url for accessing the documents is also being displayed in google search result.
Don't store your files in your web root. Keep them outside of your web root and refer to them via a PHP file. That file will authenticate the user to verify that you want them to be able to download the file and allow them to see it. Otherwise it will prevent the from occurring or load an error message instead.
HTML:
Download
Sample PHP (download.php):
<?php
if (!isset($_SESSION['authenticated']))
{
exit;
}
$file = '/path/to/file/outside/www/secret.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
?>

Force directly linked file to download

Is there any way to provide a direct link to a file and force the browser to download it using PHP?
E.g http://www.website.com/directory/file.jpg
We're dealing with huge files here and Chrome in particular seems to have a problem rendering the image, so all the user sees is a blank screen when visiting the file directly. Even though they can still right-click in the blank screen and download the file it's confusing.
We used to output the files from PHP but we ran into memory problems so switched to providing a direct link instead. The files go up to about 5GB, they aren't all images. We have zips, PDFs, PSDs etc.
Currently, the file is requested through a PHP script which accepts the ID of the file and get its URL. The PHP script then redirects to the user to full URL of the file.
How can we ensure that downloads are forced and we don't run into memory issues with the larger files?
Thank you
Just use X-Sendfile but you need to configure it first ... using XSendFilePath
if (file_exists($file)) {
header("X-Sendfile: $file");
header("Content-Type: application/octet-stream");
header(sprintf("Content-Disposition: attachment; filename=\"%s\"", basename($file)));
exit();
}
Note* Please ensure $file is properly escaped before you verify and serve the file
XSendFilePath only works on Apache for other servers please see : Caching HTTP responses when they are dynamically created by PHP
You need to set the headers for force download
$file = 'upload_directory_path/'.$image_name;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
<?php
//file path
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}

How to securely store/serve files on a webserver via PHP that are only accessible via a secure login area?

I am currently creating a PHP website which allows administrators to upload a variety of documents (pdf,doc,docx,xls) which can then be downloaded at a later date. These can only be accessed by administrators after they have logged in. Up until this point to do this I have been storing files above the web root and then using PHP to access and serve the file via a PHP script hence preventing direct access to the files. This does work but never seems like an ideal way to do it as it's reliant on setting the correct headers via PHP for the file download which does not always give the correct results on all browsers. I can't really see any other way of doing it that would also stop the files being publically accessible if they knew where they were located.
What process would you usually use to store and serve files on a web server that should not be publically accessible?
Sample PHP:
<?php
if (TRUE === $_SESSION['logged_in']) {
}
$file = '/full/path/to/useruploads/secret.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
?>

Categories