IIS团队刚刚发布了URL Rewrite v2.1。以下博客文章详细介绍了此版本中引入的更改。您可以从https://www.iis.net/downloads/microsoft/url-rewrite或从WebPI 下载最新版本。
控制URL重写规则的响应缓存能力
URL Rewrite v7.1.1909从可缓存的服务器变量集中移除了“HTTP_HOST”。这意味着任何在条件中引用“HTTP_HOST”的URL重写规则或者其操作是重写/重定向并将“HTTP_HOST”设置为其操作的一部分的URL重写规则不再是内核可缓存的。此修复的目的是防止由于缓存导致客户被困在重写循环中,因为URL Rewrite无法检测循环。但是,此更新消除了客户如果知道他们没有任何重定向循环,则允许其响应成为内核可缓存的能力。
引入一个responseCacheDirective
通过
在规则元素responseCacheDirective上引入新的指令,URL重写规则可明确标记为可缓存。
该responseCacheDirective接受四个可能的值:
1. 始终:响应始终可缓存。
2. 从不:响应永远不可缓存
3. NotIfRuleMatched:如果规则匹配,则响应不可缓存。
4. 自动(默认):URL重写根据规则中使用的服务器变量来确定规则的缓存友好性。
进入重定向循环的风险尚未缓解,因此设置responseCacheDirective来始终只使用时可以验证有没有重定向循环。
当你使用不同的responseCacheDirective定义多个规则时会发生什么?
URL重写会尝试将传入的URL顺序匹配到一组规则。每个规则有三种可能的结果,因为它适用于传入的URL:不匹配,URL匹配和规则匹配,以增加匹配度。匹配的规则与匹配的URL不同,除了匹配的URL之外还满足规则条件。
每个规则都会重新考虑响应的可缓存性,初始状态是一个中性状态,URL重写不会以任何方式指示内核缓存。如果当前状态变为不可缓存,则不考虑进一步的规则来确定缓存能力。换句话说,执行的所有规则中的单个规则足以使整个响应不可缓存。这使得规则的排序很重要在发生“规则匹配”时停止处理的情况。考虑至少有一个规则评估为“URL匹配”,并且该规则被设置为“从不”或“自动”且缓存不友好的服务器的情况。如果这个规则是在规则匹配之前的顺序,那么它会导致内核缓存被禁用。另一方面,如果规则在“规则匹配”规则之后被跳过,则对缓存能力没有影响。
对于一个对缓存能力有影响的规则,规则至少应该是“URL匹配”。如果为给定规则的responseCacheDirective选择了“NotIfRuleMatched” ,则整个规则与URL和条件匹配时,该响应的内核缓存将被禁用。请记住,“NotIfRuleMatched”不考虑缓存不友好的服务器变量。对于“ 永不”和“ 永远”也是如此,只有在存在缓存不友好的服务器变量导致内核缓存被禁用的情况下,Auto才是唯一的值。
保留原始网址编码
在V7.1.1980之前的URL Rewrite版本中,当试图使用UNENCODED_URL时,URL Rewrite将对其进行编码,如果原始URL已经被编码,则可能导致双重编码。这违反了RFC3986的第2.4 节,其中规定“ 实现必须不是百分比 - 不止一次地编码或解码相同的字符串,因为解码已经解码的字符串可能导致错误地解释百分比数据八位组作为百分比编码的开始,反之亦然百分比编码已经百分比的编码 - 编码的字符串“。这也使得UNENCODED_URL的使用变得不切实际,特别是在ARR的反向转发器场景中,后端服务器期望URL不被修改地传递。
在v7.1.1980中,我们添加了一个功能标志useOriginalURLEncoding,允许您在设置为true时关闭此不符合的URL编码。默认行为将保持不变(useOriginalURLEncoding默认为true)。
为了进一步解释这一点,我们来看下面的例子,输入的URL是https://contoso.com/ab%2fde/。在这个例子中,从IIS.SYS接收到的URL 的熟化表示是一旦解码/ ab / de /的URL 。
当保留原始URL编码(useOriginalURLEncoding == true)时,UNENCODED_URL服务器变量通过对传入URL进行编码来计算,这导致双重编码ab%252f。关闭不符合规定的行为(useOriginalURLEncoding = false)后,UNENCODED_URL现在只是传入的URL。
使用URL重写的更常见的方式是后向引用,其中{R:0}表示与规则匹配的URL的整个部分,{R:n}表示与特定部分匹配的URL部分正则表达式用括号括起来。如果RE中有多个部分用括号括起来,n表示RE 中使用的1 <= n <=#个括号对的顺序。
通过对熟化URL的相应??部分进行编码来计算得到的反向引用。但是,由于我们正在编码熟化的URL,所以不可能确定原始URL中是否存在“ /” ,或者是第一次解码的人工产物,因此我们不会尝试对其进行编码。在将useOriginalURLEncoding设置为false之后,反向引用现在只是熟化的URL。
原始网址:https://contoso.com/ab%2fde/
重写规则包含 | useOriginalURLEncoding =真 | useOriginalEncoding = FALSE |
BACK_REFERENCE | / AB /德/ | / AB /德/ |
UNENCODED_URL | / AB%252fde / | / AB%2fde / |
我们来看看传入URL已经被双重编码的另一个例子:http://contoso.com/ab%2520de/。在这个例子中,IIS从HTTP.SYS接收到的* cooked *表示是一次被解码的URL / ab%20de /。
当保留原始URL编码时,UNENCODED_URL服务器变量再次通过对熟化的URL进行编码来计算。关闭不符合规定的行为后,UNENCODED_URL仍然是原始网址。
反向引用是通过对熟化的URL进行编码来计算的。在将useOriginalURLEncoding设置为false之后,URL服务器变量现在就是熟化的 URL。
重写规则包含 | useOriginalURLEncoding =真 | useOriginalURLEncoding = FALSE |
BACK_REFERENCE | / AB%2520de / | / AB%20de / |
UNENCODED_URL | / AB%252520de / | / AB%2520de / |
在这两个示例中,useOriginalURLEncoding = false提供了一种通过使用UNENCODED_URL未修改原始URL的方法。这通常是反向代理场景中的预期结果。它也消除了URL重写模块所执行的任何双重编码。