編譯自:
request_processing
目錄:
- name-based 虛擬主機
- 對于未定義 server name 的訪問請求趣倾,如何防止其被處理
- 混合使用 name-based 虛擬主機和 IP-based 虛擬主機
- 一個簡單的 PHP 站點配置示例
name-based 虛擬主機
當一個訪問請求到達 nginx乒躺,nginx 會考慮選擇某一個 server 處理訪問請求。
我們以一個包含三個 server 區(qū)塊的配置來講解:
server {
listen 80;
server_name example.org www.example.org;
...
}
server {
listen 80;
server_name example.net www.example.net;
...
}
server {
listen 80;
server_name example.com www.example.com;
...
}
這三個虛擬主機均監(jiān)聽于 *:80 端口所宰。根據(jù)上面的配置悲没,nginx 僅通過檢查請求首部中的 “HOST” 字段來決定讓哪個虛擬主機處理訪問請求。如果該字段的值沒有匹配任何虛擬主機形娇,或者請求首部中沒有 “HOST” 字段锰霜,nginx 會將該請求路由到 *:80 端口的默認 server。
在上面的配置中桐早,默認 server 是第一個 server —— 這是 nginx 的標準默認行為癣缅。我們也可以顯式指定一個默認 server,使用 listen 指令的 default_server 參數(shù)來指定哄酝,
例如:
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
*Note*:
default_server 參數(shù)從 0.8.21 之后開始使用友存,之前是 default 參數(shù)。
要注意陶衅,默認 server 是監(jiān)聽端口的一個屬性屡立,不是 server name 的屬性。稍后將進一步描述這個問題搀军。
對于未定義 server name 的訪問請求膨俐,如何防止其被處理
如果希望禁止未定義 “Host” 請求首部字段的訪問請求,可設置一個 server 用于丟棄這樣的請求:
server {
listen 80;
server_name "";
return 444;
}
我們在這里將 server name 設置為一個空字符串奕巍,它能匹配未攜帶 “Host” 請求首部字段的訪問請求吟策,并且返回一個特殊的狀態(tài)碼 444 以關閉連接,444 不是標準的 nginx 狀態(tài)碼的止。
Note:
從 0.8.48 版開始檩坚,這個設置變成了 nginx 的默認設置,所以 server_name "" 可被刪去诅福。
在更早的版本中匾委,物理主機的主機名被設置為 default server name。
混合使用 name-based 虛擬主機和 IP-based 虛擬主機
現(xiàn)在我們看一個更復雜的配置案例氓润,這里有多個虛擬主機監(jiān)聽于不同的地址:
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80;
server_name example.com www.example.com;
...
}
根據(jù)這份配置赂乐,nginx 首先檢查訪問請求的 IP 地址和端口號,將它與 server 區(qū)塊的 listen 指令的參數(shù)進行對比咖气,過濾掉不匹配的 server挨措。然后 nginx 檢查訪問請求的 “Host” 請求首部字段,將它與剩下的 server 區(qū)塊中的 server_name 進行對比崩溪,看能否匹配浅役。如果沒有匹配的 server,該請求將交給 default server 處理伶唯。
例如觉既,nginx 在 192.168.1.1:80 端口接收到對于 www.example.com 的訪問請求,因為在 192.168.1.1:80 端口沒有匹配的 server name,這個請求最后將被交給 192.168.1.1:80 端口的 default server 處理瞪讼,也就是第一個server钧椰。
正如前面提到過,default server 是監(jiān)聽端口的屬性符欠,所以對于不同的監(jiān)聽端口嫡霞,可以分別為其定義不同的 default server。
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80 default_server;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80 default_server;
server_name example.com www.example.com;
...
}
192.168.1.1:80 端口的默認 server 是第二個 server背亥;
192.168.1.2:80 端口的默認 server 是第三個 server秒际。
一個簡單的 PHP 站點配置示例
最后我們來看一個 PHP 站點的例子悬赏,看看 nginx 是如何選擇 location 處理請求的:
server {
listen 80;
server_name example.org www.example.org;
root /data/www;
location / {
index index.html index.php;
}
location ~* \.(gif|jpg|png)$ {
expires 30d;
}
location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
nginx 首先根據(jù)訪問請求的 URI 查找匹配的定義了 prefix 前綴的 location狡汉,并記住其中匹配的最長的前綴。在上面的例子中闽颇,定義了前綴的 location 只有一個盾戴,而且前綴為 “/”,它是最短的前綴兵多,能匹配所有請求尖啡。因為 “/” 前綴最短,所以這個 location 總是被作為最后的備選剩膘。
然后 nginx 開始檢查指定了正則表達式的 location衅斩,依照配置文件中的順序依次檢查是否與訪問請求的 URI 匹配,當找到第一個匹配的正則表達式怠褐,nginx 不再繼續(xù)檢查后面的 location畏梆,nginx 將使用找到的第一個匹配正則表達式所對應的 location。如果沒有匹配的 正則表達式奈懒,nginx 將使用之前記住的擁有最長匹配前綴的 location奠涌。
要注意的是,所有類型的 location 僅測試請求的 URI 部分磷杏,不帶參數(shù)溜畅。因為在查詢字符串中的參數(shù),可能以
幾種方式提供:
/index.php?user=john&page=1
/index.php?page=1&user=john
除此之外极祸,在查詢字符串中慈格,任何人可以請求任何事情:
/index.php?page=1&something+else&user=john
現(xiàn)在我們仔細研究一下根據(jù)上面的配置,nginx 將會如何處理訪問請求:
訪問請求為 “/logo.gif”
對于 “/logo.gif” 的請求首先被 prefix location “/” 所匹配遥金,然后被正則表達式 “.(gif|jpg|png)$” 所匹配浴捆,因此,這個請求將被交給后者處理汰规。使用 “root /data/www” 指令汤功,該請求被映射為 /data/www/logo.gif,這個文件被發(fā)送給客戶端溜哮。訪問請求為 “/index.php”
對于 “/index.php” 的請求同樣首先被 prefix location “/” 所匹配滔金,然后被正則表達式 “.(php)$” 所匹配色解。因此這個請求將被交給后者處理。該請求被轉發(fā)給一個 FastCGI 服務器餐茵,該服務器監(jiān)聽于: localhost:9000科阎。fastcgi_param 指令用于設置 FastCGI 參數(shù) SCRIPT_FILENAME,這里設置為:“/data/www/index.php”忿族,之后 FastCGI 服務器會執(zhí)行該文件锣笨。$document_root 變量的值等同于 root 指令的參數(shù)值,$fastcgi_script_name 變量的值等于請求 URI道批,即 “/index.php”错英。訪問請求為 “/about.html”
對于 “/about.html” 的請求只能被 prefix location “/” 所匹配。因此該 location 會處理這個 請求隆豹。使用 “root /data/www” 指令椭岩,這個請求被映射到 /data/www/about.html 文件,該文件將被發(fā)送給客戶端璃赡。訪問請求為 “/”
對于 “/” 的訪問請求的處理更為復雜判哥。它只能被 prefix location “/” 所匹配,因此該 location 會處理這個請求碉考。然后 index 指令根據(jù)自己的參數(shù)以及 “root /data/www” 指令塌计,開始測試是否存在 index 文件。如果 /data/www/index.html 文件不存在侯谁,而 /data/www/index.php 文件存在锌仅,index 指令會將請求通過內部重定向,重定向至 “/index.php”良蒸,然后 nginx 如同接收到客戶端發(fā)來對 “/index.php” 的請求開始進行處理技扼。這個處理過程剛才已經講解過,被重定向的請求最后會被轉發(fā)給 FastCGI 服務器進行處理嫩痰。
版權信息:
本文編譯自 nginx.org 的部分剿吻,遵循其原來的 licence 聲明: 2-clause BSD-like license