记念Apache2 CheckCaseOnly一个顽固在BUG

手头有个pip源, 用过pip的人都知道, pip安装软件包的时候, 是不区分大小写的, 为了让Apache支持这一个特性, 我在apache的配置中加上了以下配置

CheckSpelling on
CheckCaseOnly on
问题表现

某次用户反馈, 在安装一个名叫twisted包时, 页面报Not Found, 继续测试后发现, 如果用Twisted是可以安装, 但用twisted却Not Found, 而使用TWisted也是可以安装到对应的包的, 这说明apache的大小写修正能起作用

而硬盘上, 实际的对应的目录如下

Twisted
TwistedChecker
Twisted-Flow
TwistedGit
Twisted-Goodies
TwistedSNMP
TwistedSNMP-working
TwistedTwitterStream
Twisted-Web2
TwistedWebsocket
twisted-csp
twisted-dev-tools
twisted-gears
twisted-hl7
twistedhttpstream
twistedinput
twisted.internet.processes
twisted-json-socket
twistedschedule
twisted.scheduling
twistedSim
twisted-smpp
twisted-theseus

追查apache的错误日志发现有这么几句, 大概的意思就是apache找不到twisted对应的目录, 但它发现候选的目录有twisted.internet.processes和twisted.scheduling, 候选数量不唯一,无法完成拼写纠正

[Wed Jan 14 15:08:11 2015] [error] [client 127.0.0.1] (20023)The given path was above the root path: dir_walk error, path_info / is not relative to the filename path /disk2/pypi/web/simple/twisted.internet.processes/ for uri /pypi/simple/twisted.internet.processes/
[Wed Jan 14 15:08:11 2015] [error] [client 127.0.0.1] (20023)The given path was above the root path: dir_walk error, path_info / is not relative to the filename path /disk2/pypi/web/simple/twisted.scheduling/ for uri /pypi/simple/twisted.scheduling/
[Wed Jan 14 15:08:11 2015] [error] [client 127.0.0.1] Negotiation: discovered file(s) matching request: /disk2/pypi/web/simple/twisted (None could be negotiated).
奇怪的地方

我的apache同时配置了CheckSpelling和CheckCaseOnly, 按照apache2.2的mod_speling的文档, CheckSpelling和CheckCaseOnly同时配置后, 只会对拼写进行大小写的纠正, 而不会纠结错误的拼写, 按理是不会出现输入twisted后,apache去纠正为twisted.internet.processes和twisted.scheduling的情况, 而应该纠正为Twisted, 但日志显示apache实际上还是尝试纠正为twisted.internet.processes和twisted.scheduling, 并因为结果不唯一, 报Not Found出来

神奇的BUG

原本我以为是我配置错了, 但查了很久, 一直没发现问题, 直到我搜索到这么一个bug反馈:
CheckCaseOnly On does not stop Multiple Choices based on common basename

实际上bug的提交者和我遇到的问题一样, 不过他没描述清楚. 我重新描述下apache这个bug

CheckSpelling 可以纠正打错的字符(包括大小写), 但如果你输入一个url时, 对应目录下没有正确的, 同时又存在几个候选的结果时(相近的名字), apache就会报错
如果你只需要大小写纠正, 就需要同时也配置上CheckCaseOnly

但有这么一种情况

1. 文件有 foo.gif,  foo.jpg, Foo
在配置了CheckCaseOnly后, 你输入foo, apache会报找不到, 因为它认为foo.gif和foo.jpg也是结果之一, 而不考虑你是CheckCaseOnly
思考

对于bug, 我们并不少遇到, 但这个bug让我诧异的地方是它存在了这么久, 从反馈页面上来看, 2008年提交, 2015年还有人更新了状态, 从大家的讨论中可以看出, 这个bug还没有解决, 包括2.4版本, 这是多么不可思议的事, 整整7年还没有解决

当然有开发者提到这个bug之所以没fix, 是因为fix的方法与mod_speling的实现有冲突? 不知道我的理解是不是对的, 最后有人提交了最新的patch, 只希望能尽快看到fix的版本出来

我最近尝试把apache换成nginx, 但没找到nginx有类似apache mod_speling的方法? 只能暂时放弃, 如果有人知道如何做, 非常欢迎给我留言

2015-01-14 16:271061
  • amoGo2017-08-16 17:35

    test.