You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IIS ARR反向代理保留%2F编码,解决GitLab API 404问题

GitLab API通过IIS ARR访问时%2F被转义的问题解决

问题详情

  • 局域网内Ubuntu-GLS虚拟机上部署了GitLab CE,通过主服务器的IIS ARR URL Rewrite模块实现外网访问
  • GitLab API获取仓库文件时,必须用编码为%2F的斜杠分隔目录,例如发送请求:
    curl --header "PRIVATE-TOKEN: <myPrivToken>" "http://gitlab.mysite.com/api/v4/projects/8/repository/files/DemoAM%2F.project?ref=master"
  • ARR会自动把请求中的%2F替换成正斜杠,导致GitLab收到的路径变成/api/v4/projects/8/repository/files/DemoAM/.project,直接返回404错误
  • 但直接访问虚拟机时,请求路径里的%2F会被保留,GitLab能正常返回200响应
  • 试过设置useOriginalURLEncoding=false但没用,而且没法修改GitLab的请求规则,现在需要让重写规则里的{R:1}字符串原封不动传递,不替换任何编码字符

当前使用的URL重写规则

<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAny">
        <add input="{CACHE_URL}" pattern="^(https?)://gitlab\.mysite\.com" />
    </conditions>
    <action type="Rewrite" url="{C:1}://Ubuntu-GLS/{R:1}" appendQueryString="true" />
    <serverVariables>
        <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
        <set name="HTTP_ACCEPT_ENCODING" value="" />
    </serverVariables>
</rule>
<outboundRules>
    <rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1" enabled="true">
       <match filterByTags="A, Form, Img" pattern="^http(s)?://Ubuntu-GLS/(.*)" />
        <action type="Rewrite" value="http{R:1}://gitlab.mysite.com/{R:2}" />
    </rule>
    <preConditions>
        <preCondition name="ResponseIsHtml1">
            <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
        </preCondition>
        <preCondition name="NeedsRestoringAcceptEncoding">
            <add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".*" />
        </preCondition>
    </preConditions>
</outboundRules>

可行解决方案

核心思路是放弃使用{R:1}(因为它是解码后的路径),改用{CACHE_URL}变量中提取的原始编码路径。修改后的入站规则如下:

<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
    <match url=".*" />
    <conditions logicalGrouping="MatchAll">
        <add input="{CACHE_URL}" pattern="^(https?)://gitlab\.mysite\.com(.*)" />
    </conditions>
    <action type="Rewrite" url="{C:1}://Ubuntu-GLS{C:2}" appendQueryString="false" />
    <serverVariables>
        <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
        <set name="HTTP_ACCEPT_ENCODING" value="" />
    </serverVariables>
</rule>

修改说明

  1. 匹配规则调整:把<match url="(.*)" />改成<match url=".*" />,不再从匹配组获取路径
  2. 条件分组修改:在{CACHE_URL}的匹配模式中加上(.*),这样{C:2}就能拿到域名后的完整原始编码路径(包括%2F这类编码字符)
  3. 重写URL调整:直接用{C:1}://Ubuntu-GLS{C:2}作为重写目标,确保原始编码路径完整传递
  4. 查询字符串设置:把appendQueryString设为false,因为{C:2}已经包含了请求的查询参数,避免重复拼接

这样修改后,ARR就不会自动解码%2F,GitLab能收到正确的请求路径,返回正常响应。

内容的提问来源于stack exchange,提问作者Jane Glass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:35:29