Closed Thread Icon

Topic awaiting preservation: Next Step: Log the Downloads (Page 1 of 1) Pages that link to <a href="https://ozoneasylum.com/backlink?for=25677" title="Pages that link to Topic awaiting preservation: Next Step: Log the Downloads (Page 1 of 1)" rel="nofollow" >Topic awaiting preservation: Next Step: Log the Downloads <span class="small">(Page 1 of 1)</span>\

 
Wes
Paranoid (IV) Mad Scientist

From: Inside THE BOX
Insane since: May 2000

posted posted 05-05-2005 01:39

Okay, so now that my nifty PHP image-downloading script is working, I've decided I'd like to know when the clients are actually downloading the images. I figure writing to a simple text file that X file was downloaded will do just fine. I believe I can handle that part, but I'm not sure how I should trigger it.

Right now, when someone enters an invoice number, the script looks for the files, and if they're found, it builds a page with regular anchor tags linking to those files. Given this, what options do I have for triggering the function that writes to the log file and knowing which link was selected? Do I have to change the anchor tags to form buttons?

Incidentally, I'd like to avoid any kind of redirection to another page if at all possible.

I'm sure this is monkey simple, but I'm not sure how to start.

DL-44
Maniac (V) Inmate

From: under the bed
Insane since: Feb 2000

posted posted 05-05-2005 01:45

I would personally use a redirect.

The basic setup would work like this -

on the download page, you have anchors linking to each file. instead of linking to the file, it links to a php file, with some sort of identifier for the file (ie <a href="count.php?file=filename">). This file contains the function that logs your download, and then redirects the browser to the actual file.

simple and invisible.



(Edited by DL-44 on 05-05-2005 01:55)

mr.maX
Maniac (V) Mad Scientist

From: Belgrade, Serbia
Insane since: Sep 2000

posted posted 05-05-2005 10:16

Don't forget to use some sort of file locking ( php->flock() ) while writing to the text file, if you don't want to end up with corrupted content in case of parallel writes.




(Edited by mr.maX on 05-05-2005 10:16)

Wes
Paranoid (IV) Mad Scientist

From: Inside THE BOX
Insane since: May 2000

posted posted 05-06-2005 18:33

That's what I had originally considered, actually -- going to another page and redirecting.

The thing is, there may be more than one file for them to download. I'd prefer them not to have to click a "return to the download page" link.

So, I was thinking ... At the moment, the whole thing works using only index.php. When the form is submitted, it posts to index.php, which takes $_POST["formfield"] if it exists and creates new content. So, what if I were to make the download links into forms as well, which posted again to index.php, which recreated the same content, then logged the download and echoed the meta tag for the redirect to the file? The page would refresh, the user's download dialog would pop up, but the page wouldn't really go anywhere else. It would almost be invisible. And I wouldn't have to worry about parsing a URL query string.

Or am I over/underthinking this?

And I'll be sure to look at that flock thing you mentioned, max, thanks.

bitdamaged
Maniac (V) Mad Scientist

From: 100101010011 <-- right about here
Insane since: Mar 2000

posted posted 05-06-2005 18:59

That's how I'd do it.

But you don't have to even put it into a form. You can just have your download links something like

code:
<a href="index.php?download_file=/path/to/file.zip&invoicenumber=XXXX" />




Literally all you would have to change is look to see if download_file is set, and if it is log the download and add the meta tag to the page you already have.



.:[ Never resist a perfect moment ]:.

(Edited by bitdamaged on 05-06-2005 23:35)

DL-44
Maniac (V) Inmate

From: under the bed
Insane since: Feb 2000

posted posted 05-06-2005 23:20

what I posted originally can also be done by simply reloading the same page with the link, as BD stated.

WarMage
Maniac (V) Mad Scientist

From: Rochester, New York, USA
Insane since: May 2000

posted posted 05-09-2005 03:32

IMHO I would always use a database if possible for data storage. If you are getting thousands of requests an hour you might need a more scaling solution. There is also the possability of just parsing your log files. Might not offer the control you are looking for though.

