Forum Moderators: phranque

Message Too Old, No Replies

using .htaccess to run a script

trying to control access to downloads

         

toucan

4:30 pm on Nov 16, 2005 (gmt 0)

10+ Year Member



Hi,
I'm pretty new to .htaccess other than for the basic directory protection.
My problem is that I have a /members/ directory which stores hundreds of .wmv files that can be downloaded if you're a member.
When someone clicks a link to download one of the movies, .htaccess should prompt for a username and password. Then it should redirect to a php script which checks for available credit they have. If enough credit, then allow to download. Otherwise, give error message.
Problem is, the way I have it, the redirect will always redirect so they can never download the movies!
I'm sure there's a way but just too new at this to figure it out.

Any suggestions would be greatly appreciated?

jdMorgan

10:33 pm on Nov 16, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



toucan,

Welcome to WebmasterWorld!

There is very little conditional 'scripting' capability in .htaccess, so your script needs to do most of the work.

An easy way to do this would be to create a subdirectory, and then put your "credit counter" script in that subdirectory.

Then in .htaccess, password-protect that subdirectory. Also in .htaccess add a rewrite (not a redirect) using mod_rewrite so that all requests for restricted-access content URLs get rewritten to the credit-counter script in the protected subdirectory. You could also move all the protected content into or below that subdirectory, just to keep it organized and protected.

SO, if someone requests restricted content, Apache will prompt for a username and password. If this is entered successfully, then the script will be run. It can take the originally-requested URL and figure out what file to send to the user if the credit count is high enough. I'd suggest you let the script "include" the requested content so that no redirection is used. This will keep the real path to the content 'hidden' behind the orginally-requested URL.

If this is unclear, keep in mind that the filepath to the actual content need have nothing to do with the requested URL-path. Mod_rewrite in .htaccess can be used to 'map' any URL to any Web-accessible file on your server. Also, keep in mind that password protection in .htaccess is directory-based, not file-based.

The details of implementation will vary, but hopefully this will get you started.

Jim

toucan

2:00 am on Nov 17, 2005 (gmt 0)

10+ Year Member



Thanks Jim,

So let me get clear on a couple of things:

I put the password protection and rewrites in the same .htaccess? And it doesn't matter if the requested files are in the same directory?

I have no problem understanding the rewrite which redirects to the php. What I have is:

RewriteEngine on
RewriteRule ^(.*)\.wmv validate.php [nc]

I'm at the point where my php can echo out the requested path to the file and the file size. But how do I then begin the download once they're validated?

Rob

jdMorgan

2:15 am on Nov 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Use PHP to open the content file, and include that content in the 'page' that PHP builds -- in much the same way that you would include a file if it were just HTML to be output on the page. Be sure to also send a proper MIME-type header (video/x-ms-wmv) before sending the content.

RewriteRule ^([^.]+)\.wmv$ /validate.php [NC]

would be more efficient. Avoid ".*" whenever possible, as it is maximally-ambiguous, greedy, and inefficient.

I'm no PHP guru, so I'll recommend you inquire in our PHP forum if you have questions about php implementations.

Jim

toucan

2:16 am on Nov 17, 2005 (gmt 0)

10+ Year Member



Just noticed what might be a problem. Prior to your reply I was using:

AddHandler validate .wmv
Action validate /validate/validate.php

Where validate.php was in a separate directory than the .wmv files. In that script I then had:

$filepath = $_SERVER["PATH_TRANSLATED"];

which could tell me what file people were trying to access and therefore the size of it. Now that the script and .wmv's are in the same directory and I'm using rewrite, this variable contains the path to the php script (of course). Does this mean I can't find out what people were trying to access any more?

Rob

toucan

2:19 am on Nov 17, 2005 (gmt 0)

10+ Year Member



Thanks for the tips. Greatly appreciated. I'll continue this at the php forum.

Rob

jdMorgan

2:23 am on Nov 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No problem. Just pass it as a different variable in the query string:

RewriteRule ^([^.]+\.wmv)$ /validate.php?what_I_want_is=$1 [NC]

toucan

1:13 pm on Nov 17, 2005 (gmt 0)

10+ Year Member



Re: "Use PHP to open the content file, and include that content in the 'page' that PHP builds -- in much the same way that you would include a file if it were just HTML to be output on the page. Be sure to also send a proper MIME-type header (video/x-ms-wmv) before sending the content."

When including the .wmv file in the page PHP builds, won't that again trigger the script to run in a loop?

jdMorgan

1:42 pm on Nov 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> won't that again trigger the script to run in a loop?

Not necessarily, and you should code it so that it does not. I don't know that I can explain it any better, but a script doesn't necessarily have to output anything, or even *do* anything, for that matter. Generally on a dynamic site, you write a script so that it outputs some HTML code, and thus that script 'appears to be' an HTML page.

In this case, you'll code it so that it opens a .wmv file, reads in the contents of that file, and writes it to STDOUT -- sending it to the requesting browser. So in this case, the script 'appears to be' a .wmv file -- it is simply serving as a 'pipe' between the .wmv file data stored on the server's disk and the client browser. No redirects involved, and no need to re-invoke anything.

Only in the case where the 'credit count' is insufficient does the script output any HTML. And that would be the 'Not enough credit' warning page (or whatever you call it, since I don't know what this 'credit' means). Otherwise, it simply sends the requested .wmv data to the user.

Also, there's nothing here that says that this script has to be your existing script. You could split the credit-checking function out of the the existing script, add the .wmv-file-serving function, and create a separate new script, if that suits you better.

There are undoubtedly many ways to accomplish your goal. The method described here is the simplest one with 'the fewest moving parts,' as far as I know.

Jim

toucan

4:38 pm on Nov 17, 2005 (gmt 0)

10+ Year Member



I was advised in the php forum to add the following lines to my script in order to begin downloading after validation:

header("Location: $file_to_download");
exit;

I got the following error when I tried to run it:
"Redirection limit for this URL exceeded. Unable to load requested page. This may be caused by cookies that are blocked."

I explained how the mod_rewrite rule redirects to php. The header line he gave me is creating some kind of loop again.

His reply was:
"This means we need to be able to alter your mod_rewrite rule so that validated visitors redirected by the script are not redirected. I believe this might be achieved by setting an environment variable that can then be read by the htaccess file (RewriteCond %{ENV:ALLOW_DOWNLOAD} or something similar.

mod_rewrite isn't my specialty unfortunately, so hopefully someone else could advise you on this."

Does anyone have any idea on how I could accomplish this?