http host vs server name

今天调试 Yale 的 cas 客户端,发现客户端返回地址总是为localhost,开始还以为这个地址是由服务器端根据refer和client address来解析得到的。后来 阅读客户端源码才知道是由客户端传递给服务器端的。

在获取客户端的callback地址时,使用 Client.php 中的 _getServerUrl 方法来计算。
该方法中前半部分在处理proxy后的情况,这是个复杂问题,因为根据代理服务器的级别程度不同,隐藏或修改的信息不同。只能按照信息是可靠的且是参考HTTP规范的来识别。
后半部分是一般情况,接下来讨论的重点。主要是HTTP的三个参数的处理 HTTP_HOST, SERVER_NAME ,SERVER_PORT。
HTTP_HOST 是 HTTP 请求中 HOST 头字段
  根据 HTTP/1.1 规范 (RFC 2616 ), HOST 应该符合如下要求,原文如下:

In order to prevent denial of service attacks, an invalidation based on the URI in a Location or Content-Location header MUST only be performed if the host part is the same as in the Request-URI.

 也就是 HOST 字段 应该和 URL 中的 HOST part 部分相同。基于该规则下,HTTP_HOST 可能会含有端口号。

 

SERVER_NAME 是当前Web服务器名,可在Web Server程序(如 Apache,Nginx)的配置文件中配置(server_name , 一般默认为 localhost)。

 PHP中的解释:
    The name of the server host under which the current script is executing. If the script is running on a virtual host, this will be the value defined for that virtual host.
  CGI文档中对SERVER_NAME参数的定义(规范):
The SERVER_NAME variable MUST be set to name of the server host to
which the client request is directed. It is a case-insensitive
hostname or network address. It forms the host part of the Script-
URI. The syntax for an IPv6 address in a URI is defined in RFC 2373   [12].
  SERVER_NAME = server-name
  server-name = hostname | ipv4-address | ( “[” ipv6-address “]” )
A deployed server can have more than one possible value for this
variable, where several HTTP virtual hosts share the same IP address.
In that case, the server uses the contents of the Host header to
select the correct virtual host.
另外Web Server中还可以配置 server_name_alias 。
SERVER_PORT 是 TCP 链接时的端口号,也就是服务器端配置的监听端口号。因为很多协议如HTTP默认80端口, HTTPS默认443端口。所以在request url中可以缺省。
综上,可以看到 http_host 和 server_name 可能相同,可能不同。不同时,可能只是因为端口部分一个有,一个没有。也可能完全不同。
在 CAS 的 客户端中,优先选取 server_name,然后再选取 http_host 。因为 这个原因导致了 前面的那个问题。
我想优先server_name的原因是因为在某些语言中如PHP,提示http_host可能会不存在(不规范的HTTP请求导致?)。
至于为什么php中http_host可能不存在,需要阅读PHP源码。
如果是因为HTTP请求本身导致,依据RFC2616的定义,HTTP_HOST 是必须有的,对于建立TCP链接蓄意破坏HTTP协议的请求导致http_host不存在,应该作为非法请求处理。
不仅仅程序语言问题,还有另外一个重大问题是涉及到不同的人:
    对于一个请求是否作为非法请求进行处理,往往是产品经理或者需求管理、系统安全人员的工作范畴。
    对于应用程序,http_host或server_name的使用是Web开发人员的工作。
    对于server_name的配置,是系统运维人员的工作。
因为在不同的应用环境下问题是不同的。http_host应该优先server_name处理,而标准CGI规范下,server_name 和 http_host中的hostname部分是相同的。

http host vs server name》上有1条评论

  1. 张迪张迪

    不愧是肖总!太虎了!看肖总在我的电脑上解决问题,我完全跟不上肖总的思路啊,一会儿就成酱油了!
    肖总这回是又干了运维的事,又干了开发的事。像抓包这种事本人一直不怎么会。
    肖总这次帮大忙了!这次的事主要还是因为对方文档不全,功力不够,弄得我们麻烦肖总。
    以后有类似的事我和夏威夷搞,搞不出来就算了,不麻烦肖总。

评论已关闭。