Secure Direct File Downloader PHP Needs Fixes - php

Unfortunately, This code isn't working because i wanna download files through php and need to hide the direct path of files uploaded in my server.
If i define complete path in variable.. example.com/files/filedownload.iso then it's working but it's pointless, because i wanna hide a path while downloading.
<form target="_blank" id="download_file" action="download.php" method="post">
<input name="ip" type="hidden" value="192.123.23.1">
<input name="filename" type="hidden" value="filedownload.iso"'; ?>
<div align="center">
<input alt="Submit" src="download.gif" type="image" />
</div>
</form>
The above code is POST method..
<?php
if(isset($_POST['ip']) && $_POST['ip']!="" && isset($_POST['filename']) && $_POST['filename']!=""){
$filename = $_POST['filename'];
}
$domain="http://example.com/".$filename;
//$redirect_url="http://example.com".$filename;
$redirect_url=$path;
$redirect_url= encrypt_download_link($domain,$path);
?>
<script type="text/javascript">
var max_time= 5; //Seconds
function Redirect()
{
window.location="<?php echo $redirect_url; ?>";
}
function refresh_remaining_time()
{
max_time = max_time-1;
if (max_time>=0) {
document.getElementById("waiting_time_span").innerHTML = max_time+" Seconds";
}
}
window.onload = function() {
setInterval(function () {
if (max_time>=0) {
refresh_remaining_time();
}
}, 1000); // Execute somethingElse() every 2 seconds.
setTimeout(function () {
Redirect();
}, 5000);
};
</script>
<?php
}
function encrypt_download_link($domain,$path){
$secret = '4rTyHHgtopSUm';
$expire = strtotime("+7 days");
$md5 = base64_encode(md5($secret.$path.$expire,true));
$md5 = strtr($md5, '+/', '-_');
$md5 = str_replace('=', '', $md5);
$url = $domain.$path."?st=".$md5."&e=".$expire;
return $url;
}
?>

I'm not sure if this would work for you, and it won't work for large files, but if you redirect users to a page with this code it will stream the file in binary down to their system. Don't be a hater if your files are larger and this won't work :)
P.S. I'd love to take credit for this, and I searched for the source (couldn't find it), but this hit my library at someone else's suggestion a few years back.
$nameFile = 'insert just name of file here'
$pathFile = 'insert file and path here';
$sizeFile = filesize($pathFile);
$pointerFile = fopen($pathFile, "rb"); // Open file for reading in binary mode
$contentFile = fread($pointerFile, $sizeFile);
fclose($pointerFile);
header("Content-length: ".$sizeFile);
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=".$nameFile.";" );
echo $contentFile;

Related

Problem with PHP paths: does not see the directory and files in it

