| Info: Collect statistics on the popularity
of your downloads with Apache's mod_rewrite and PHP.
How some of the others do
it
Some sites present you an URI like http://www.example.com/download.php?file=/foo/bar,
which is less than perfect. Being a Windows user (well sometimes)
I expect that when I add a file to my download manager I'll
see the filename in the list - unfortunately the result
from adding a file from such a link is the meaningless download.php
in your file list.
While the method mentioned above is easy to implement it
is not the best way to do it. We want visitors to see the
real filename as the URI not as a query string. So what
we'll do internally is exactly the same as in the above
example but this time the visitor will see the real filename.
How do we do it
Our URIs will be in the form of http://www.example.com/foo/bar
which makes more sense, doesn't it?
What do we need
- Apache compiled with mod_rewrite (off by default, you
need to add --enable-module=rewrite to your configure
line)
- PHP as the scripting engine
- A database, like MySQL, to store the download data
Apache's configuration
Options +FollowSymLinks
RewriteEngine On
RewriteBase /foobar/
RewriteRule download/send.php - [L]
RewriteRule download/(.+\..+)$ download/send.php?file=$1
[L]
You can put this block of code in a .htaccess file in
/foobar/, your downloads should be in /foobar/download/
- these are the directories accessible by the paths mentioned
from your webserver.
What we do is switch on FollowSymLinks which is required
by mod_rewrite, if you don't need other options you can
remove the +. We turn on the rewrite engine which is off
by default, then set the base location for the URI rewrites.
The next two lines are our rewrite rules, if the request
is for send.php (our script that counts downloads) we don't
modify it, if we get a request for download/foo.bar that
will become download/send.php?file=foo.bar for Apache (the
rewrite base is prepended). The rule processed only filenames
with extensions.
The download counter
<?php
$file = isset($_GET['file']) ? trim($_GET['file'])
: '';
if (!$file) {
die("Error");
}
if ( substr_count($file, '..') > 0 or substr($file, 0,
1) == '/' ) {
die("Invalid filename.");
}
$path = dirname($_SERVER['PATH_TRANSLATED'])
. '/' . $file;
if ( !file_exists($path) ) {
die("File not found: $file");
}
$ext = explode('.', $file);
if ( sizeof($ext) < 2 ) {
die("Invalid filename: should have extension");
}
We do some checking first, you should never display files
to the visitors that they have requested without checking
for unwanted characters like ../ or / at the start of the
filename.
[ next page
]
|