PDA

View Full Version : Custom download links


Red Marble Games
12-16-2005, 07:29 AM
Though much of this is usually handled by the e-commerce provider, I'd like to have the ability to send customers an email with a link to the full version of a game that would expire after some period of time. Something like:

http://www.redmarblegames.com/hsdfjhl324-nmbcbn098f/FullVersion.zip

I assume there is some handy PHP way to generate such URLs programmatically, have them invisibly redirected to the "real" URL when the user clicks on them in the email, and then expire. Anyone doing this, or know how it's done? Or know of a PHP resource where I could go look this up?

Many thanks.

Mark

Sirrus
12-16-2005, 07:51 AM
Used to do this but can't recall what our web guy used...
Its a pretty simple script though - done a standard search on it?

ggambett
12-16-2005, 08:11 AM
Making them should be easy - make an actual directory with a symlink to the real file and that's it. About the expiration part, use a cron job that deletes the directories older than N days. If you can't use cron, a trick I'm using to run a process periodically on my server is to have a PHP script that does what I want to do, and have a local .html page as my browser's starting page. That HTML includes an IFRAME that calls that PHP script. Poor man's cron :) This pretty much guarantees the script is run several times a day.

BTW, if you're stuck in a toy OS without symlinks, this won't work. Fortunately the next version of their OS will "innovate" symlinks and other things UNIX has had for 3 or 4 decades :)

Red Marble Games
12-16-2005, 08:18 AM
Thanks for these interesting suggestions. I'm new to PHP and so finding my way from the textbook to the thing I want to accomplish is still a bit of a task.

Mark

Ryan Clark
12-16-2005, 09:35 AM
We have a "one time download" system that does exactly what you're talking about, Mark. Basically it generates a unique token:

$token = md5(uniqid(rand(),1));

Then stores it in a database. It then generates a download link that passes this token as a URL parameter.

When a user clicks on the link, the script looks up the token in the database, and if it finds it, starts pushing the download using the "readfile" function. (It then removes the token from the database, of course!) You may have to mess with the "header" function to get it to work on all systems. Here's what I use:

Windows:
$file = '/path/to/your/dowload.exe';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header("Content-Length: ".filesize($file));
readfile($file);

Mac:
$file = '/path/to/your/dowload.dmg';
header('Content-Description: File Transfer');
header("Content-Transfer-Encoding: Binary");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header("Accept-Ranges: bytes");
header("Content-Length: ".filesize($file));
readfile($file);

Not sure if all of those header fields are absolutely needed, but it took a fair amount of fiddling to get this to work... the above code seems to work well :)

If that doesn't make sense, this link may help: http://www.onlamp.com/pub/a/php/2002/12/05/one_time_URLs.html

revve
12-16-2005, 10:57 PM
To do what you are asking is really very simply. The link will usually be http://www.redmarblegames.com/download/hsdfjhl324-nmbcbn098f/FullVersion.zip

It's just a bit of mod_rewrite on Apache and a php script. Basically what happens is when the above link is called, apache transparently calls something like ]http://www.redmarblegames.com/download.php?token=hsdfjhl324-nmbcbn098f&file=FullVersion.zip - so you can see, it's actually a lot easier to implement than it looks (no folders, symlinks or cron jobs involved).

The token could be autogenerated by the page that displays the link and the row in the DB that stores the token could have an expiry date. Sorry for not giving more info but I don't have a lot of time to post at the moment. I'll come back later and give some more info if required. I suggest if you do a custom script (very easy to implement something like this) you google mod_rewrite (lots of info about it) and take a look at the comments in the fread page on the online php manual - they have an example of a funtion that does downloads that supports resumes. Oh, and don't worry about the mod_rewrite - it just involved adding something like 3 or 4 lines to a .htaccess file in the folder the script is in.

The code that Ryan Clark supplied (it's an excellent starting point) will cause problems on the majority of browsers. The octet-stream content type should only be used for exes and because he doesn't send a size header, the browser or download manager will not be able to give you a percentage of how much has been downloaded, since it will only count up to show you how much has been done.

Edit: the php.net comment you want is at http://www.php.net/manual/en/function.fread.php#57243

And a good link about mod_rewrite is at http://www.sitepoint.com/article/guide-url-rewriting