I have forms.
On the forms should be adding files to the Files folder. (It works, but there is a problem) when I only add a file, it is not added, this error appears instead:
Warning:Cannot modify header information -headers already sent by (output started at Q:\home\rat\www\pr5\files.php:1) in Q:\home\rat\www\pr5\files.php on line 10
The file of the file in the Files folder (it does not work: constantly writes that the file exists, even if there is no such file)
The image of the added files (it works too)
Deleting files (it does not work completely, the files are not deleted), this error appears:
Warning: unlink(files/Удалить) [function.unlink]: No such file or directory in Q:\home\rat\www\pr5\files.php on line 61
What is the problem with the paths of me? I can not understand. I did everything on the textbook, but does not work ...
files.php
<?
class Files {
public $files;
function __construct() {
$this->files = scandir("files/");
}
function redirect($url) {
header('Location: '.$url);
}
function counter() {
$filename = "count.txt";
if(file_exists($filename)) {
$h = fopen($filename, "r+");
$Content = fread($h, filesize($filename));
fclose($h);
$text = $Content + 1;
} else {
$text = 1;
}
$h = fopen($filename, "w");
if(fwrite($h, $text)) {
echo "Вы $text-й посетитель сайта =)";
} else {
echo "Что-то не работает на сайте! =(";
echo "Надо напрячь прогера!";
}
fclose($h);
echo "<hr>";
}
function upload() {
if($_FILES['myfile']) {
$uploaddir = 'files/';
$destination = $uploaddir.$_FILES['myfile']['name'];
if(move_uploaded_file($_FILES['myfile']['tmp_name'], $destination)) {
$this->redirect('/pr5');
} else {
return "error <br>";
}
}
}
function search() {
if($_POST['searchname']) {
$folder = "files/";
$file = $searchname;
$file = $folder.$file;
if(file_exists($file)) {
print "Файл существует";
} else {
print "Файл не существует";
}
}
}
function delete() {
if($_POST['delete']) {
unlink("files/".$_POST['delete']);
$this->redirect('/pr5');
}
}
}
?>
index.php
<?
include "files.php";
$f = new Files;
if($_FILES['myfile']) {
$f->upload();
}
if($_POST['delete']) {
$f->delete();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pr5</title>
</head>
<body>
<?
$f->counter();
?>
<form enctype = "multipart/form-data" method = "post">
<input type = "hidden" name = "MAX_FILE_SIZE" value = "30000" />
<input type = "file" name = "myfile" /><br>
<input type = "submit" value = "Отправить" />
</form>
<hr>
<form enctype = "multipart/form-data" method = "post">
<input type = "text" name = "searchname" /><br>
<input type = "submit" value = "Найти" />
</form>
<?
if($_POST['searchname']) {
$f->search();
}
?>
<hr>
<?
if(count($f->files) > 2) {
?>
<form method = "POST">
<table>
<tr>
<th>Имя</th>
<th>Удалить</th>
</tr>
<?
foreach($f->files as $s) {
?>
<?
if($s != '.' and $s != '..') {
?>
<tr>
<td> <?
echo $s;
?> </td>
<td>
<button type = "submit" name = "delete" value = "<? echo $s; ?>">Удалить</button>
</td>
</tr>
<?
}
?>
<?
}
?>
</table>
</form>
<?
}
?>
</body>
</html>
Okay, let's check this error more closely.
Warning: Cannot modify header information -headers already sent
PHP cannot modify headers - so the point where it realizes something's amiss is when it calls the header() function - because
output started at Q:\home\rat\www\pr5\files.php:1)
So, in that file, at row 1, there is something output. Something that's not PHP.
What appears to be line 1 is just
<?
which should have been perfectly copacetic (well, actually you'd better take the habit of using long tags, so, "<?php", since that's the established standard).
I am therefore betting something that in that line, unless there is an empty line before it of course, there is something you cannot see. My money is on a BOM: three invisible bytes that tell the operating system that file is coded in UTF8 with specific characteristics.
Usually, your editor should have an option to create files without a Byte Order Mark.

How to get my .php site to refresh when the contents of the .txt file is modified

I have a .php file that displays a .txt from my FTP server to a webpage.
My problem is that I want to get the .php page to refresh when something is added to the .txt file.
Right now I'm using this:
<?php
header("Refresh: 5; URL=$url1");
include('filename.txt');
?>
Which refreshes the page every five seconds to see if the .txt file is modified. I dislike this method because it spams my logs of who is viewing the webpage with the same information.
I was wondering if I could modify the .php to refresh only filename.txt is modified.
Use filetime() for this. http://php.net/manual/en/function.filemtime.php
Example from there
<?php
// outputs e.g. somefile.txt was last modified: December 29 2002 22:16:23.
$filename = 'somefile.txt';
if (file_exists($filename)) {
echo "$filename was last modified: " . date ("F d Y H:i:s.", filemtime($filename));
}
You can use a logic combination of PHP and Javascript (more specifically JQuery) with a trick. Of course this is a work-around approach (can be modified to make it better).
Pseudo-example can be like:
// A new PHP file "proxy.php"
<?php
if (!empty($_GET) && !empty($_GET['check'])) {
$previouslyChecked = $_GET['check'];
if (filemtime("filename.txt") > $previouslyChecked) {
echo 1;
} else {
echo 0;
}
die();
}
// Your PHP File
<html>
<head>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<?php
include('filename.txt');
$lastModified = filemtime("filename.txt");
?>
<input type="hidden" id="loadedAt" value="<?php echo $lastModified; ?>"/>
<script type="text/javascript">
function reloadPage(){
console.log("within reload");
window.location.reload();
}
function checkFile(){
console.log("checkfile");
jQuery.ajax({
type: "GET",
url: "proxy.php",
data: {check: jQuery("#loadedAt").val()},
success: function(data){
if (data == 1) {
console.log("reload called");
reloadPage();
}
setTimeout(checkFile, 5000);
}
});
};
jQuery(document).ready(function(){
console.log("checkfile called");
checkFile();
});
</script>
</body>
</html>
Hope this may work.

