<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 深入研究虛擬主機的匹配 虛擬主機部分的代碼在**Apache 1.3**中進行了完全的重寫。本文檔試圖詳細解釋Apache在接受到請求后如何確定使用哪一個虛擬主機進行伺服。在新的`NameVirtualHost`指令的幫助下,虛擬主機的配置比1.3版以前更加簡單和安全。 如果您只是想&lt;cite class="calibre27"&gt;讓它能夠工作&lt;/cite&gt;而不愿意進行深入理解,這里有[一些示例](#calibre_link-38)。 ## 解析配置文件 在`<VirtualHost>`配置段外有一個_主服務器(main_server)_段中包含著所有定義。其中有`<VirtualHost>`配置段中定義的叫做_虛擬主機(vhost)_的虛擬服務器。 `Listen`, `ServerName`, `ServerPath`, `ServerAlias`指令可以出現在一個服務器定義段的任何地方。而且每個指令都會覆蓋前面出現的同樣定義(在那個服務器配置中)。 主服務器段中`Listen`指令的默認值是80。主服務器段沒有默認的`ServerPath`和`ServerAlias`指令值。`ServerName`的默認值是由服務器的IP地址推斷而來。 主服務器的`Listen`指令有兩個功能:其一是決定Apache將要綁定的網絡端口;其二是在重定向中指定絕對URI將使用的端口號。 不象在主服務器里,虛擬服務器的端口_不會_影響到Apache的監聽端口。 每個`VirtualHost`指令中的地址都可以附帶一個可選的端口。如果沒有進行特別的指定,這個端口默認為主服務器中最近的一個`Listen`指令指定的值。特殊的端口"`*`"表示匹配所有端口。所有這一系列地址(包括由DNS查詢出的所有`A`記錄)統稱虛擬主機的_地址集(address set)_。 如果沒有對一個特定的IP地址使用`NameVirtualHost`指令,那么第一個使用這個地址的虛擬主機將被視為基于IP的虛擬主機。IP地址也可以用通配符"`*`"表示。 如果使用了基于域名的虛擬主機,那么_必須_用`NameVirtualHost`指令為這個基于域名的虛擬主機指定IP地址集。換句話說,您必須在配置文件中通過`NameVirtualHost`指令指定包括主機名映射(CNAME)的IP地址。 可以使用很多`NameVirtualHost`指令來分別對應一套`NameVirtualHost`指令,但對于每個特定的"IP:port"對來說,只能使用一次`NameVirtualHost`指令。 `NameVirtualHost`和`VirtualHost`指令出現的順序并不重要。只有對應_同一個_IP地址的`VirtualHost`指令的次序才是重要的。所以下面兩例所起的作用是完全相同的: ``` NameVirtualHost 111.22.33.44 &lt;VirtualHost 111.22.33.44&gt; # server A ... &lt;/VirtualHost&gt; &lt;VirtualHost 111.22.33.44&gt; # server B ... &lt;/VirtualHost&gt; NameVirtualHost 111.22.33.55 &lt;VirtualHost 111.22.33.55&gt; # server C ... &lt;/VirtualHost&gt; &lt;VirtualHost 111.22.33.55&gt; # server D ... &lt;/VirtualHost&gt; ``` ``` &lt;VirtualHost 111.22.33.44&gt; # server A &lt;/VirtualHost&gt; &lt;VirtualHost 111.22.33.55&gt; # server C ... &lt;/VirtualHost&gt; &lt;VirtualHost 111.22.33.44&gt; # server B ... &lt;/VirtualHost&gt; &lt;VirtualHost 111.22.33.55&gt; # server D ... &lt;/VirtualHost&gt; NameVirtualHost 111.22.33.44 NameVirtualHost 111.22.33.55 ``` (為了使您的配置文件更具可讀性,我們推薦您使用左邊的格式) 在解析完`VirtualHost`指令后,虛擬主機服務器將被賦予在它的`VirtualHost`指令中第一個名字對應的端口作為默認的`Listen`端口。 如果所有域名都指向同一個地址集的話,`VirtualHost`指令中的所有域名列表都將會得到和`ServerAlias`指令一樣的處理(但不會被其他`ServerAlias`語句覆蓋)。請注意,這個虛擬主機自帶的`Listen`指令將不能影響到那個地址集的端口號。 在初始化的過程中,將會為每一個IP地址產生一個列表,并插入到一個散列表中。如果這個IP地址是用在一個`NameVirtualHost`指令中的,這個列表將會包含所有指定為這個IP地址的基于域名的虛擬主機。如果沒有虛擬主機針對這個IP地址,那么`NameVirtualHost`指令將被忽略,并會在日志中記錄一個錯誤信息。對于基于IP的虛擬主機而言,這個散列表中的列表為空。 因為使用了高效的散列算法,使得在請求到達的時候在其中查找IP地址的開銷變得很小,或者根本不需考慮。而且這個表格還為只有最后一個八進制位不同的IP地址做了優化。 虛擬主機的每個變量都有初始值。特別是以下這些: 1. 如果虛擬主機沒有`ServerAdmin`, `ResourceConfig`, `AccessConfig`, `Timeout`, `KeepAliveTimeout`, `KeepAlive`, `MaxKeepAliveRequests`, `ReceiveBufferSize`, `SendBufferSize`指令,那么將從主服務器繼承它們的值。(也就是說,使用在主服務器中最后出現的設定值)。 2. 虛擬主機的默認目錄權限將繼承主服務器的設置(包括所有模塊針對每個目錄的配置信息)。 3. 虛擬主機將繼承主服務器中每個模塊針對主服務器的設置。 本質上,主服務器在建立每個虛擬主機的時候,充當了一個默認值或根基的角色。但這些存在于主服務器中的定義的位置是無關緊要的——主服務器的配置在與虛擬主機整合之前就已經解析過了。所以即使一個主服務器的配置出現在虛擬主機定義的后面,它也同樣會影響到虛擬主機的配置。 如果沒有定義主服務器中的`ServerName` ,那么將由運行這個`httpd`服務的機器的主機名來代替。我們將由DNS查找此`ServerName`返回的IP地址稱為_主服務器地址集(main_server address set)_。 在沒有定義`ServerName`的情況下,一個基于域名的虛擬主機默認采用定義虛擬主機時在`VirtualHost`指令中最先出現的地址。 所有使用了"`_default_`"通配符的虛擬主機將被賦予和主服務器相同的`ServerName` 。 ## 虛擬主機匹配 服務器用下述方法來確定對一個特定的請求使用哪個虛擬主機: ### 散列表查找 當客戶端第一次連接的時候,會從內部的IP散列表中查找客戶端想要連接的IP地址。 如果查找失敗(沒有找到相應的IP地址),而所請求的端口又存在一個"`_default_`"虛擬主機,那么這個請求將會由這個虛擬主機來伺服。如果沒有找到這樣的"`_default_`"虛擬主機,那么這個請求將會由主服務器來伺服。 如果在散列表中沒有找到IP地址,但存在一個"`NameVirtualHost *`"指令與所請求的端口號相匹配,那么將用這個虛擬主機來處理這個請求。 如果查找成功(找到了對應于這個IP地址的列表),下一步就是看我們要處理的是一個基于IP的虛擬主機還是一個基于域名的虛擬主機。 ### 基于IP的虛擬主機 如果返回的列表中域名列表為空,那么我們處理的就是一個基于IP的虛擬主機,這個虛擬主機將會直接進行處理而不會有其他步驟。 ### 基于域名的虛擬主機 如果返回的域名列表包含一個或多個虛擬主機的結構,那么我們處理的就是一個基于域名的虛擬主機。這個列表包含的虛擬主機的順序與配置文件中相應`VirtualHost`指令出現的順序是相同的。 這個列表中第一個虛擬主機(也就是在配置文件中第一個指定了這個IP地址的虛擬主機)對處理請求有著最高的優先級。所有對未知服務器名或沒有"`Host:`"頭的請求都將由它進行處理。 如果客戶端在請求中提供了一個"`Host:`"頭,那么將在列表中查找第一個`ServerName`或`ServerAlias`與其符合的虛擬主機,并將其用于伺服這個請求。盡管"`Host:`"頭中可以包含端口號,但Apache還是會用收到請求的那個真實端口來進行匹配。 如果客戶端提交了一個不包含"`Host:`"頭的HTTP/1.0的請求,我們將無法確認客戶端想要連接那個服務器。而如果存在一個`ServerPath`與客戶端提交的請求中的URI相對應,那么列表中第一個符合條件的虛擬主機將用于伺服這個請求。 如果還是找不到對應的虛擬主機,那么這個請求將會由客戶端連接的IP對應的列表中的第一個與請求的端口相同的虛擬主機來伺服(如前所述)。 ### 持久連接 上述IP查找對一個特定的TCP/IP進程只執行_一次_。但在持久連接(KeepAlive)中,_每個_請求都會進行一次這樣的查找過程。換句話說,一個客戶端在一個持久連接中可以向位于不同的基于域名的虛擬主機的頁面提出請求。 ### 絕對URI 如果請求提交的URI是一個絕對URI,而其中的主機名和端口號又和主服務器或某個虛擬主機相符合,_并且_也與作為此請求提交對象的地址和端口相符,那么這個請求的類型/主機名/端口前綴將被抹除,僅留下相對URI為對應的主服務器或虛擬主機所伺服。如果不滿足上述符合條件,這個URI將保留原樣,而此請求將被作為一個代理請求處理。 ### 備忘錄 * 基于域名的虛擬主機和基于IP的虛擬主機之間互相不干擾。基于IP的虛擬主機只接受發送到它自身地址集的請求,而不接受其他IP地址。基于域名的虛擬主機也是一樣,它們只接受`NameVirtualHost`指令定義的地址集的訪問。 * 永遠不會對一個基于IP的虛擬主機執行`ServerAlias`和`ServerPath`檢查。 * 在配置文件中,基于域名的虛擬主機、基于IP的虛擬主機、"`_default_`"虛擬主機和`NameVirtualHost`指令出現的順序并不重要。而對于某個指定的地址集來說,基于域名的虛擬主機的順序是不能混淆的:在配置文件中較先出現的虛擬主機在相應的地址集中有較高的優先權。 * 出于安全性的考慮,在"`Host:`"頭中出現的端口號將不用于匹配。Apache會一直使用客戶端所連接的真實端口作為匹配。 * 如果一個`ServerPath`指令湊巧是后面出現的另外一個`ServerPath`指令的前綴,前者將用于匹配,而后者將被忽略。(這里討論的是沒有"`Host:`"頭來將這兩個情況分開的情況下) * 如果有兩個基于IP的虛擬主機使用了同一個地址,則在配置文件中首先出現的那個用于匹配。這種事情可能發生在你疏忽的時候。當服務器遇到這種情況的時候,會在日志文件中寫入一個錯誤信息。 * 僅當沒有其他虛擬主機符合客戶端請求的IP地址和端口號時,"`_default_`"虛擬主機才會捕獲這個請求。_并且_僅當"`_default_`"虛擬主機的端口號(默認值由您的`Listen`指定)與客戶端發送請求的目的端口號相符時,這個請求才會被捕獲。也可以使用通配符(例如:"`_default_:*`")來捕獲任何端口號的請求。這也同樣適用于"`NameVirtualHost *`"的虛擬主機。 * 僅當客戶端連接的目的IP地址和端口號沒有指定而且不與任何一個虛擬主機(包括"`_default_`"虛擬主機)匹配的時候,才會用主服務器來伺服請求。換句話說,主服務器僅捕獲沒有指定IP地址和端口的請求(除非存在一個匹配端口的"`_default_`"虛擬主機)。 * 如果客戶端連接到一個用于基于域名的虛擬主機使用的地址(和端口),比如說使用了`NameVirtualHost`指令,那么一個未知的或沒有"`Host:`"頭的請求就_不會_與"`_default_`"虛擬主機或是主服務器相匹配。 * 絕對不能在`VirtualHost`指令中使用DNS名稱,否則您的服務器就會依賴DNS來進行啟動。而且,如果您無法控制列表中所有的域,您將會面臨安全威脅。您可以在這里獲得關于這個問題和以下兩個問題的[更多詳情](#calibre_link-55)。 * 應當為每個虛擬主機設定`ServerName` 。否則就會需要為每個虛擬主機進行DNS查詢。 ## 小技巧 作為[DNS問題](#calibre_link-56)頁面小技巧的附加,這里有些額外的技巧: * 將所有主服務器的定義放在所有`VirtualHost`定義之前(為了增加可讀性),否則會使得類似在虛擬主機旁邊的定義影響到所有的虛擬主機這樣的問題不容易發現。 * 將您配置中相應的`NameVirtualHost`和`VirtualHost`定義放到一起,以獲得更好的可讀性。 * 避免前一個`ServerPaths`是后一個`ServerPaths`的前綴。如果您無法避免這樣的情況,您最好確保在您的配置文件中"長在前,短在后"(也就是說:"ServerPath/abc/def"應當出現在"ServerPath/abc"之前)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看