在主机标头不匹配的虚拟主机环境中返回400

时间:2013-02-05 10:45:47

标签: http

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

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

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

GET / HTTP/1.1
Host: nothostedhere.com

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

所以我的问题是......

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


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

2 个答案:

答案 0 :(得分:5)

在这种情况下,

400并不是真正的语义正确的响应代码。

10.4.1 400 Bad Request

  

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

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

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

10.4.4 403 Forbidden

  

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

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

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

10.4.5 404 Not Found

  

服务器未找到与Request-URI匹配的任何内容

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

在HTTP / 1.1 Host:标头中是必需的。如果客户端声明它使用的是版本1.1并且未提供Host:标头,那么400肯定是正确的响应代码。如果客户端声明它使用的是1.0版本,则不需要提供主机头,这应该得到优雅处理 - 这种情况与无法识别的域相同。

在这个事件中你真的有两个选择:将请求路由到默认的虚拟主机容器,或者回复错误。如上所述,如果您要回复错误,我相信错误应该是403。

答案 1 :(得分:2)

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

  • 对于一般网站:
    假设从用户的浏览器触发请求是非常安全的,在这种情况下,我会对Host:标头的缺失或不正确性更加宽容。我甚至走得太远,并说Apache处理案例的方式(即回退到第一个适当的VHost)完全没问题。毕竟,你不想吓跑你的顾客。

  • 对于API / RPC类型的服务:
    这是一个完全不同的情况。您应该期望任何消费您服务的人都遵守您的规范。因此,如果这些要求消费者传递有效的Host:标题并且消费者没有这样做,那么您应该以合理的回复返回(400 Bad Request对我来说似乎没问题。)