gerrit 安装配置完成后,正常情况没有问题,但是一旦涉及到子目录中的项目就会出现“HTTP Not Found” 错误,导致不能创建项目子目录,也不能访问已经存在的子目录中的项目。
gerrit 文档中针对 HTTP 反向代理的说明(参见 Reverse Proxy),说是要设置 “AllowEncodedSlashes On”,apache2 文档对的 AllowEncodedSlashes 解释是:允许编码的路径分隔符(%2F / 或者 %5C \)。
但是最新版的 Apache2 配置文件格式布局好像有很大调整,一开始没有找到文档中说的 VirtualHost 配置节点,把 AllowEncodedSlashes 放在 mods-enabled/proxy.conf 或者 apache2.conf 中都没有用。
网上也很难找到其他相关的问题解答,于是没办法只能用最原始的抓包来排查问题。
浏览器发出的请求是 GET /gerrit/projects/testing%2Famlogic/config,中间有一个 URL Encode 字节 %2F,解码后应该是斜线 “/”,只有子目录项目才会有目录分隔符“/”,这与不能访问子目录项目的现象吻合。
抓主机内回环接口报文(tcpdump -i lo) ,发现没有抓到 lo 接口的报文,apache2 收到请求后没有转发给 gerrit ,看来 AllowEncodedSlashes 没有起作用,apache2 直接拒绝了该请求。
搜索找到了 VirtualHost 配置节点在 sites-available/default 文件中,增加 AllowEncodedSlashes On 配置后,还是 “HTTP Not Found” 错误,再抓包,有 HTTP 转发请求给 gerrit,转发的请求对 URL 做了解码,变成 GET /gerrit/projects/testing/amlogic/config,看来 gerrit 要求没有解码的带 %2F 的 URL。
根据 apache2 文档,AllowEncodedSlashes 还有一个 NoDecode 模式,好像可以阻止解码,但是设置后,还是 “HTTP Not Found” 错误,再抓包,发现 apache2 发给 gerrit 的请求变成了 GET /gerrit/projects/testing%25%2Famlogic/config,确实没有解码,但是又额外对 % 进行了编码,真是诡异。
从网上找到了答案,Need to allow encoded slashes on Apache,这里解释说,虽然 NoDecode 模式阻止解码,但是反向代理模块会进行编码,需要设置反向代理模块的 ProxyPass 增加 nocanon 属性,像这样 ProxyPass /gerrit http://localhost:8081/gerrit nocanon 。
终于 OK 了 !