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 的可靠性如何?的主要内容,如果未能解决你的问题,请参考以下文章