Add hotlink prevention to this php download code - php

How can I add a hotlink prevention to the following code only to be accessed by *.mydomain.com via php? Where do I add it?
<?php
$dir = 'folder';
$file = $_GET['name'];
// local file that should be send to the client
$local_file = $dir.'/'.$file;
// filename that the user gets as default
$download_file = 'video.mp4';
// set the download rate limit (=> 20,5 kb/s)
$download_rate = 200;
if(file_exists($local_file) && is_file($local_file)) {
// send headers
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);
// flush content
flush();
// open file stream
$file = fopen($local_file, "r");
while (!feof($file)) {
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
// close file stream
fclose($file);
}
else {
die('Error: File '.$local_file.' does not exist!');
}
?>
I know it must be something like
define('HOTLINK_PROTECTION',TRUE); // enable hotlinking? true/false
define('HOTLINK_PAGE_URL','http://www.mydomain.com/images/hotlink.jpg'); // Hotlink URL
$allowed_domains="*.mydomain.com, www.mydomain.com";
#checks the referer of the script
function getReferer() { preg_match('#^(?:http://)?([^/]+)#i',$_SERVER['HTTP_REFERER'], $match); return $match[1]; }
#checks if referer domain is okay
function hotlink_check() {
global $allowed_domains; $allowed_domains.=','.$_SERVER['HTTP_HOST'];
$domains=explode(',',str_replace(' ','',$allowed_domains));
$referer=getReferer(); $site=array();
foreach ($domains as $value) { $site[]='^'.str_replace('*','([0-9a-zA-Z]|\-|\_)+',str_replace('.','\.',$value)).'$'; }
foreach ($site as $pattern) { if(eregi($pattern,$referer)) $MATCH=TRUE; if($MATCH==TRUE) break; }
if($MATCH==TRUE) return TRUE; else return FALSE;
}
define('HOTLINK_PASS',hotlink_check());
if(HOTLINK_PROTECTION&&!HOTLINK_PASS&&$_SERVER['QUERY_STRING']!='admin') { header('HTTP/1.1 403 Forbidden'); header('Location: '.HOTLINK_PAGE_URL); die(); }
But where do I implement it? How can I do that?
--- Edit ---
I did it, but it doensn't work with Mozilla Firefox... With firefox it just goes directly to the hotlink image.
I've tested it with Chrome, Internet Explorer, Safari and Opera and the only one who took me to the hotlinked image was Firefox, I must be doing something wrong here.
Here's the code:
<?php
define('HOTLINK_PROTECTION',TRUE); // enable hotlinking? true/false
define('HOTLINK_PAGE_URL','http://www.site.com/images/hotlink.jpg'); // Hotlink URL
$allowed_domains="*.site.com, www.site.com";
#checks the referer of the script
function getReferer() { preg_match('#^(?:http://)?([^/]+)#i',$_SERVER['HTTP_REFERER'], $match); return $match[1]; }
#checks if referer domain is okay
function hotlink_check() {
global $allowed_domains; $allowed_domains.=','.$_SERVER['HTTP_HOST'];
$domains=explode(',',str_replace(' ','',$allowed_domains));
$referer=getReferer(); $site=array();
foreach ($domains as $value) { $site[]='^'.str_replace('*','([0-9a-zA-Z]|\-|\_)+',str_replace('.','\.',$value)).'$'; }
foreach ($site as $pattern) { if(eregi($pattern,$referer)) $MATCH=TRUE; if($MATCH==TRUE) break; }
if($MATCH==TRUE) return TRUE; else return FALSE;
}
define('HOTLINK_PASS',hotlink_check());
if(HOTLINK_PROTECTION&&!HOTLINK_PASS) { header('HTTP/1.1 403 Forbidden'); header('Location: '.HOTLINK_PAGE_URL); die(); }
$dir = 'directory';
$video = $_GET['name'];
// local file that should be send to the client
$local_file = $dir.'/'.$video;
// filename that the user gets as default
$download_file = 'video.mp4';
// set the download rate limit (=> 200 kb/s)
$download_rate = 200;
if(file_exists($local_file) && is_file($local_file)) {
// send headers
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);
// flush content
flush();
// open file stream
$file = fopen($local_file, "r");
while (!feof($file)) {
// send the current file part to the browser
set_time_limit(0);
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
// close file stream
fclose($file);
}
else {
die('Error: File '.$local_file.' does not exist!');
}
?>

