HTTP_HOST 的可靠性如何?

Posted

技术标签:

【中文标题】HTTP_HOST 的可靠性如何?【英文标题】:How reliable is HTTP_HOST? 【发布时间】:2011-05-05 00:19:38 【问题描述】:

我编写了一个 php 脚本,我想在同一服务器上的多个域上使用它(指向同一个脚本)。我想为脚本添加功能,以便随时找出脚本正在使用的域。 HTTP_HOST 可用于查找域,但是,我读到它不可靠,尤其是在旧浏览器中。我的理解是大多数 Apache 服务器都使用虚拟主机,它们无论如何都使用相同的方法,所以如果它不是托管服务提供商的问题,那么它不应该是我的代码的问题。

任何人都可以验证这一点并消除混乱吗?

【问题讨论】:

【参考方案1】:

编辑:我已更正:HTTP 1.0 请求中不存在 HOST 标头。请参阅@Bruno 的答案。出于安全考虑,将我的留在原地

我知道的 HTTP_HOST 的唯一问题是安全问题,而不是兼容性问题。

安全问题源于HTTP_HOST 是由用户发送的。如果 Web 服务器设置不正确和/或有问题,任意 HTTP_HOST 值可能会出现在您的站点/脚本中(参见例如 here 以了解详细讨论)。您的应用程序需要为此做好准备。

最好永远不要信任 HTTP_HOST(例如,在 PHP 脚本中处理它之前为其设置一个允许值的数组可能是个好主意):

<?php
  $allowed_hosts = array("domain1.com", "domain2.com", "domain3.com");

  if (!in_array(strtolower($_SERVER["HTTP_HOST"]), $allowed_hosts))
   die ("Unknown host name ". $_SERVER["HTTP_HOST"]);

【讨论】:

+1 也是您的答案,虽然这与旧版浏览器的兼容性无关,但绝对是“HTTP_HOST 的可靠性如何?”的主题 @Pekka 这就是我打算做的。这也带来了另一个问题,那就是让 Apache 解决这个问题并改用服务器别名 HTTP_SERVER 会更好。我唯一遇到的问题是使 host.conf 动态化。 @andicrook 可以,但您必须为每个可能的域名设置一个虚拟主机。但是看到你无论如何都需要将所有域名引入 httpd.conf ...... 我应该能够将虚拟主机设置为动态或使用 CNAMES @andi 我必须纠正自己,我很确定 可以使用通配符。 Serverfault.com 可能对特定问题有更好的答案【参考方案2】:

HTTP_HOST 用于 HTTP 1.1 用户代理在请求期间发送的 Host: 标头。 HTTP 1.0 客户端不使用它,因此它不会出现。但是,现在,我认为 HTTP 1.0 客户端仍然不多。

【讨论】:

现在甚至大多数 HTTP 1.0 客户端都已扩展为使用此字段 - 只有旧的、未更新的 HTTP 1.0 不提供它。 @Pekka 没什么大不了的。这种虚构的客户端无法访问大多数站点(基于虚拟主机的站点),因此,它是不切实际的。 @Col 是的,这就是我想知道的:这样的客户端如何从多虚拟主机服务器请求资源?那一定是真的老了。无论如何,它回答了这个问题【参考方案3】:

Pekka 的回答似乎更有趣,但您似乎想知道哪些浏览器支持 http 1.1,哪些不支持。 在谷歌上找到这个:http://www.1-script.com/forums/Browser-Support-for-HTTP-1-1-article34982--8.htm

来自该线程的注释:“HTTP 1.0 浏览器无法访问非默认虚拟主机。” 这意味着据我所知,不支持 http 1.1 的浏览器无法访问共享服务器上的任何网站。共享主机上有很多网站。通过使用 HTTP_HOST 变量,子域也可能(虽然不确定)以相同的方式“检测到”。

读完这些后,我真的不认为有人使用现在这么旧的浏览器,他们不可能真正浏览网络:)

【讨论】:

请注意,仍然有很多手机使用 HTTP/1.0 你有吗?如果他们实际上无法访问子域,我会很好奇。 是的,Apache 对大多数虚拟主机使用 HTTP_HOST,如果其基于 IP 的托管,那么它可以使用 DNS 反向查找,这无论如何都会产生开销【参考方案4】:

这是我在similar question 中回答的:


出于其他目的我自己对此进行了调查:

"HTTP/1.0 被代理、一些移动客户端和 IE 使用 配置为使用代理。所以 1.0 似乎仍然占非 整体网络流量的微不足道的百分比。 ... 是的,还有很多 1.0 客户端。”

来源(2009 年 7 月):http://groups.google.com/group/erlang-programming/msg/08f6b72d5156ef74

:-(


我个人在我的网站上收到很多 HTTP/1.0 请求,但缺少 HTTP_HOST :-(

【讨论】:

【参考方案5】:

这是我偶然发现的一篇旧帖子,我给出的解决方案是:

我创建了一个 JSON 文件(我的代码大量使用了我称之为令牌的这些文件),以成为唯一的事实来源,并同时开放以供谁知道应用程序中会出现什么新事物进行修改/框架:

// accounttoken.json

    "site": 
        "email": "admin@email.com",
        "password": "Bty1!",
        "firstname": "John",
        "secondname": "Doe",
        "country": "USA",
        "username": "Admin",
        "role": "admin",
        "protocol": "http://",
        "domain": "a9623c7ca853.eu.ngrok.io",
        "site_key": "fgRt4%$x!0($DqJi",
        "language": "en"
    ,
    "google": 
        "client_id": "51965.apps.googleusercontent.com",
        "client_secret": "8Kz"
    ,
    "db_mysql": 
        "db_port": 3306,
        "db_user": "<user>"
    ,
// more entries here...

现在,您所要做的就是在一个文件中查阅您的条目:

// find php executable
cent$ whereis php
php: /usr/bin/php7.0 /usr/bin/php /usr/lib/php /etc/php /usr/include/php ...

// start interactive shell
cent$ /usr/bin/php7.0 -a

php > $json = file_get_contents('accounttoken.json');
php > $json = json_decode($json, true);
php > echo('Your domain is: ' . $json['site']['domain']);
php > echo('The site url is: ' . $json['site']['protocol'] . $json['site']['domain']);
php > quit

【讨论】:

已经证明是正确的:另一个 json 文件中的cookie.domain 应该设置为localhost,而这个文件中的site.domain 应该像我的示例一样在将localhost 重定向到ngrok 服务器并测试身份验证时设置!

以上是关于HTTP_HOST 的可靠性如何?的主要内容,如果未能解决你的问题,请参考以下文章

TCP协议如何保证数据可靠性

UDP如何保证传输的可靠性

rabbitmq如何保证消息可靠性

大数据开发工程师Hadoop(HDFS是如何保证数据可靠性的?)

如何保证消息队列的可靠性传输?

kafka是如何保障消息的可靠性的(一)