I have written a small download portal and I use application/octet-stream to download the files.
function fu($filename)
{
header("Content-Type: application/octet-stream");
$save_as_name = basename($filename);
header("Content-Disposition: attachment; filename=\"$save_as_name\"");
readfile($filename);
}
When I am downloading a large file it is not possible to browse through the directory tree until the download has finished.
Is there any chance to do this in parallel?
You're probably using sessions. While you have a session open in Window A which is busy serving the download Window B will not be able to get any pages because the PHP process serving A still has the session data open/locked and B is waiting on that lock to be released.
The simple solution is to call session_write_close() at some point before you call readfile(). This will commit the session to disk on the server, close it, and release the lock so other PHP processes can pick it back up.
Related
following issue:
I have a large file on my server (~2GB).
A user who is logged in to my site can download this file from my server.
Unfortunately my server is not that strong. When many user downloading this file simultaneous they will all have very poor dl speed.
So I uploaded the file to google drive and generated a direct download link:
http://googledrive.com/host/[FILE_ID]
My code:
<?php
$remoteFile = 'http://googledrive.com/host/[FILE_ID]';
$filename = basename($remoteFile);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$filename\"");
echo file_get_contents($remoteFile);
?>
My question: is file_get_contents() really bypassing the dl or is this file going thru my server? If so, that makes no sense :[ ]
Generate a unique google drive share link after every download, so that only your authenticated users can download, and links may not be used more than once.
Im using fopen to let users download a audio in the code below as the code attribute doesn't always works in all situations and browsers.
Does this downloads the file to my server temporarily or lets the user download it from the external sourced
<?php
$file=fopen('link','r');
header("Content-Type:audio/mp4");
header("Content-Disposition: attachment; filename='example.m4a' ");
fpassthru($file);
?>
All the data will be read (from wherever the file handle points) by your PHP program on your server. That may involve copying data from a remote URL to your server. That data may exist entirely in RAM. It may hit swap space on the disk.
The PHP program then outputs it to the browser.
The browser never has direct access to 'link'.
I have "Files Downloading Center" for large files (100MB - 2GB).
I'm using PHP.
My problem is when forcing files to download by using php headers the server memory consumed very much, although I make chunks from file when download process, that is mean when 5 users download large file at the same time the server will stop to work.
How to make users to download large files form my server without any problem.
For example, if i use header("location : path/to/files/2GB.zip");, the problem finish. but this is what i don't need because i don't need to give users direct link to the files for security.
What is solution ?
You could store the files outside of your web path, then include the files at the time of download, using the header function to deploy it to the user. This is a little over-killie, but it works:
$getFiles = fread($FILEHANDLE,$FILESIZE);
header("Content-Transfer-Encoding: Binary");
header("Content-length: ".$FILESIZE."");
header("Content-type: ".$FILETYPE."");
header('Content-Disposition: attachment; filename="'.$FILENAME.'"');
echo $getFiles;
This consumes more memory as you're reading the file on the server before you transfer it, but your downloaders will never know where the files live. YMMV with very large files for obvious reasons.
I'm developing a web service. With this service, user's will upload their .php files, and service will remove UTF8 BOM characters from php file. And then, There will be a link like this :
Download Your File
But when i click this link, browser browsing to this file. I don't want browse it, i want to download it. So , when user click this link, downloading will start.
Any ideas ?
(P.S. I don't want modify uploadedfile.php file, also i read 5 questions about this, but still i have problem.)
You need to supply this HTTP header:
Content-Disposition: attachment; filename=example.txt
You can usually specify this for entire directories at a time by configuring your web server appropriately. If you mention which web server you are using, somebody may be able to suggest how to do this.
The problem is that you're allowing people to upload PHP files on your server, then giving them a link to execute that PHP file. The web server is automatically treating those uploaded PHP files like any other PHP file, i.e. executing it, which opens you up to a massive security hole.
Whatever purpose your web service has, I'd suggest renaming the file on your server when it is uploaded (something 'random' is best, without an extension), then having a PHP script feed it back out with the appropriate headers set when it is requested.
The URL for such a script would look like:
http://www.example.com/get_uploaded_file.php?id=jgh3h8gjdj2389
It would link the value in id with the file on the server, and if you've saved the original filename somewhere (flat file, DB), you can serve it out using its original name, so long as you set the right HTTP headers.
Linking directly to the PHP file may end up executing it. One way is (like somebody above suggested) to rename it. Or, you can have a downloader.php which does below:
<?php
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jan 2000 01:00:00 GMT'); // some date in past
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename='.basename($filepath));
header('Content-Length: ' . filesize($filepath));
flush(); // or any other flush function/mechanism you use.
readfile($filepath);
and link it something like:
Download
This method will let you retain the .php extension. Also, if the PHP file is big and connection is slow, they progress-bar would be accurate (because you've flushed the content length upfront.
Firstly: I'm a lowly web designer who knows just enough PHP to be dangerous and just enough about server administration to be, well, nothing. I probably won't understand you unless you're very clear!
The setup: I've set up a website where the client uploads files to a specific directory, and those files are made available, through php, for download by users. The files are generally executable files over 50MB. The client does not want them zipped, as they feel their users aren't savvy enough to unzip them. I'm using the php below to force a download dialogue box and hide the directory where the files are located.
It's Linux server, if that makes a difference.
The problem: There is a certain file that becomes corrupt after the user tries to download it. It is an executable file, but when it's clicked on, a blank DOS window opens up. The original file, prior to download opens perfectly. There are several other similar files that go through the same exact download procedure, and all of those work just fine.
Things I've tried: I've tried uploading the file zipped, then unzipping it on the server to make sure it wasn't becoming corrupt during upload, and no luck.
I've also compared the binary code of the original file to the downloaded file that doesn't work, and they're exactly the same (so the php isn't accidentally inserting anything extra into the file).
Could it be an issue with the headers in my downloadFile function? I really am not sure how to troubleshoot this one…
This is the download php, if it's relevant ($filenamereplace is defined elsewhere):
downloadFile("../DIRECTORY/files/$filenamereplace","$filenamereplace");
function downloadFile($file,$filename){
if(file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
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));
# flush();
readfile($file);
exit;
}
}
ETA Additonal Info:
- Tests for working/non-working files have been done on the same machine
- If it makes any difference, the original file has a custom icon. After download, the file has a generic blank document icon.
Additonal Info: I THINK THIS ONE'S IMPORTANT!
I just tried downloading the file directly (to bypass the download link that triggers the download function above). If I download the file by just going to its url and downloading it that way, the downloaded file WORKS. So I'm thinking it must have something to do with the download function. But what??
3/17 MAJOR CORRECTION —AND RESOLVED—
So I woke up this morning and it dawned on me that maybe I was comparing the files wrong. (I had re-saved them as binary text, and then compared them. I didn't realize the comparison program would take and compare actual exe files). This morning I tried comparing the actual exe files and there is a difference. There was one line of php code that was being injected into the first line of the file. I adjusted the php, and the problem was fixed. (It was from the if/else statement that defined teh $filenamereplace variable in the code I'd cited). Thanks again for all your help, and sorry for misleading you in insisting that the files' contents were identical!
"I've also compared the binary code of the original file to the downloaded file that doesn't work, and their exactly the same (so the php isn't accidentally inserting anything extra into the file)."
If that's really true, then the problem must be in how the exe is started after it has been downloaded. It should certainly not be a problem with your PHP code.
Perhaps they were corrupted on upload. This can happen if you transfer them via FTP in ASCII mode instead of BINARY.