msgbartop
PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 – 左手代码 右手诗
msgbarbottom

28 Aug 08 HTTP1.0下HTTP_HOST为空

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


分享到:



Related Posts:

Tags: ,

10 Responses to “HTTP1.0下HTTP_HOST为空”

  1. 风雪之隅-鸟哥文章汇总 | 互联网菜鸟 |

    [...]   HTTP1.0下HTTP_HOST为空  一个巧妙的分页方法 31 Dec 08 一个低概率的PHP Core dump 21 Feb [...]

  2. PHP教程:HTTP1.0协议下HTTP_HOST为空的根本原因 | PHP爱好者 |

    [...] 原文链接:http://www.laruence.com/2008/08/28/483.html [...]

  3. LungZeno |

    錯別字:
    第一度關口→第一道關口

  4. LungZeno |

    錯別字:
    第一通關口→第一度關口

  5. LungZeno |

    我是刻意的,因為實質情況是這樣:
    平常溝通和工作,對於 IT 術語,人們使用純英文而不使用中文,甚至不知道對應的中文說法,或根本沒有對應的中文說法,等的嚴重程度為:
    香港>台灣>大陸
    在這個網路時代,大家都透過網路學習,加上大陸的人口遠多過港台,很多轉載文章都使用劣拙的繁簡轉換,因而很多台灣年青人都在使用大陸 IT 中文術語,除非他們在之前已在學校學到台灣版本,但教師也會透過網路學習……更不說極多香港人根本不懂分辨甚或不屑分辨。
    我堅持,其中一個原因是因為語文常是學習、理解、溝通的第一通關口。

  6. 雪候鸟 |

    你是台湾的? 都是繁体, 并且用词也不太一样, 呵呵

  7. LungZeno |

    我的句子有歧義,「只要分開指定 IP 地址和 port 就可以」是指「只要分開 host name 的指定與 IP 地址和 port 的指定就可以」。

  8. LungZeno |

    HOST 欄位通常用於實現 name-based 虛擬主機。
    HOST 欄位儲存了你在瀏覽器發請求時,完整 URL 中的域名(或 IP 地址)與連接埠(port,如果有的話),網路上封包的傳輸是使用 IP 地址,與域名無關,因此才有 DNS ,在發封包前先由域名 lookup 出 IP 地址,而伺服器軟體和客戶端軟體接收封包是依靠 IP 地址和 port (TCP port 或 UDP port),也是與域名無關,你使用一些設定或工具,host name是可以任意填寫的(攻擊?),只要分開指定 IP 地址和 port 就可以,不一定要用那 host name 對應的 IP 地址和 port , HTTP Proxy 就是這樣實現的。

  9. 雪候鸟 |

    HOST指明了要访问的主机名, DNS不知道你是指什么,是指服务器的域名么?

  10. migou |

    请教一下HTTP的HOST字段与DNS有什么区别和联系呢?

Leave a Reply

*