忽略内部重定向的请求

时间:2012-07-27 15:57:56

标签: apache mod-rewrite

RewriteRule ^resources/.+$ - [L]

RewriteRule .? index.php?t=$0 [QSA,L]

会生成一个500 - Internal Server Error,因为它会一次又一次地重复相同的规则,因为内部重定向的请求被完全视为第一个。它会导致无限链index.php?t=index.php&t=index.php&t=index.php&[...infinite more...]&t=test.php

但在我看来,这并不是更好:

RewriteRule ^resources/.+$ - [L]

RewriteCond %{QUERY_STRING} !t=
RewriteCond %{REQUEST_URI} !^index\.php$
RewriteRule .? index.php?t=$0 [QSA,L]

因为现在用户可以输入index.php?t=test.php作为地址,所以会传递脚本并获得与他给出test.php相同的内容。我不喜欢那样。

那么如何在没有重复内部重定向的情况下执行第一个呢?当然,标志 VL - 非常最后可以做到这一点但是遗憾的是它不存在。

1 个答案:

答案 0 :(得分:0)

首先,我们看看给出规则的所有参数,可能表明这是否是一个链式请求。这意味着,我们要么1)需要在链接请求中更改的变量而不是相对于更改的URI,或2)相反,一个相对于更改的URI并且没有更改的变量(因为我们可以将其与其他人进行比较) 做了 chage)。

问题是,它们几乎都根据应用的RewriteRules更新。

IS_SUBREQ(1)和THE_REQUEST(2)是唯一有趣的变量,但遗憾的是内部重定向不被视为子请求,因此IS_SUBREQ消失。只有THE_REQUEST不会更改并包含实际给定的路径,因此我们找到了入口点。

考虑到这一点,这是令人讨厌的复杂解决方案:

RewriteEngine On

# Set SCRIPT_URI and SUBREQ
# MUST be the first statements in the file
 # SCRIPT_URI is the original browser-requested path
 # SUBREQ is "true" if the original browser-requested path is not overriden yet

 RewriteCond %{ENV:REQUEST_PARSED} !true
 RewriteCond %{THE_REQUEST} ^\s*\w+\s+(http://[^\s/]+/|/?)([^\s\?]*)[\s\?$]
 RewriteRule .? - [E=SCRIPT_URI:/%2,C]
 RewriteRule .? - [E=REQUEST_PARSED:true]

 RewriteCond %{ENV:SCRIPT_URI} ^(.*?)/\.($|/.*$)
 RewriteRule .? - [E=SCRIPT_URI:%1%2,N]

 RewriteCond %{ENV:SCRIPT_URI} ^(.*?)/[^/]+/\.\.($|/.*$)
 RewriteRule .? - [E=SCRIPT_URI:%1%3,N]

 RewriteCond %{ENV:SCRIPT_URI} ^(.*?)//\.\.($|/.*$)
 RewriteRule .? - [E=SCRIPT_URI:%1/%2,N]

 RewriteCond %{ENV:SCRIPT_URI}#%{REQUEST_URI} !^/*(.*)#/*\1$
 RewriteRule .? - [E=SUBREQ:true]

# SCRIPT_URI and SUBREQ are set now. Actual content follows:

RewriteCond %{ENV:SUBREQ} !true
RewriteRule ^resources/.+$ - [L]

RewriteCond %{ENV:SUBREQ} !true
RewriteRule .? index.php?t=$0 [QSA,L]