I had the same problem
it was that I used my entire domain name in the file url instead of a relative path..
//download image now
$file_name = "test.jpg";//$_GET['f'];
$file_url = "http://www.example.com/yfolder/". $file_name; //WRONG
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header('Content-Type: image/jpg');
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
correct code
//download image now
$file_name = "test.jpg";//$_GET['f'];
$file_url = "yfolder/". $file_name; //i removed my domain and it worked, i managed to download the actual image instead of the hotlinked image
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header('Content-Type: image/jpg');
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);

Related

Unable to view the download PDF file in browser in php

I have a download media function in which all type of media files gets downloaded. Below is the code
public function downloadMedia($file, $filename_direct = '', $extern = '', $exitHere = 1)
{
jimport('joomla.filesystem.file');
clearstatcache();
if (!$extern)
{
if (!JFile::exists($file))
{
return 2;
}
else
{
$len = filesize($file);
}
}
else
{
/* Return the size of a remote url or a local file specified by $url.
$thereturn specifies the unit returned (either bytes "", MiB "mb" or KiB
"kb"). */
$len = filesize($file);
}
$filename = basename($file);
$file_extension = strtolower(substr(strrchr($filename, "."), 1));
$ctype = $this->getMime($file_extension);
ob_end_clean();
// Needed for MS IE - otherwise content disposition is not used?
if (ini_get('zlib.output_compression'))
{
ini_set('zlib.output_compression', 'Off');
}
header("Cache-Control: public, must-revalidate");
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header("Expires: 0");
header("Content-Description: File Transfer");
header("Content-Type: " . $ctype);
header("Content-Length: " . (string) $len);
header('Content-Disposition: attachment; filename="' . $filename . '"');
// set_time_limit doesn't work in safe mode
if (!ini_get('safe_mode'))
{
#set_time_limit(0);
}
/*#readfile($file);
if ($exitHere == 1)
{
exit;
}*/
$fp = fopen($file, "r") ;
ob_clean();
flush();
while (!#feof($fp)) {
$buff = #fread($fp, $len);
print $buff;
}
exit;
}
Now the issue is, whenever I download the PDF file & clicked on downloaded file it shows an error in a browser like 'Failed to load PDF document.'
The downloaded PDF file is opened correctly only when if I open the file in adobe instead of opening it in browser.

PHP: Download file from Server

I have tried all sorts of codes I've found but nothing has worked for me...
When I use readfile() or fopen() or something like this:
function makeDownload($file, $dir, $type) {
header("Content-Type: $type");
header("Content-Disposition: attachment; filename=\"$file\"");
readfile($dir.$file);
}
... A download is started but the file is always empty...
here's the last code I've tried:
$filename = "gandalf.jpg";
// define error message
$err = '<p style="color:#990000">Sorry, the file you are requesting is unavailable.</p>';
if (!$filename) {
// if variable $filename is NULL or false display the message
echo " filename NULL";
echo $err;
} else {
// define the path to your download folder plus assign the file name
$path = 'upload/'.$filename;
// check that file exists and is readable
if (file_exists($path) && is_readable($path)) {
echo "file exists";
// get the file size and send the http headers
$size = filesize($path);
header('Content-Type: image/png');
header('Content-Length: '.$size);
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: binary');
// open the file in binary read-only mode
// display the error message if file can't be opened
//readfile($path.$filename);
$file = # fopen($path, 'rb');
if ($file) {
// stream the file and exit the script when complete
fpassthru($file);
exit;
} else {
echo $err;
}
} else {
echo $err;
}
}
This is the source of my code: Source code
I hope you can help me :)
I use google chrome
I need your help for this little project: Link to Project
When you click on a file in the drop down appears "herunterladen" (download in german) here is where I want to start the php download code
I just need the most basic download function for PHP... why is there an upload example on w3schools but NOT a download example? oO
$fileSource= $_GET['fileSource']; //If you are passing the filename as a URL parameter
$fileSource= "sample.pdf" //If the filename is fixed in the current folder
if($fileSource) {
$filesize = filesize($fileSource);
$path_parts = pathinfo($fileSource);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-Disposition: attachment;
filename=\"".$path_parts["basename"]."\""); // use 'attachment' to
force a download
header("Content-type: application/pdf"); // add here more headers
for diff. extensions
break;
default:
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
if($filesize) {
header("Content-length: $filesize");
}
readfile($fileSource);
exit;
}

