在IIS7 / 8 / 8.5中指定多个(gzip + brotli)httpCompression方案并确定brotli的优先级

时间:2016-10-20 14:10:55

标签: iis http-headers gzip http-compression brotli

我正在尝试使用Brotli的“Brotli compression module for Microsoft IIS”在IIS中使用新的iisspeed.com压缩方案。

如果我将<httpCompression>中的applicationHost.config配置部分更改为具有Brotli模块,则Brotli压缩模块本身可以正常工作。

问题是我想两者 gzip和Brotli,并且更喜欢Brotli

iisspeed.com上的文档说要这样做:

<httpCompression directory="path\to\temp\folder" minFileSizeForComp="50">
        <scheme name="br" dll="path\to\iisbrotli.dll" />
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
        ...
</httpCompression>

但是我发现这不起作用。

浏览器(本例中为Chrome)发送以下accept-encoding标题:

accept-encoding: gzip, deflate, sdch, br

这意味着浏览器可以接受Brotli编码br以及gzip我希望IIS比br更喜欢gzip,但似乎没有办法确定配置中每个<scheme>元素的优先级。我已经尝试更改.config文件中的顺序,但它没有效果。

IIS始终使用gzip,即使支持br也是首选,因为它的文件较小。

我已经搜索了Google,发现IIS 6中的每个压缩方案都有一个优先级设置,但似乎已经在IIS7 +中删除了。

它被称为HcPriority并进入IIS6配置数据库XML文件。

请参阅以下链接:

https://msdn.microsoft.com/en-us/library/ms525366(v=vs.90).aspx

https://blogs.iis.net/ksingla/changes-to-compression-in-iis7

https://forums.iis.net/t/1150520.aspx

如果客户端接受,我可以为IIS7 +做些什么来告诉IIS更喜欢br而不是gzip

2 个答案:

答案 0 :(得分:6)

您引用的Brotli模块似乎需要付费许可证,所以我没有尝试过,但我遇到了与我自己的open source Brotli plugin for IIS类似的问题。

正如您所指出的,当前浏览器会在gzip标题中deflateAccept-Encoding之后宣传Brotli支持。

HTTP RFC没有提供有关如何从具有相同优先级的许多Accept-Encoding值中进行选择的具体指导,因此将br内容返回给这些客户端是可以接受的。但是,似乎IIS总是选择与其配置的压缩方案之一匹配的第一个(从左到右)。

如果您希望启用两个方案,则可以在请求进入IIS管道时修改Accept-Encoding标头值。 IIS URL Rewrite Module可以通过简单的规则执行此操作。

Accept-Encoding标头由IIS管道中的HTTP_ACCEPT_ENCODING服务器变量表示,您可以在它到达压缩模块之前对其进行修改。以下是一个示例配置:

<rewrite>
    <allowedServerVariables>
        <add name="HTTP_ACCEPT_ENCODING" />
    </allowedServerVariables>
    <rules>
        <rule name="Prioritize Brotli">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_ACCEPT_ENCODING}" pattern="\bbr(?!;q=0)\b" />
            </conditions>
            <serverVariables>
                <set name="HTTP_ACCEPT_ENCODING" value="br" />
            </serverVariables>
        </rule>
    </rules>
</rewrite>

上面的规则在br标题中查找字符串;q=0(由字边界包围 - 而不是紧跟Accept-Encoding),并将其重写为简单br,只给IIS一个选择。

请注意,默认URL Rewrite配置不允许修改HTTP_ACCEPT_ENCODING变量。 allowedServerVariables元素会覆盖该限制,必须在applicationHost.config中进行配置。然后可以在配置层次结构中的任何级别定义重写规则,尽管将其设置为全局可能是有意义的。

答案 1 :(得分:2)

从你的第二个链接(强调我的):

  

当在Accept-Encoding头中出现多个请求时,HcPriority被删除作为方案使用选择选择取决于在Accept-Encoding头中首先出现的方案(假设没有q因子)。 这是根据HTTP规范

此处还讨论了:HTTP: What is the preferred Accept-Encoding for “gzip,deflate”?

如果您通过允许您手动设置请求标头(例如PostmanFiddler)的HTTP客户端或允许您使用Accept-Encoding: br, gzip, deflate的浏览器扩展名与{{1}}进行相同的请求您要更改请求标头(例如Chrome的ModHeader),即使gzip和/或deflate可用,您也应该会看到使用Brotli编码的响应。

编辑:我能够让Brotli模块按照需要工作(即,当它与最优选的一致时使用Brotli编码,无论在Accept-Encoding中的排序如何)registering it as a global native module并在两者之前对其进行排序动态和静态压缩模块。