I'm not getting flush to work

I have the following script:
function follow($file)
{
$currentSize = filesize($file);
$size = $currentSize;
$index=0;
while ($index<$currentSize) {
//echo "ENTERING LOOP!!!!";
clearstatcache();
$currentSize = filesize($file);
if ($size == $currentSize) {
usleep(100);
continue;
}
$fh = fopen($file, "r");
fseek($fh, $size);
while ($d = fgets($fh)) {
ob_end_flush();
echo $d;
ob_flush();
flush();
ob_start();
}
fclose($fh);
$size = $currentSize;
$index=$index+1;
}
}
follow("/var/www/devicemanagement/testFile.txt");
This script echoes a log file in real time and it works well when run in command line.
The following html code is meant to display the echoed lines from the php script:
<!DOCTYPE html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.js"></script>
<script>
var sentData = {
'param1': 'value1',
'param2': 'value2'
};
function successCallback(returnedData) {
$('#myDiv').html(returnedData);
}
function doAjaxCall() {
$.get('/labtool/controllers/tailor.php', sentData, successCallback);
//$.get('testFile.php', sentData, successCallback);
}
$(document).ready(function () {
var id;
$('#doStuff').click(function () {
clearInterval(id);
//$.get('testFile.php', sentData, successCallback);
});
id = setInterval(doAjaxCall, 1000);
});
</script>
</head>
<body>
<div id="myDiv"><h2>Let AJAX change this text</h2></div>
<button type="button" id="doStuff">Change Content</button>
<div id="myDiv"></div>
</body>
</html>
I understand the key is using flush right, but despite my best efforts and a lot of experimenting I'm unable to get it to work.
Can anyone see what I'm doing wrong?
This works for me using info I gathered from probably many sources including stackoverflow, sorry about the formatting. Every time you have text to flush, simply call the function:
function flush_message($msg)
{
echo $msg;
// not a space, just '', I haven't tried removing it to see what happens
// cause I should really be working on something else right now!
echo str_pad('', 4096) . "\n";
ob_flush();
flush();
}
I also set
apache_setenv('no-gzip', 1);
ini_set('zlib.output_compression', 0);
at the beginning of script
Apparently there are lots of browser specific issues as well (regarding how big buffer until output is drawn) so you might want to test on different platforms to see how it performs.

How to append the name of the file which has just been uploaded? [duplicate]

