Apache 重写规则和php下载计数器

Apache 重写规则和php下载计数器,apache,mod-rewrite,Apache,Mod Rewrite,(1) 我有一个提供MP3文件的网站: http://domain/files/1234567890.mp3 (2) 我有一个跟踪文件下载计数的php脚本: http://domain/modules/download_counter.php?file=/files/1234567890.mp3 下载_counter.php记录下载后,会重定向到原始文件: 标题(“位置:$FQDN_url”) (3) 我希望我的所有公共链接都以(1)中的直接文件URL的形式呈现。我正在尝试使用Apache重

(1) 我有一个提供MP3文件的网站:

http://domain/files/1234567890.mp3
(2) 我有一个跟踪文件下载计数的php脚本:

http://domain/modules/download_counter.php?file=/files/1234567890.mp3
下载_counter.php记录下载后,会重定向到原始文件: 标题(“位置:$FQDN_url”)

(3) 我希望我的所有公共链接都以(1)中的直接文件URL的形式呈现。我正在尝试使用Apache重定向下载_counter.php的请求:

RewriteRule ^files/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]
我目前仍停留在(3)上,因为它会导致重定向循环,因为download_counter.php只是将请求重定向回原始文件(而不是流式传输文件内容)

我还想按原样使用download_counter.php(不修改它的重定向行为)。这是因为脚本是一个更大的CMS模块的一部分,我希望避免使升级路径复杂化


也许我的问题没有解决方案(除了修改下载计数器脚本)。WDYT?

我首先想到使用referer的东西会起作用:

RewriteCond %{HTTP_REFERER} !download_conter\.php
RewriteCond %{HTTP_REFERER} !=""
RewriteRule ^files/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]
但是,浏览器不配合。假设您单击file.html中指向something.mp3的某个链接,然后被转发到下载_counter.php。当php脚本执行转发时,它设置为referer,而不是download_counter.php,而是file.html


我认为你能做到这一点的唯一方法是使用一个外部重写程序,该程序将保持某种状态——用户第一次请求文件时,它将保存该信息并进行重写,第二次它将知道它已在第一时间进行了重写,并将在未修改的情况下通过请求。请参阅的文档。

如果这不是有史以来最强的保护(正如我所看到的,它不是),那么只需使用脚本将浏览器重定向到文件,而不是

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

确保您的Web服务器仍能作为文件下载正确地提供此类请求。如果会,则只需添加否定的重写条件即可确保在且仅当链接未以/redirected结尾时重定向成功

我认为您遇到了很多麻烦,因为您的伪url实际上是真实的url:它们会导致文件。因此,您应该将伪url更改为类似于
domain.com/downloads/file.mp3
的内容,然后检查请求的文件是否不存在,以便重定向不会循环

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^downloads/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]
放入此
.htaccess
文件

RewriteEngine On
RewriteOptions Inherit
RewriteRule ^(.*).(mp3)$ /modules/download_counter.php?file=$1.$2 [R,L]

这应该可以做到…

我想我可以做的一件事是编写/检查环境变量:RewriteCond%{ENV:Rewrite}^是的$RewriteRule^files/(.+\.mp3)$/modules/download\u counter.php?file=/files/$1[L,E=Rewrite:yes]我不确定为什么这不起作用,但它不起作用。嗨,我很难理解这一点。你能解释一下为什么/什么时候请求的文件名不存在吗?