我正在尝试将 pdf 文件的外部链接重定向到托管 pdf 的 html 页面。
我已经更新了
/etc/apache2/conf.d/includes/pre_main_global.conf
,这是 httpd.conf
的包含文件:
#rewriteMap to stop hotlinking
RewriteMap pdf-mapping txt:/home/stakehol/public_html/pdf-mapping.txt
pdf-mapping.txt
包含:
/stakeholder-register.pdf /stakeholder-register.html
/project-templates/lessons-learned-template.pdf /project-templates/lessons-learned-template.html
/project-templates/Exception%20Report.pdf /project-templates/prince-2-exception-report.html
它将有数百个 URL,但这三个仅用于测试。
在
.htaccess
中我添加了:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?stakeholdermap.com [NC]
RewriteCond ${pdf-mapping:$1} !^$
RewriteRule ^(.*\.pdf)$ https://www.stakeholdermap.com/${pdf-mapping:$1} [R=302,L]
我已重新启动 Apache,但 pdf 文件未重定向。准备放弃,只需将 pdf 中的链接添加回页面,但我想在某个时候对 pdf 收费,所以...
RewriteRule ^(.*\.pdf)$ https://www.stakeholdermap.com/${pdf-mapping:$1} [R=302,L]
您在
RewriteRule
pattern: 中捕获的 URL 路径存在一些问题
捕获的 URL 路径不包含斜杠前缀,但您在重写映射中包含斜杠前缀。所以这永远不会匹配。
捕获的 URL 路径已进行 % 解码,因此重写映射中包含编码的 space(即
%20
)的第三个 URL 将永远不会匹配。然而,文字空格在 TXT 重写映射中是有问题的(因为 spaces 是分隔符并且无法转义)。您需要改为捕获 % 编码的 URL。
一个小问题(边缘情况)是,检查
RewriteCond
的第二个条件(HTTP_REFERER
指令)允许仅使用您的域名作为子域的外部域来绕过您的热链接。
使用现有的重写映射尝试以下操作:
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com($|/) [NC]
RewriteCond %{THE_REQUEST} \s(/[^?]+\.pdf)(\s|\?)
RewriteCond ${pdf-mapping:%1} (.+)
RewriteRule \.pdf$ https://www.example.com/%1 [R=302,L]
RewriteRule
pattern .pdf$
只是检查请求的 URL 路径是否以 .pdf
结尾。
服务器变量包含 HTTP 请求请求标头的第一行,并将包含以下形式的字符串(请注意,这包括 查询字符串 - 如果有):THE_REQUEST
GET /project-templates/Exception%20Report.pdf?query-string HTTP/1.1
第三个条件(检查
THE_REQUEST
)实际上捕获了请求的URL 路径。这是根据请求进行%编码的。我们会小心地从捕获的 URL 中排除任何查询字符串,否则会绕过您的热链接保护(查找将失败并且将提供 PDF 文件)。
第四个条件捕获重写映射的输出。请注意,
%1
反向引用用在TestString(而不是$1
)中,其中包含从前面的条件捕获的第一个子模式。另请注意在 CondPattern中使用
+
(1 个或更多)量词,因此只有在非空时才成功(您显式检查非空,即 !^$
- 但否定表达式不能用于捕获)。
最后一个条件中捕获的重写映射的输出将用于
RewriteRule
substitution 字符串 (%1
),而不是再次调用重写映射(尽管我预计这可能会在内部缓存)。请注意此处再次使用 %1
,但这与前面条件的 TestString中的
%1
是不同的值。