[SOLVED] - htaccess help

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
fresh
Forum Contributor
Posts: 259
Joined: Mon Jun 14, 2004 10:39 am
Location: Amerika

[SOLVED] - htaccess help

Post by fresh »

hey, I am building a auto-download after purchase routine and I am now working on the downloading part of the routine and I can not seem to get this to work. Basically, I have a folder with the download and I have protected the folder with .htaccess. Now the script they goto when they receive their email after the purchase is outside that folder. I am trying to allow just my script to pull that file or at least send them to the file for download. I don't want to give them the password and I assumed that my script would be allowed to access the folder but it can't. I have tried to popen to the file and that was no good, I tried to fopen the file but that didn't work either. I even tried to send a header like: user:pass@site.com/protected/file.zip

but it asks me if I want to log in and then shows the password! Is ther anyway, I can keep the folder .htaccessed and allow my script to get to the file so I can pipe it to the user or just send him/her to the file through the script? thanks
Last edited by fresh on Sun Jul 31, 2005 3:15 am, edited 1 time in total.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Just place the file outside of the web directory (higher up the 'tree' then) public_html
then just do this with your script

Code: Select all

if ($authorized) {
   header('Content-Type: application/zip'); // or is it application/octet-stream? oh well, google it
   readfile ('../../secret_file.zip')
} else {
   echo 'You cant download this file';
}
User avatar
fresh
Forum Contributor
Posts: 259
Joined: Mon Jun 14, 2004 10:39 am
Location: Amerika

Post by fresh »

EDIT: couldn't they still guess the path and get the dl that way? I think I rather stay with the same format I have now, using .htaccess and trying to authorize on the back-end. So, is there a way I can do this the way I would preffer? I could use a solution to this in other projects as well so, I will certainly appreciate further assitance. thanks
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

No they can't guess the path if you put it in a non web accessible path like I said. (not under public_html) If you really want you could leave it in a web accessible directory and protect it with htaccess, and find some way to open it, I'm guessing a hack using curl, but why?
User avatar
fresh
Forum Contributor
Posts: 259
Joined: Mon Jun 14, 2004 10:39 am
Location: Amerika

Post by fresh »

yeah but if my script can access the file, why can't they? I wouldn't mind doing it this way if I know that navigating to the file is impossible. I just haven't heard that this was possible before so I am a bit weary of the affects. Is this a common method to use in cases like mine? Other developers go this route? I just can't see how my script inside the public_html can access the file outside of the public_html folder but micsellanious users from the wild can't? Could you eloborate on the theory a bit more? thanks in advance
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Q. yeah but if my script can access the file, why can't they?
A. Because its in a non web accessible directory

Q. I wouldn't mind doing it this way if I know that navigating to the file is impossible.
A. It is

Q. Is this a common method to use in cases like mine?
A. Yes

Q. Other developers go this route?
A. Yes

Q. I just can't see how my script inside the public_html can access the file outside of the public_html folder but miscellaneous users from the wild can't?
A. Apache is configured by default to not serve files outside of the web directory, PHP on the other hand, being a script interpreted by a program running on the server, has access to the hard drive and does not need to request the file through apache

Q. Could you elaborate on the theory a bit more? thanks in advance
A. Lets assume your folder is on a shared host
/home/fresh/public_html/index.php is your current home page
if you were to place a file in /home/fresh/testing.php and goto http://www.yoursite.com/testing.php you would most likely get a 404 error.
So what you do is create /home/fresh/protected_files/
Put all the stuff you're selling in that folder
then with php

Code: Select all

if ($authorized) {
   header('Content-Type: application/zip'); // or is it application/octet-stream? oh well, google it
   readfile ('/home/fresh/protected_files/secret_file.zip')
} else {
   echo 'You cant download this file';
}
Hope I explained it all to your satisfaction.


PS, if you're cautious about this method, perhaps place a test file in there first and test it out and see for yourself you can't 'navigate' to a directory outside of public_html?
User avatar
fresh
Forum Contributor
Posts: 259
Joined: Mon Jun 14, 2004 10:39 am
Location: Amerika

Post by fresh »

Yes, you have absolutly convienced me that this is a sound method. I see how it would be impossible unless someone gained FTP or SSH access, which is a completly new topic, indeed! Plus, using readfile should stream the file and hdie the path, I assume. And, with the headers, they would trigger the browser to download the file. Completes all points of this project, thank you very much. Your help is very much appreciated. best regards!

EDIT: This is offically solved, however, I would like to point out a few things:

1. You must make sure the folder is readable by PHP, just chmod for this on the folder you store the downloads in.

2. You must name the file in the headers:

Code: Select all

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="secret.zip"');
readfile ('/home/blah/priv_folder/secret.zip');
Note: If you do not name the file, apache will give the name of the script to the download.

3. It is wise to set_time_out to 0 since we are using readfile and it is possible that our users are still using dial-up. So we add:

Code: Select all

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="secret.zip"');
readfile ('/home/blah/priv_folder/secret.zip');
//
// prevent time-outs during slow conns
set_time_limit(0);
4. It is nice to include the file size with the headers for our users when downloading. So we add:

Code: Select all

$fullpath = "/home/blah/priv_folder/secret.zip";
//
header('Content-Type: application/octet-stream');
header("Content-Length: ".filesize($fullpath));
header('Content-Disposition: attachment; filename="secret.zip"');
//
// prevent time-outs during slow conns
set_time_limit(0);
//
readfile ($fullpath);
And that should be good to go. Works great, much appreciated!
Post Reply