Jump to content

Recommended Posts

First Question: Yes that would be secure.

Second Question: Yes they are receiving a stream not an actual link to the file being downloaded.

I am not completely sure what is wrong with that scrip that you are using, but it appears to be serving the file content in a format that is not valid such as Forced Download. Also it is specifying more than is really necessary, which could be causing trouble. Instead you should use the post fix of the file to determine it's content. All modern browsers support this method.

<?php
$type=explode('.',$file);
$type=$type[1];
header('Content-type: application/'.$type);
?>

Very strange about the corruption... and stripping the few lines down to what you are using didn't help.

 

<?php
$file = $_GET['file'];
// the absolute path to your directory storing your files.
$path = '/home/claims/';
$download = $file;
//header("Pragma: public");
//header("Expires: 0");
//header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
//header("Content-Type: application/force-download");
//header( "Content-Disposition: attachment; filename=".$download);
//header( "Content-Description: File Transfer");
//header('Accept-Ranges: bytes');
//header('Content-Length: ' . filesize($file));
//@readfile($file);
$type=explode('.',$download);
$type=$type[1];
header('Content-type: application/'.$type);
header( "Content-Disposition: attachment; filename=".$download);
readfile($download);
?>

 

Is there a better way to make this happen - this would be perfect for what I'm needing...?

 

Also, is there a file type that this process is limited to like only .jpg's?

 

Thanks,

WolfRage, I may have found the problem.. when I downloaded the file I noticed it was 237K and not 110K like the original, so I opened the downloaded file with a text editor and this is what I found.

 

<br />

<b>Warning</b>:  readfile(chart.pdf) [<a href='function.readfile'>function.readfile</a>]: failed to open stream: No such file or directory in <b>/home/mydomain.com/dbpages/download.php</b> on line <b>92</b><br />

 

My link was setup like this:

 

<a href= http://mydomain.com/dbpages/download.php?file=chart.pdf> testing</a>

 

The file reside in /home/files/ so how do I format the link correctly?

 

A JM,

Ahh remember when we were talking about hard coding the file location in, well this is where we need to do that.

 <?php
$location=realpath('../../');
$location=$location.'/files/chart.pdf'; /*OR it maybe like this $location.'files/chart.pdf' either way if you run realpath on $location again it should correct it. You can also adjust the above to accept the cleaned get variable instead of the hard coding the pdf file. But make sure this works first.*/
$location=realpath($location);
//Then readfile on $location.
//Hope all of this solves your problem, let me know what happens.
?>

It depends on where you are located on the server. But in this case the "../" signifies to back up in the directory. For instance if you are on a shared server then you are probably under some huge directory list that is broken down usually alphabetically. Might look something like this: "/home/content/a/l/p/alpha/html/mysitefolder/"

if you use your code then you would be calling this: "/home/content/a/l/p/alpha/html/index.php"

However your code had an error and needs to be like this.

<?php
$location=realpath('../index.html');
print_r($location);
exit;
?>

Basically using the real path you can back up as much as you would like  then use real path again to proceed down another path in your directory. This was the simplest way for me to figure out how to back up and then move to another location of which was being called dynamically.

I think this is starting to look like a folder permission issue...?

 

The pathing looks good, but I don't see anything showing up in the logs. I guess it needs to be asked to what permissions should a folder above root be set to?

 

Since PHP is reading and writing the files does that have some impact on that?

 

Thanks,

Well the question is does PHP have access to folders above the root? usually not. In that case you need to make a folder that is below root but inaccessible via the web. Another words I should not be able to get to that folder via a browser or any type of URL, instead only php should be able to access these areas.

.htaccess has very little to do with logins unless you are talking about http logins. But other wise .htaccess is all about access control to web users. So yes it could be that simple, now I am not a .htaccess pro so you may want some confirmation. But I am pretty sure that will tell appache to forbide any from viewing that directory.

Well since I was able to upload a file using php I was also assuming I would be able to delete a file using php, not.

 

With an .htaccess file similar to what you posted this is what I get.

 

You don't have permission to access /documents/graph.pdf on this server.

 

Same goes for downloading the file - man this has got me hung up...

 

Essentially I've got everything working working except now I don't have permissions...

 

help...  :'(

OK early on we had made some good progress but it sounds like you may not be putting it all together correctly. You will not be able to supply the user with the files directly, instead you have to perform a readfile for the user through php. If they want to delete the file you have to perform a unlink for the user through php. PHP is not a user it is the system and so it has the permissions to perform these operations. The user is not allowed into this directory at all in any way. Basically PHP must be the interface.

Wolfrage,

 

I finally got it!!! user error as usual... I wasn't including the path in the readfile() function.

 

<?php
$file = $_GET['file'];
// the absolute path to your directory storing your files.
$path = '/home/download/';
$download = $file;
//header("Pragma: public");
//header("Expires: 0");
//header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
//header("Content-Type: application/force-download");
//header( "Content-Disposition: attachment; filename=".$download);
//header( "Content-Description: File Transfer");
//header('Accept-Ranges: bytes');
//header('Content-Length: ' . filesize($file));
//@readfile($file);
$type=explode('.',$download);
$type=$type[1];
header('Content-type: application/'.$type);
header( "Content-Disposition: attachment; filename=".$download);
readfile($download);
?>

 

NEW

 

