View Full Version : Hiding download path in PHP
Artichoke Games
12-06-2003, 06:32 AM
Hi,
I'm going to start selling my game soon and I decided to have two different exes for demo and full version. I have come up with the idea to generate random string and put it into database with buyer's details. Buyers would get the email with the link "http://.../download.php?key=testString" and after clicking it, PHP would check if testString matches the one in the database and if it does, user would be allowed to download the demo. And here comes my problem. I was wondering what is a correct way to hide download path, so the user doesn't know where the demo he is downloading comes from. I was experimenting with <?php header("Location: http://.../fullversion.exe"); ?> but I don't know if this is safe solution.
Can you help? Thanks in advance!
SPACENEEDLEEXCHANGE
12-06-2003, 08:03 AM
put the downloads in a folder that you deny all access to using .htaccess files.
then in the php download script, just do a @readfile to echo the contents of the tile and thus "manually" initiate the download.
this is what i do with my website/patcher/launcher thinger.
Fenix Down
12-06-2003, 08:34 AM
Can't you also just put it above public_html or will the script not be able to access it then?
hanford_lemoore
12-06-2003, 12:36 PM
I use SpaceNeedle's method but instead of @readfile I use fpassthu. It has issues with some browsers though. Every once in a while I gen an email from someone who bought the game that can't get it to download.
I've not come up with anything better, though. How is @readfile's compatability for you. SpaceNeedle?
~Hanford
Artichoke Games
12-06-2003, 01:55 PM
@SPACENEEDLE: @readfile works perfectly, this is exactly what I needed.
@Fenix Down: To my surprise the script was able to find the file above public_html, so I guess there's no need to use .htaccess.
Thank you guys! :D
SPACENEEDLEEXCHANGE
12-06-2003, 05:47 PM
hanford: hard to say, since it's still in development. but i'm actually transferring the file via http to a custom client, not a web browser, so i don't have to worry about anything weird with the browser not recognizing the download. it's just byte spew to my client.
Lizardsoft
12-07-2003, 08:05 AM
Sending the right headers to the browser can be a huge pain. On my own such download script, I never figured out how to get Safari and IE for Mac to work correctly. The headers I send are:
Cache-control: private
Content-type: application/octet-stream
Content-disposition: attachment; filename="turtle.zip"
Content-transfer-encoding: binary
Content-length: 4435435
If anyone has any ideas how to improve on this to get that last 0.1% of browsers working with it, let me know.
SPACENEEDLEEXCHANGE
12-07-2003, 08:19 AM
i don't know, but have you ever tried
Content-type: application/force-download
?
elund
12-07-2003, 10:15 AM
This is the PHP function I wrote for downloading files:
function deliverFile ($file)
{
$size = filesize ($file);
$saveName = basename ($file);
header ('Expires: 0');
header ('Last-Modified: ' .
gmdate ('D, d M Y H:i:s', filemtime ($file)) . ' GMT');
header ('Pragma: public');
header ('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header ('Accept-Ranges: bytes');
header ('Content-Length: ' . $size);
header ('Content-Type: Application/octet-stream');
header ('Content-Disposition: attachment; filename="' . $saveName . '"');
header ('Connection: close');
readfile ($file);
}It works very well, except some browsers add ".html" to the name of the file delivered. (e.g., "BigHeadZedSetup.exe.html") To combat this, I added the following rule to my .htaccess:
RewriteRule securedl.exe /securedl.html [QSA,L]So securedl.html does a meta refresh back to itself with an exe extension instead (securedl.exe?mode=now). The browsers that were tacking on .html to the filename then stopped doing that.
Lizardsoft
12-07-2003, 10:24 AM
Very nice elund. Could you explain the reasoning behind these header choices? More importantly, which browsers have the .html problem, and do they have this problem on normal links to files like http://www.somewebsite.com/demo/demo.exe ? Theortically we should be able to come up with a set of headers that emulate a normal link perfectly (well there's the .php extension difference, so maybe not...)?
elund
12-07-2003, 08:03 PM
I believe the browser that was adding ".html" to the filename was Mozilla 1.4. I know some other browsers have this kind of problem too, I've seen the older Netscapes do this. This browser does not have problems with links to an exe. The problem is when the browser requests a URL ending with html but gets back binary content. It automatically tacks on .html (or whatever is the extension of the page) to the saved filename, despite the fact that the Content-Disposition header is telling them what filename to use. Using the Apache .htaccess rewrite I posted allows me to point users to an exe, causing the server to run a php script (encased in html), which then returns executable content. :)
Some of these headers are from doing my own telnets to an exe url to see what my web server was returning, and reading a number of forums discussing different tags. This was the combination I eventually decided on. :cool: I wasn't sure if client-side caching could be a problem so that's why all those Netscape and IE cache control headers are in there.
Lizardsoft
12-07-2003, 09:17 PM
What if the script has extension of .php? I've never had problems with Mozilla and my download script...
Thanks for the headers though. The cache-control is definitely necessary as it causes IE to go really screwy without it. I had my cache-control set to private but I'm trying yours out and seeing if it works better. Placing a last modified is a nice touch too.
Kai-Peter
12-07-2003, 11:09 PM
I use similar PHP magic like Eric but I add a bit of mod_rewrite trickery to get the filenames correct. The download URL for a full version of my game is (you can try it, it only works if you really have access):
http://www.mistaril.com/my/files/72/SpaceStationManagerFullSetup.exe (http://www.mistaril.com/my/files/72/SpaceStationManagerFullSetup.exe)
Then I use this rewrite rule:
RewriteRule ^/my/files/([0-9]+)/.* /my/download_release_file.php?file_ID=$1 [L]
So the 72 is the actual file id in my database and the filename is just used to fool the browser. The key is in using a non-redirecting rewrite. The files are stored outside the document root and the database record contains the actual filename from where to get output the file.
Note: As far as I know, none of these methods work with download managers like GetRight. This is on my list next, to parse the headers and make the script support partial downloads and resuming from arbitrary locations in the file.
elund
12-08-2003, 02:53 PM
Snazzy. :)
hanford_lemoore
12-08-2003, 03:21 PM
I had the same problem as Elund and Kai-peter, but I solved it by sending the link to a folder with no extention, and the PHP script was the index.php file, so the link was going to
www.monolux.dom/dl/
rather than
www.monolux.com/dl/download.php
or anything like that.
I'm not sure how/why that worked, but it seemed to work.