3

考虑一个提供三个虚拟主机的 Web 服务器:

  • mysite.com
  • myothersite.com
  • imnotcreative.com

现在假设服务器接收到以下原始请求消息(代码格式化删除了终止\r\n序列):

GET / HTTP/1.1
Host: nothostedhere.com

我在 RFC 2616 中没有看到任何关于如何响应当前服务器上不存在的主机名的请求的指南(也许我错过了?)。例如,Apache 将简单地将其配置中定义的第一个虚拟主机用作“主主机”,并假装客户端请求该主机。显然这比返回400 Bad Request响应更健壮,并保证客户端总是看到一些表示。

所以我的问题是...

除了“健壮性与正确性”论点之外,任何人都可以提供其他理由来阻止我400在使用 HTTP/1.1 协议时客户端请求不存在的主机时使用(或其他错误代码)响应吗?


请注意,所有 HTTP/1.1 请求必须根据 RFC 2616指定Host:标头。对于 HTTP/1.0 请求,唯一真正的选择是提供“主要”主机结果。这个问题专门针对 HTTP/1.1 协议请求。

4

2 回答 2

5

在这种情况下,400 并不是真正语义正确的响应代码。

10.4.1 400 错误请求

由于语法错误,服务器无法理解该请求。

这不是已经发生的事情。该请求在语法上是有效的,并且当您的服务器到达路由阶段(当您检查标头的值时)时,这已经确定了。

我会说这里正确的响应代码是 403:

10.4.4 403 禁止

服务器理解请求,但拒绝执行。

这更准确地描述了发生的事情。服务器拒绝完成请求,因为它无法完成,并且可以在消息实体中提供更详细的错误消息。

还有一个论点是 404 是可以接受/正确的,因为找不到满足请求的合适文档,但我个人认为这不是正确的选择,因为 404 指出:

10.4.5 404 未找到

服务器没有找到任何与 Request-URI 匹配的东西

这明确提到了 Request-URI 的问题,并且在路由阶段的早期阶段,您可能对 URI 不感兴趣,因为您首先需要将请求分配给主机,然后才能确定它是否具有合适的文档处理 URI 路径。

In HTTP/1.1 Host: headers are mandatory. If a client states that it is using version 1.1 and does not supply a Host: header then 400 is definitely the correct response code. If the client states that it is using version 1.0 then it is not required to supply a host header and this should be handled gracefully - and this scenario amounts to the same situation as an unrecognised domain.

Really you have two options in this event: route the request to a default virtual host container, or respond with an error. As outlined above, if you are going to respond with an error, I believe the error should be 403.

于 2013-02-05T12:46:36.117 回答
2

我想说这在很大程度上取决于您希望使用您的服务的客户类型以及您提供的服务类型。

  • 对于一般网站:
    假设请求是从用户的浏览器触发的,这是相当安全的,在这种情况下,对于Host:标题的缺失或不正确,我会更加宽容。我什至会说 Apache 处理这种情况的方式(即回退到第一个适当的 VHost)非常好。毕竟,您不想吓跑您的客户。

  • 对于 API/RPC 类型的服务:
    这是完全不同的情况。您应该期望任何/谁使用您的服务来遵守您的规范。所以,如果这些要求消费者传递一个有效的Host:标头而消费者没有这样做,你应该返回一个合理的响应(400 Bad Request对我来说似乎很好)。

于 2013-02-05T11:10:02.783 回答