即使目录存在,也使用 FallbackResource

即使目录存在,也使用 FallbackResource

我已经在 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

我正在运行以下测试环境;目录结构如下:

./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/

答案1

mod_dir.c我也亲自回答了这个问题,因为我很确定这个问题与工作原理有关内部我认为一个错误

如果资源无法映射到本地文件系统,则该函数fixup_dflt()将运行,使用来FallbackResource确定应该加载哪个文档。

然而,当资源被映射到本地文件系统并且它是一个目录,它将尝试通过运行来解析文档fixup_dir();此函数迭代值列表,DirectoryIndex直到找到第一个合适的文档。

就我而言,配置有一个空的DirectoryIndex值列表,因此fixup_dir()将失败并返回 404。

以下补丁对我有用(公共关系):

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_dflt()后再尝试fixup_dir()

更新 2015-04-21

A使固定已经提交给项目,预计发布2.5版本;也可能移植到2.4版本。

更新 2015-05-18

已修复已恢复因为:

[...] 它至少会FallBackResource在可能发挥作用之前导致mod_autoindex其发挥作用。

我仍在尝试找出如何避免这种情况。

答案2

你的配置应该是正确的。

奇怪的是,问题似乎是mod_deflate

在此处成功重现您的配置后(不是出现 404 错误),我也遇到了 5 秒的延迟。但是,我注意到,当 UA 省略gzip其 Accept-Headers 时,页面会立即显示/接收。您可以使用 亲自测试这一点wget

有趣的是,进一步的调试strace表明,apache 将您的内容发送FallbackResource到客户端的套接字,而延迟没有明显差异两个都情况。这在线上也很明显,在 HTTP 请求之后,服务器向客户端发送了一个回复包,没有任何明显的延迟1

然而,在这种情况下使用 mod_deflate 时,UA 似乎不知道服务器发送的数据何时结束,因此在 TCP 连接超时2并被服务器强制关闭之前不会呈现任何内容。这符合 HTTP/1.0,其中关闭的连接表示内容结束。

为了HTTP/1.1,服务器有其他可用于表示内容结束的手段但这些似乎都没有发生在这里

但是,目前我无法确定该错误是隐藏在 mod_dir 还是 mod_deflate 中。我通过禁用 gzip 压缩使其完美运行;作为一种解决方法,在问题彻底解决之前,您可以有选择地禁用 gzip。

1 ) 这告诉我们问题不是源于服务器上未刷新的缓冲区。2
)默认情况下,apache 的超时时间为 5 秒 - 这就是 5 秒的来源。

相关内容