Anyways pipe the output to the user.

code:
<?php

$file = validate($_POST['file']);
incrementDownloadCount($file); //The code to incement your containing file

//sets the header by the file extention .gif = image/gif for example
//you would issue the command header("type: image/gif") for instance
setHeader($file);

//Section to actually send the output.
readfile($file);



This would make it appear like they are just downloading the file as a direct link. You might want to look at readfile() because you can run into some big problems with file sizes and timeouts.

You also want to make sure that the validate function is rock solid. You want to make sure they are only grabbing authorized files. You don't want anything like ../../../etc/passwd or anything like that getting out. So duplicate periods are out! Also you want to verify that the file that is being requested actually exists. If it does not send a 404 error immediately. You will want to crash hard and fast whenever and error is found here. When working with anything that allows access to your files or data crash hard and dirty. If you don't kill the request right then you are giving the attacker more to work with.

Dan @ Code Town

Wes
Paranoid (IV) Mad Scientist

From: Inside THE BOX
Insane since: May 2000

posted posted 05-09-2005 18:58

I had thought about linking the page to itself like that originally, but I wasn't sure if the page would reload reliably. I might go ahead and do it that way.

As for a database, that's far more complicated than I need. These are just downloads for images I've negotiated licenses for. If I were licensing thousands of publishings an hour, I'd be paying someone else to worry about this.

WarMage
Maniac (V) Mad Scientist

From: Rochester, New York, USA
Insane since: May 2000

posted posted 05-09-2005 19:40

You will find that using a database tends to be the easy solution, and ultimately less complicated. That is why I reccomend it.

The code to create the table:

code:
CREATE TABLE imagetracker (image VARCHAR(255), hits INT)



The code to increment the counter:

code:
<?php
function incrementCounter($image){
$connection = mysql_connect("localhost","username","password");
mysql_select_db("database");
$sql = "SELECT image FROM imagetracker WHERE image = '$image'";
$results = mysql_query($sql) or die("Query Failed: " . mysql_error());
if(mysql_num_rows($results) != 1){
$sql = "UPDATE imagetracker SET hits = hits + 1 WHERE image = '$image'";
} else {
$sql = "INSERT INTO imagetracker (image,hits) VALUES ('$image',1)";
}
mysql_query($sql) or die("Query Failed: " . mysql_error());
}
?>



Then you will need code to pull out the data from the database:

code:
<?php
function getResultTable(){
$connection = mysql_connect("localhost","username","password");
mysql_select_db("database");
$sql = "SELECT image,hits FROM imagetracker";
$results = mysql_query($sql) or die("Query Failed: " . mysql_error());
$output = "<table>\n";
$output.= "\t<tr>\n";
$output.= "\t\t<td>Images</td>\n";
$output.= "\t\t<td>Hits</td>\n";
$output.= "\t</tr>\n";
while($line = mysql_fetch_array($results)){
$output.= "\t<tr>\n";
$output.= "\t\t<td>" . $line['image'] . "</td>\n";
$output.= "\t\t<td>" . $line[hits'] . "</td>\n";
$output.= "\t</tr>\n";
}
$output.= "</table>";
return $output;
}
?>



Using these three small pieces and you have your database, your input and your output. You still might find the idea of the DB a bit scary, but it will save you time in the end. Eventually you will want to do something else with your data, and you will end up needing a database, and you will either have to create a script to import all your data into the database or you will end up dumping all the old data and starting fresh. Neither of which is an optimal solution. It is never a bad idea to create the stronger infrastructure when you can. If you don't it can bite you in the ass.

Dan @ Code Town

(Edited by WarMage on 05-09-2005 19:41)

DL-44
Maniac (V) Inmate

From: under the bed
Insane since: Feb 2000

posted posted 05-10-2005 01:31

Wes - for the record, I use a database at times when textfiles would suffice precisely because I find it easier than dealing with the files

But that's a matter of preference...whatever works for you (and as long as it is small scale, it shouldn't matter either way)

« BackwardsOnwards »

Show Forum Drop Down Menu