昨天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.