This question already has an answer here:
It is not appending the variable
(1 answer)
Closed 8 years ago.
I have a problem appending the imageNameArray where it is suppose to display file names which have been uploaded.
The problem is that lets say I previously uploaded a file (pig.png), when I refresh page and upload another file (panda.png), then when I upload the file, it should display 'panda.png'. But instead it is appending the name of the previous uploaded file (pig.png) and it does not append panda.png.
If I refresh page again and upload another file (tiger.png), then when I upload the file, it should display 'tiger.png'. But instead it is still just appending the name of the previously uploaded files (panda.png) and it does not append tiger.png.
If I upload another file (not refreshing page) such as monkey.png, then again it appends panda.png. No monkey.png. So it should of append tiger.png and monkey.png but instead it appends panda.png and panda.png.
All I want is that when a file is uploaded, it's name is appended. But how can this be achieved? Please show a coded example of how to fix it as I find it easier than an explanation saying why this is happening :)
Below is the javascript code where the appending occurs:
<?php
session_start();
$idx = count($_SESSION ['fileImage'] - 1);
$output = isset($_SESSION ['fileImage'][$idx]) ?
$_SESSION ['fileImage'][$idx]['name'] : "";
?>
<script type="text/javascript">
function imageClickHandler(imageuploadform){
if(imageValidation(imageuploadform)){
return startImageUpload(imageuploadform);
}
return false;
}
function startImageUpload(imageuploadform){
$(".imageCancel").click(function() {
$('.upload_target').get(0).contentwindow
return stopImageUpload();
});
return true;
}
function stopImageUpload(success){
var imageNameArray = new Array();
imageNameArray = <?php echo $output ?>;
var result = '';
if (success == 1){
result = '<span class="msg">The file was uploaded successfully!</span><br/><br/>';
for(var i=0;i<imageNameArray.length;i++)
{
$('.listImage').append(imageNameArray[i]+ '<br/>');
}
}
else {
result = '<span class="emsg">There was an error during file upload!</span><br/><br/>';
}
return true;
}
</script>
<body>
<form action='imageupload.php' method='post' enctype='multipart/form-data' target='upload_target' onsubmit='return imageClickHandler(this);' class='imageuploadform' >
Image File: <input name='fileImage' type='file' class='fileImage' /></label><br/><label class='imagelbl'>
<input type='submit' name='submitImageBtn' class='sbtnimage' value='Upload' /></label>
</p><ul class='listImage' align='left'></ul>
<iframe class='upload_target' name='upload_target' src='#' style='width:0;height:0;border:0px;solid;#fff;'></iframe></form>");
</body>
Below is the php script (imageupload.php) where it uploads a file which is on another page from the javascript function above:
<?php
session_start();
$result = 0;
$errors = array ();
$dirImage = "ImageFiles/";
if (isset ( $_FILES ['fileImage'] ) &&
$_FILES ["fileImage"] ["error"] == UPLOAD_ERR_OK) {
$fileName = $_FILES ['fileImage'] ['name'];
$fileExt = pathinfo ( $fileName, PATHINFO_EXTENSION );
$fileExt = strtolower ( $fileExt );
$fileDst = $dirImage . DIRECTORY_SEPARATOR . $fileName;
if (count ( $errors ) == 0) {
if (move_uploaded_file ( $fileTemp, $fileDst )) {
$result = 1;
}
}
}
$_SESSION ['fileImage'][] = array('name' => $_FILES ['fileImage']['name']);
?>
<script language="javascript" type="text/javascript">window.top.stopImageUpload(<?php echo $result;?>);</script>
The problem is that you are outputting the name of the uploaded file when the PHP code renders the page, which is before the (next) image is uploaded.
This happens on this line in the stopImageUpload() JavaScript function:
imageNameArray = <?php echo $output ?>;
There are a couple ways you can resolve this, but I would go for the straightforward way of passing the file name back via the stopImageUpload() function.
// stolen from http://stackoverflow.com/questions/1219860/javascript-jquery-html-encoding
function htmlEncode(value) { return $('<div/>').text(value).html(); }
function stopImageUpload(success, filename) {
var imageNameArray = new Array();
var result = '';
if (success) {
result = '<span class="msg">The file was uploaded successfully!</span><br/><br/>';
$('.listImage').append(htmlEncode(filename) + '<br/>');
} else {
result = '<span class="emsg">There was an error during file upload!</span><br/><br/>';
}
}
Then you simply need to adjust the last line of imageupload.php:
<script language="javascript" type="text/javascript">window.top.stopImageUpload(<?php echo $result ? 'true' : 'false'; ?>, '<?php echo $_FILES['fileImage']['name'] ?>');</script>
Note: If you have the option turned on to allow <?= ?> blocks you can make the above code look much nicer:
<script language="javascript" type="text/javascript">window.top.stopImageUpload(<?= $result ? 'true' : 'false'; ?>, <?= $_FILES['fileImage']['name'] ?>);</script>

