昨天xuepeng师兄提出一个问题是 $_SERVER['HTTP_HOST']为空, 经过我翻看RFC文档以及测试,得出结论如下:

在http 1.1中, host字段是不能为空的,如果为空, 服务器会认为是bad request

但是在http 1.0中, host字段是可以为空的. 如:

<?php
$fp = fsockopen("localhost", 80, $errno, $errstr, 30);
$header =  "GET /index.php";
$header .= " HTTP/1.0\r\n";
$header .= "Connection:Close\r\n\r\n";
fwrite($fp, $header);
    echo fread($fp, 1024);
fclose($fp);
?>


其中,主机的index.php只是var_dump($_SERVER['HTTP_HOST']);

可以看到,当你指明使用http 1.0协议的时候, 请求正常,返回结果是false;

但是如果你指明协议是http 1.1 :

<?php
$fp = fsockopen("localhost", 80, $errno, $errstr, 30);
$header =  "GET /index.php";
$header .= " HTTP/1.1\r\n";
$header .= "Connection:Close\r\n\r\n";
fwrite($fp, $header);
    echo fread($fp, 1024);
fclose($fp);
?>


则结果是400 bad request;

究其原因是因为在HTTP1.0的时候, 并没有设想到现在有这么多服务器共用一个IP的情况(virtual host), 而在HTTP1.1的时候,加入了对多个HOST共用一个IP的支持.

以下文字摘自RFC2616:

> 14.23 Host
>
> The Host request-header field specifies the Internet host and port
>
> number of the resource being requested, as obtained from the original
>
> URI given by the user or referring resource (generally an HTTP URL,
>
> Fielding, et al. Standards Track [Page 128]
> RFC 2616 HTTP/1.1 June 1999
>
> as described in section 3.2.2). The Host field value MUST represent
>
> the naming authority of the origin server or gateway given by the
>
> original URL. This allows the origin server or gateway to
>
> differentiate between internally-ambiguous URLs, such as the root "/"
>
> URL of a server for multiple host names on a single IP address.
>
> Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
>
> A "host" without any trailing port information implies the default
>
> port for the service requested (e.g., "80" for an HTTP URL). For
>
> example, a request on the origin server for
>
> would properly include:
>
> GET /pub/WWW/ HTTP/1.1
>
> Host: www.w3.org
>
> A client MUST include a Host header field in all HTTP/1.1 request
>
> messages . If the requested URI does not include an Internet host
>
> name for the service being requested, then the Host header field MUST
>
> be given with an empty value. An HTTP/1.1 proxy MUST ensure that any
>
> request message it forwards does contain an appropriate Host header
>
> field that identifies the service being requested by the proxy. All
>
> Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request)
>
> status code to any HTTP/1.1 request message which lacks a Host header
>
> field.
>
> 以下省略.....

后记: 虽然HTTP_HOST不能缺失, 但是可以为空值 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23):

> If the requested URI does not include an Internet host name for the service being requested, then the Host header field MUST be given with an empty value.