最近查了一些請求行URI和Host字段的資料。
HTTP請求的請求行包括
方法(METHOD)
請求URI(Request-URI)
協議版本(HTTP-Version)
其中請求URI在HTTP1.1中被命名為請求目標(request-target)。似乎是因為HTTP1.1協議新增方法請求的對象不僅限於URI了,為了方便討論,下面我們將請求行第二項均稱為請求URI。
請求URI在不同版本協議中定義不同
HTTP 1.0協議中請求URI有兩種[1]:
1.絕對URI(absoluteURI):形式類似於protocol://host[:port]/uri在 1.0協議中,絕對路徑只允許在發給代理的請求中使用。
2.絕對路徑(abs_path):形式類似於的/uri
HTTP 1.0協議中沒有host字段。是通過TCP連接標識主機的。
HTTP1.1協議中請求URI有4種[2]:
1.絕對URI(absolute-form):類似HTTP1.0。區別是在不再只用於發送給代理的請求,但是在代理請求中必須使用絕對URI(CONNECT、OPTIONS方法除外)。
2.絕對路徑(origin-form):類似於之前提到的/uri
3.認證格式(authority-form):僅在CONNECT方法中可用,格式為[ userinfo "@" ] host [ ":" port ] 其中userinfo包含用戶名/密碼等信息。
4.星號格式(asterisk-form):僅在OPTIONS方法中可用。格式為"*",表示對服務器發送OPTIONS請求。
在HTTP1.1中需要將協議、host、URI組合成“有效URI”(Effective Request URI),然后才能得到客戶端請求的資源
主要規則如下[2]:
1.請求URI如果是絕對URI,直接將絕對URI作為“有效URI“。
2.當OPTIONS請求通過代理時,如果沒有指定請求資源(/uri),在代理鏈的最后一個節點應該將請求URI改為星號形式。
3.當請求URI不是絕對URI時,Host的優先級為 服務器配置->請求URI中host->請求頭host字段->服務器默認host。
4.當請求URI不是絕對URI時,Port的優先級為 服務器配置->TCP連接port->請求頭host字段。
5.協議中要求瀏覽器(user agent)發送的請求URL中包含host、port信息和Host字段中的信息應該一致。
當請求URI中和Host字段主機名沖突時,比如:
GET http://www.baidu.com/ HTTP/1.1
Host: www.google.com
nginx將按照規則1.直接使用URI中的主機名,忽略掉后邊的Host字段信息。
事實上這種請求並不合法[2],但協議中並沒有規定如何處理,返回403也是可以的[3]
參考文檔:
[1]https://www.w3.org/Protocols/rfc1945/rfc1945