javascript return function's data as a file

I have a function in javascript called "dumpData" which I call from a button on an html page as **onlick="dumpData(dbControl);"* What it does is return an xml file of the settings (to an alert box right now). I want to return it to the user as a file download. Is there a way to create a button when click will open a file download box and ask the user to save or open it? (sorta of like right-clicking and save target as)...
Or can it be sent to a php file and use export();? Not sure how I would send a long string like that to php and have it simple send it back as a file download.
Dennis
I don't think you can do that with javascipt, at least not with a nice solution.
Here's how to force a download of a file in PHP:
$file = "myfile.xml";
header('Content-Type: application/xml');
header("Content-Disposition: attachment; filename='$file'");
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
Instead of using readfile to output your file, you could also directly display content using echo.
/EDIT: hell, someone was faster :).
EDITED:
just a proof of concept.. but you get the idea!
instead of
<a onlick="dumpData(dbControl); href="#">xml file</a>
you can have like this:
xml file
then like this:
// Assuming your js dumpData(dbControl); is doing the same thing,
// retrieve data from db!
$xml = mysql_query('SELECT * FROM xml WHERE id= $_GET['id'] ');
header("Content-type: text/xml");
echo $xml;
I eneded up going this route:
The HTML code
<script type="text/javascript">
$(document).ready(function() {
$("#save").click(function(e) { openDialog() } );
});
</script>
<button id="save" >Send for processing.</button>
The javascript code:
function openDialog() {
$("#addEditDialog").dialog("destroy");
$("#Name").val('');
$("#addEditDialog").dialog({
modal: true,
width: 600,
zIndex: 3999,
resizable: false,
buttons: {
"Done": function () {
var XMLname = $("#Name").val();
var XML = dumpXMLDocument(XMLname,geomInfo);
var filename = new Date().getTime();
$.get('sendTo.php?' + filename,{'XML':XML}, function() {
addListItem(XMLname, filename + ".XML");
});
$(this).dialog('close');
},
"Cancel": function () {
$("#Name").val('');
$(this).dialog('close');
//var XMLname = null;
}
}
});
}
PHP Code, I just decided to write the file out to a directory. Since I created the filename in the javascript and passed to PHP, I knew where it was and the filename, so I populated a side panel with a link to the file.
<?php
if(count($_GET)>0)
{
$keys = array_keys($_GET);
// first parameter is a timestamp so good enough for filename
$XMLFile = "./data/" . $keys[0] . ".kml";
echo $XMLFile;
$fh = fopen($XMLFile, 'w');
$XML = html_entity_decode($_GET["XML"]);
$XML = str_replace( '\"', '"', $XML );
fwrite($fh, $XML);
fclose($fh);
}
//echo "{'success':true}";
echo "XMLFile: ".$XMLFile;
?>
I don't know why, but when I send the XML to my php file it wrote out the contents withs escape charters on all qoutes and double quotes. So I had to do a str_replace to properly format the xml file. Anyone know why this happens?
POST the XML via a form to a php script that writes it back to the client with a Content-Disposition: attachment; filename=xxx.xml header.
<form name="xml_sender" action="i_return_what_i_was_posted.php" method="POST">
<input type="hidden" name="the_xml" value="" />
</form>
Then with js
function dumpData(arg) {
var parsedXML = ??? //whatever you do to get the xml
//assign it to the the_xml field of the form
document.forms["xml_sender"].the_xml.value = parsedXML;
//send it to the script
document.forms["xml_sender"].submit();
}
Can't remember if this loses the original window, if so, post to an iframe.

Categories