即使目录存在,也使用FallbackResource

我已经使用非常基本的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()

更新2015-04-21

项目已经提交了一个解决scheme,定于2.5; 它也可能被移植到2.4。

更新2015-05-18

该修复已被恢复,因为:

[至less]会导致FallBackResourcemod_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秒钟的地方。