views:

83

answers:

3

(1) I have a site that serves up MP3 files:

http://domain/files/1234567890.mp3

(2) I have a php script that tracks file download counts:

http://domain/modules/download_counter.php?file=/files/1234567890.mp3

After download_counter.php records the download, it redirects to the original file: Header("Location: $FQDN_url");

(3) I'd like all my public links to be presented as the direct file urls from (1). I'm trying to use Apache to redirect the requests to download_counter.php:

RewriteRule ^files/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]

I'm currently stuck on (3), as it results in a redirect loop, since download_counter.php simply redirects the request back to the original file (rather than streaming the file contents).

I'm also motivated to use download_counter.php as is (without modifying it's redirect behaviour). This is because the script is part of a larger CMS module, and I'd like to avoid complicating my upgrade path.

Perhaps there is no solution to my problem (other than modifying the download_counter script). WDYT?

A: 

I first thought something that would use the referer would work:

RewriteCond %{HTTP_REFERER} !download_conter\.php
RewriteCond %{HTTP_REFERER} !=""
RewriteRule ^files/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]

However, the browser does not cooperate. Let's say you click some link in file.html to something.mp3 and then are forwarded to download_counter.php. When the php script does the forward it sets as referer not download_counter.php but file.html.

The only way I see you could do this would be using an external rewriting program that would keep some state -- the first time the user requested the file it would save that information and make the rewrite, the second time it would know it had made the rewrite in the first place and would pass through the request unmodified. See the documentation of RewriteMap.

Artefacto
One thing that I thought I'd be able to do is write/check an environment variable: RewriteCond %{ENV:Rewrite} !^yes$ RewriteRule ^files/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L, E=Rewrite:yes]I'm not sure why this doesn't work, but it doesn't.
rcourtna
You certainly cannot use environment variables to track users...
Artefacto
+1  A: 

If this is not about the strongest protection ever (as I can see, it is not), then just have your script to redirect browser not to the file, but to the

http://domain/files/1234567890.mp3/redirected

Ensure your webserver will still serve such request correctly as a file download. If it will, then just add negative RewriteCond that will ensure, that redirection is done if and only if the link is not ending with /redirected

FractalizeR
+1  A: 

UPDATED ANSWER

i think you are into a lot of troubles because your pseudo url are actually real urls: they lead to the file. So you should change your pseudo url to something like domain.com/downloads/file.mp3 and then just check whether the requested file does not exist, so that the redirect does not loop.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^downloads/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]
pixeline
Hi, I'm having a hard time following this. Can you please explain why/when the requested filename would not exist?
rcourtna
i rephrased my answer.
pixeline