<?php
$file = $_GET['file'];
// the absolute path to your directory storing your files.
$path = '/home/download/';
$download = $file;
//header("Pragma: public");
//header("Expires: 0");
//header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
//header("Content-Type: application/force-download");
//header( "Content-Disposition: attachment; filename=".$download);
//header( "Content-Description: File Transfer");
//header('Accept-Ranges: bytes');
//header('Content-Length: ' . filesize($file));
//@readfile($file);
$type=explode('.',$download);
$type=$type[1];
header('Content-type: application/'.$type);
header( "Content-Disposition: attachment; filename=".$download);
readfile($path.$download);
?>

 

I'll now refine the script for my application. Many thanks for all your help, guidance and suggestions with this...  :D

 

A JM,

 

[EDIT]

 

I am still having a slight problem and its with passing variables. This now works perfectly "except" the variable $recordID is not available for use after testing with "if(asset" even though it is gotten originally with $_GET['ID'] and set to $recordID - when I submit the form the variable is blank. I thought every object on the form would be available, what am I missing here?

 

<?php
$recordID= $_GET['ID'];

$path = "../claims/" . $recordID . "/";
if(isset($_GET['delete']) && $_GET['delete']=='true') {
	$fname = $_GET['deletefile'];
	$path = '../claims/' . $recordID . '/';
        print_r($path.$fname);
        exit;
   //$location=realpath('../claims/' . $recordID . '/');
   //chdir($location);
   //unlink($path.$fname);
   //header('location: adm_file_list.php'); die();
}
?>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<body>
<?php
$dir = dir($path);
while($file = $dir->read()) {
 if($file != '.' && $file != '..') {
echo "<form method='post' action="?><?php echo $_SERVER['PHP_SELF'].'?delete=true&deletefile='.$file;?>
<?php echo" ><a href= /dbpages/download.php?file=$file&recordid=$recordID> $file </a>   <input type='submit' value='Delete'></form>";
}
}
?>

Passing the variable through the form again works...? I don't understand that?

 

<?php
$dir = dir($path);
while($file = $dir->read()) {
 if($file != '.' && $file != '..') {
echo "<form method='post' action="?><?php echo $_SERVER['PHP_SELF'].'?delete=true&recordid='.$recordID.'&deletefile='.$file;?>
<?php echo" ><a href= /dbpages/download.php?file=$file&recordid=$recordID> $file </a>   <input type='submit' value='Delete'></form>";
}
}
?>

Since I'm working on this at the moment and trying to finish it up I found one last item. Hopefully you'll login tonight Wolfrage...

 

When I uncomment the last 2 lines of the script after deleting the file

unlink($path.$fname); 
header('location: adm_file_list.php'); 
die();

this is the error that is generated:

 

Warning: Cannot modify header information - headers already sent by (output started at /home/mydomain.com/dbpages/adm_file_list.php:4) in /home/mydomain.com/dbpages/adm_file_list.php on line 15

 

The issue is somehow related to "adm_file_list.php" being in an iframe and I'm trying to refresh it since it has one less file to delete. I don't understand what I'm doing wrong?

 

This is the last piece to the puzzle andI think this can be put to bed...

 

Thanks.

 

A JM,

The problem with recieveing this variable $_GET['ID'] is that the form is submitted with POST so the line should look like this:

<?php $recordID= $_POST['ID']; ?>

The header warning is due to the fact that headers can only be sent prior to any other data that is going to the browser and only once. So before we pick apart the Iframe lets see what is on these two lines: adm_file_list.php: line 4 & line 15

[/]

Well I think I've resolved all the problems let me know what you think.

 

From the main form I'm setting the variable for $recordID using a $_SESSION and it is retrieved form the actual recordset.

 

$recordID= $_SESSION['port_recordID']; //variable used to carry claimnumber

 

Then in the Iframe I just get the variable from the $_SESSION['port_recordID']

 

$recordID= $_SESSION['port_recordID'];

 

Using that scenario all my problems disappeared... what do you think? should I run into any problems with the $_SESSION variable; do I need to do anything in particular with it before or after its use?

 

<?php
//initialize the session
if (!isset($_SESSION)) {
  session_start();
}

$recordID= $_SESSION['port_recordID']; //variable comes from detail page only used to carry claimnumber

$path = "../documents/" . $recordID . "/";
if(isset($_GET['delete']) && $_GET['delete']=='true') {
	$fname = $_GET['deletefile'];
	$fID = $_GET['recordid'];
	$path = '../documents/' . $fID . '/';
        //print_r($path.$fname);
        //exit;
   unlink($path.$fname);
   header('location: adm_file_list.php'); 
   die();
}
?>
<?php
$dir = dir($path);
while($file = $dir->read()) {
 if($file != '.' && $file != '..') {
echo "<form method='post' action="?><?php echo $_SERVER['PHP_SELF'].'?delete=true&recordid='.$recordID.'&deletefile='.$file;?>
<?php echo" ><a href= /dbpages/download.php?file=$file&recordid=$recordID> $file </a>   <input type='submit' value='Delete'></form>";
}
}
?>

 

 

 

The only other recommendation I would make is to catch the result of your unlink. So that you can print a confirmation or a failure screen. Although the $_GET variables in this case are not a risk, it is still always a good idea to clean every incoming variable. Good job AJM.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.