【问题标题】:Apache mod_dav 400 Bad Request for non-existent collection resourceApache mod_dav 400 对不存在的收集资源的错误请求
【发布时间】:2012-01-23 18:01:24
【问题描述】:

Apache 似乎正在为一个简单的不存在的集合资源发回 400 Bad Request。

我有一个资源/test/junit/test.bin。我想检查集合 /test/junit/test.bin/ 是否存在(即同名的集合)---根据 RFC 2518,集合(带有斜线)和非集合是不同的。当我在/test/junit/test.bin/ 上发出PROPFIND 时,Apache 以 400 Bad Request 响应。

现在,我了解到许多人和实施已经模糊了集合和非集合之间的界限——也就是说,集合是否必须有一个结束斜线。但无论如何,集合/test/junit/test.bin/ 不存在——在不存在的集合上发出PROPFIND 并不是“错误请求”。 Apache 不应该简单地发出标准的 404 Not Found 或 410 Gone 吗?我的请求有什么“不好”的地方?

PROPFIND /test/junit/test.bin/ HTTP/1.1
depth: 1
content-length: 102
authorization: BASIC XXXXX
host: example.com

<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:">
    <D:allprop />
</D:propfind>

HTTP/1.1 400 Bad Request
Date: Mon, 23 Jan 2012 15:30:37 GMT
Server: Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8k DAV/2 SVN/1.7.2 mod_jk/1.2.28
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>

这是 Apache 在日志中添加的内容:

[Mon Jan 23 14:31:09 2012] [error] [client XX.XXX.XX.XXX] Could not fetch resource information.  [400, #0]
[Mon Jan 23 14:31:09 2012] [error] [client XX.XXX.XX.XXX] (20)Not a directory: The URL contains extraneous path components. The resource could not be identified.  [400, #0]

是的,我知道存在同名资源,我正在询问集合的属性。所以我们可以说“这就是 Apache 这样做的原因”。但这并不能解释任何事情——它只是对 Apache 将要做什么的预测。我想知道为什么 Apache 认为发回 400 而不是 404 更合适?

【问题讨论】:

  • 我个人想知道 apache 是否会在错误日志中显示更多详细信息。您可以将错误日志级别设置得相当高。
  • 好主意---我已经从日志中添加了相关条目。这是关于你会猜到什么。我不同意 Apache 的做法——还有其他人同意吗?
  • 我已经向 Apache 提交了一个错误:issues.apache.org/bugzilla/show_bug.cgi?id=52539

标签: apache http webdav


【解决方案1】:

我在 Apache 2.4 作为 Windows 2012 上的 Webdav 服务器运行时遇到了同样的错误,并解决了它禁用“mod_negotiation.so”:

#LoadModule negotiation_module modules/mod_negotiation.so

【讨论】:

    【解决方案2】:

    这是猜测:

    Apache 实际上允许将子路径发送到资源。 PHP 示例:

    http://example.org/index.php/foobar
    

    Foo bar 将作为 PATH_INFO 发送到 index.php。我的猜测是,现在错误地发回 HTTP/1.1 400 的功能是相同的。

    正确的响应确实是 404 Not Found,虽然因为它只是一个附加的斜线,我个人可能只是将 /test.bin/ 映射到 /test.bin。

    重定向到 /test.bin 也可以。

    您知道我不是普通人,我将 90% 的职业时间花在 HTTP 和 WebDAV、CalDAV 等上。

    【讨论】:

    • 感谢您的回复。当您说“Apache 实际上允许将子路径发送到资源”以及“Foo bar 将作为 PATH_INFO 发送到 index.php”时,我不太理解您在说什么。特别提到 PROPFIND 方法,RFC 2518 允许使用“Depth”标头来指定应返回哪些子资源,并且非常具体地说明应如何解释它。我在 RFC 2518 中找不到任何关于 PATH_INFO 的语言,或者如果非集合资源具有相似的名称,那么集合应该被区别对待。
    • 至于按照您的建议将/test.bin/ 映射到/test.bin,这似乎完全违反了RFC 2518。RFC 说“......资源可以接受一个没有尾随'/'的URI 指向到一个集合。在这种情况下,它应该在响应中返回一个内容位置标头,指向以“/”结尾的 URI”,但它没有提供相反的映射(例如 removing斜杠),这是这里讨论的内容。
    • 是的,我不是在谈论标准。这绝对是 apache 错误地实现的。您在询问为什么它可能被错误实施的理由,所以我给你我最好的选择。您希望从中获得什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    相关资源
    最近更新 更多