IIS错误地解码包含系统区域设置之外的字符的URL

时间:2017-10-19 10:24:24

标签: iis utf-8 isapi wfastcgi

如果URL包含UTF-8编码字符(当前系统区域设置不支持),则IIS似乎错误地将请求URL传递给Web应用程序。所有“不支持”的字符都被问号('?')取代。

示例:系统区域设置设置为挪威语。 以下URL工作正常:

/myapp/Blåbærsyltetøy/

以下网址不起作用:

/myapp/черничный-джем/

在这两个网址中,非ASCII字符编码为UTF-8,然后进行百分比编码,因此实际网址如下所示:

/myapp/Bl%C3%A5b%C3%A6rsyltet%C3%B8y/
/myapp/%D1%87%D0%B5%D1%80%D0%BD%D0%B8%D1%87%D0%BD%D1%8B%D0%B9-%D0%B4%D0%B6%D0%B5%D0%BC/

该应用程序使用两种处理请求的方式:

  • wfastcgi + Python
  • ISAPI + C ++

两者都遇到了同样的问题,如果URL只包含系统区域设置支持的字符,则两者都没有问题。

对于ISAPI,看起来EXTENSION_CONTROL_BLOCK::lpszPathInfo已经提供了经过百分比解码的URL,其中所有“不受支持的”字符都已被问号替换。 EXTENSION_CONTROL_BLOCK::lpszPathInfo属性是一个多字节字符串,并且没有此结构的宽字符串版本。

有没有办法获取原始的百分比编码的URL或阻止IIS解码URL来解决问题?

1 个答案:

答案 0 :(得分:0)

ISAPI解决方案

从服务器变量HTTP_URL而不是PATH_INFO获取请求网址。这将提供原始的百分比编码URL,然后可以正确解码(通过百分比解码为字节数组并将该字节数组解释为UTF-8编码的字符串)。

此变量包含查询字符串和URL重写之前的原始路径,这可能是不需要的,因此可能需要一些额外的处理。

此外,对于错误处理程序请求,此变量包含格式类似于

的字符串
<DLL_PATH>?<STATUS_CODE>;<ORIGINAL_HTTP_URL>

需要解析。但它包含PATH_INFO包含的所有信息,除非没有错误的解码。

注意:使用Path_INFO而不是GetServerVariable结构获取EXTENSION_CONTROL_BLOCK 解决编码问题。

wfastcgi解决方案

默认情况下,服务器变量使用系统区域设置(在Python中称为'mbcs')进行编码。可以通过设置注册表项来更改此行为:

reg add HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\w3svc\Parameters /v FastCGIUtf8ServerVariables /t REG_MULTI_SZ /d REQUEST_URI\0PATH_INFO

请注意,这会影响同一服务器上的所有wfastcgi应用程序,并且可能会破坏不希望变量为UTF-8编码的现有应用程序(相当不太可能,因为任何使用非ASCII URL的理智应用程序都将使用UTF- 8编码......)。

另见https://support.microsoft.com/en-us/help/2277918/fix-a-php-application-that-depends-on-the-request-uri-server-variable