Create Download Link PHP

I had a problem with my code . when I click the button to download the picture , it appears the code that I do not know, how to solve this ? what is wrong with my code ?
--> Download.php
if (isset($_GET['file']) && basename($_GET['file']) == $_GET['file']) {
$filename = $_GET['file'];
} else {
$filename = NULL;
}
// define error message
$err = '<p style="color:#990000">Sorry, the file you are requesting is unavailable.</p>';
if (!$filename) {
// if variable $filename is NULL or false display the message
echo $err;
} else {
// define the path to your download folder plus assign the file name
$path = '../images/upload/lowongan_pekerjaan/'.$filename;
// check that file exists and is readable
if (file_exists($path) && is_readable($path)) {
// get the file size and send the http headers
$size = filesize($path);
header('Content-Type: application/octet-stream');
header('Content-Length: '.$size);
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: binary');
// open the file in binary read-only mode
// display the error message if file can't be opened
$file = #fopen($path, 'rb');
if ($file) {
// stream the file and exit the script when complete
fpassthru($file);
exit;
} else {
echo $err;
}
} else {
echo $err;
}
}
why show like this?
My Picture
whats wrong with my code?
header('Content-Type: application/octet-stream');
header('Content-Length: '.$size);
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: binary');
should be
header('Content-Type: image/jpg');
header('Content-Length: '.$size);
header('Content-Disposition: attachment; filename='.$filename);
or png or gif or whatever your file type is.. the browser does not know how to handle what you are sending it because application/octet-stream != an image type.

How can I add a download speed limit to this php script?

I found this great script to download and protect the files from a directory:
http://www.gowondesigns.com/?page.getfile
And I saw this code from a website too:
// local file that should be send to the client
$local_file = 'test-file.zip';
// filename that the user gets as default
$download_file = 'your-download-name.zip';
// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file)) {
// send headers
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);
// flush content
flush();
// open file stream
$file = fopen($local_file, "r");
while (!feof($file)) {
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
// close file stream
fclose($file);
}
else {
die('Error: The file '.$local_file.' does not exist!');
}
How can I combine them? I mean how can I use the getfile script and add a download rate to it?
I tried adding:
while (!feof($file)) {
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
But instead of $file I think it should be $fd and I had no positive results
What am I doing wrong?
Based on your comment - I assume you want the following:
// open file stream
$file = fopen($local_file, "r");
while (!feof($file)) {
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
// close file stream
fclose($file);
You should note, however, that it is the whole script that will make it successfully prompt a user to download the file and speed limit it. Simply rename the first script in your question as download.php, then link to it as <a href='download.php?id=1'>Download 1</a> (then file ID 1 will download).
<?php
$file_id = $_GET['id'];
if($file_id == 1){
// local file that should be send to the client
$local_file = 'test-file.zip';
// filename that the user gets as default
$download_file = 'your-download-name.zip';
} else {
die('Invalid file selected for download');
}
// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file)) {
// send headers
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);
// flush content
flush();
// open file stream
$file = fopen($local_file, "r");
while (!feof($file)) {
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
// close file stream
fclose($file);
} else {
die('Error: The file '.$local_file.' does not exist!');
}
?>
<?php
$file = #$_GET["file"];
$rate = 100; // kb/sn
if (!file_exists($file)) {die("File Not Found");}
header("Content-Disposition: attachment; filename=" . $file);
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
echo fread($fp, $rate * 1024);
flush();
sleep(1);
}
fclose($fp);
?>
i use this . And no problem.

How to support IDM without allow request the page two times

I got this error ,as the above image show, while trying to download a file by IDM from my site. the limit of requesting this page one time only after entering Captcha Code and if you request the page again must enter the captcha code again.
How to support IDM in this case
The download code as the following
$file='test.mp3';
$download_rate = 50; //50 kb/s
if(file_exists($file) && is_file($file))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($file));
header('Content-Disposition: filename='.$file);
flush();
$file = fopen($file, "r");
while(!feof($file))
{
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
fclose($file);
}
else {
echo 'File Not Found';
}
Use xsendfile. A mod for apache
https://tn123.org/mod_xsendfile/

Categories