我已经使用非常基本的configuration在Apache 2.4.7上设置了我的虚拟主机:
<VirtualHost *:80> ServerName foo.example.com DocumentRoot /var/www/html DirectoryIndex index.php FallbackResource /index.php </VirtualHost>
在文档根下面,我有以下结构:
/index.php /help/readme.txt
我提出请求时得到以下结果:
/bla -> 200 OK /help/ -> 404 Not Found /help/a -> 200 OK
看起来, /help/目录的存在导致Apache返回404因为那里没有index.php ,但是我希望所有请求都调用/index.php ,从而产生200 OK响应。
我不记得使用mod_rewrite时这是一个问题,但如果可能的话,我更喜欢使用FallbackResource 。 有没有办法来解决这个问题?
更新
它工作,如果我删除DirectoryIndex指令,但遭受五秒延迟问题 。
更新3
我正在运行以下testing环境; 目录结构如下:
./htdocs index.html test/ bla.txt ./conf httpd.conf ./logs
httpd.conf的内容是:
ServerName apache-bug.local Listen 8085 DirectoryIndex disabled DirectorySlash Off <VirtualHost *:8085> DocumentRoot /home/user/apache-bug/htdocs FallbackResource /index.html </VirtualHost>
我的config.nice包含:
"./configure" \ "--enable-debugger-mode" \ "--with-apr=/usr/local/apr/bin/apr-1-config" \ "--enable-dir=static" \ "--with-mpm=prefork" \ "--enable-unixd=static" \ "--enable-authn-core=static" \ "--enable-authz-core=static" \ "$@"
运行服务器:
httpd -X -d /home/user/work/apache-bug/
我自己也在回答这个问题,因为我很确定这个问题与mod_dir.c是如何工作的,我认为这是个bug 。
如果资源无法映射到本地文件系统,函数fixup_dflt()将运行,使用FallbackResource来确定应该加载哪个文档。
但是,当一个资源可以映射到本地文件系统,并且它是一个目录时,它将尝试通过运行fixup_dir()来parsing文档。 这个函数迭代DirectoryIndex值的列表直到find第一个合适的文档。
在我的情况下,configuration有一个空DirectoryIndex值的列表,所以fixup_dir()将失败,并返回一个404。
以下补丁适用于我( PR ):
static int dir_fixups(request_rec *r) { if (r->finfo.filetype == APR_DIR) { - return fixup_dir(r); + if (fixup_dir(r) != OK) { + /* use fallback */ + return fixup_dflt(r); + } + + return OK; } else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) { /* No handler and nothing in the filesystem - use fallback */ return fixup_dflt(r); } return DECLINED; }
它基本上在fixup_dir()失败后尝试fixup_dflt() 。
项目已经提交了一个解决scheme,定于2.5; 它也可能被移植到2.4。
该修复已被恢复,因为:
[至less]会导致
FallBackResource在mod_autoindex被踢入之前踢出。
我仍然试图找出如何避免这种情况。
你的configuration应该是正确的。
奇怪的是,这个问题似乎是mod_deflate 。
在这里成功复制你的configuration( 没有 404),我也得到了5秒的延迟。 但是,我注意到,当UA从Accept-Headers中忽略gzip时,页面即时显示/接收。 你可以用wget为自己testing一下。
有趣的是,使用strace进一步debugging显示,apache会将您的FallbackResource的内容发送到客户端的套接字,而不会在两种情况下都有明显的延迟差异。 这在线上也是明显的,在HTTP请求之后,应答请求从服务器发送到客户端,没有任何明显的延迟1 。
但是,在这种情况下使用mod_deflate时,UA并不知道服务器发送的数据何时结束,因此在TCP连接超时2之前不会呈现任何内容,并被服务器强制closures。 这符合HTTP / 1.0,closures连接表示内容结束。
对于HTTP / 1.1 ,服务器还有其他方法可以用来表示内容的结束 – 但是这些都不会在这里发生 。
无论是mod_dir还是mod_deflate中的bug,现在都超出了我的可用时间。 我通过禁用gzip压缩来实现它的无懈可击; 作为一个解决方法,直到问题解决好,你可以select性地禁用gzip。
1 )这告诉我们这个问题不是源于服务器上的无刷新缓冲区。
2 )默认情况下,超时是5秒与Apache – 这是你的5秒钟的地方。