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>
修改说明
- 匹配规则调整:把
<match url="(.*)" />改成<match url=".*" />,不再从匹配组获取路径 - 条件分组修改:在
{CACHE_URL}的匹配模式中加上(.*),这样{C:2}就能拿到域名后的完整原始编码路径(包括%2F这类编码字符) - 重写URL调整:直接用
{C:1}://Ubuntu-GLS{C:2}作为重写目标,确保原始编码路径完整传递 - 查询字符串设置:把
appendQueryString设为false,因为{C:2}已经包含了请求的查询参数,避免重复拼接
这样修改后,ARR就不会自动解码%2F,GitLab能收到正确的请求路径,返回正常响应。
内容的提问来源于stack exchange,提问作者Jane Glass
相关产品推荐
相关产品推荐

