Apache HTTP Server 版本 2.4
可使用語言: en
警告 - 這是需要進一步修改的第一份(快取)草稿!
2.0 及以上的數項變更影響內部請求的處理機制。模組作者需要瞭解這些變更,才能善用這些最佳化和安全性強化功能。
第一項主要變更適用於子請求和重新導向機制。Apache HTTP Server 1.3 中有許多不同的程式碼路徑,用於嘗試最佳化子請求或重新導向行為。當修補程式導入到 2.0 時,這些最佳化(以及伺服器行為)會因為這些重複程式碼而快速中斷。所有重複程式碼已摺疊回到 ap_process_request_internal()
中,以防止程式碼再次不同步。
這表示現有程式碼的許多部分已「非最佳化」。Apache HTTP 計畫的第一個目標,是建立 HTTP 伺服器 RFC 的健全且正確的實作。其他目標包括安全性、可擴充性和最佳化。新的方法用於在不引入脆弱或不安全的程式碼的情況下,最佳化伺服器(超越 1.3 的效能)。
在 server/request.c
中,包括子請求和重新導向在內的所有請求都會通過 ap_process_request_internal()
。如果模組沒有透過此程式碼傳遞產生請求,則建議作者要為未來請求處理的變更做好準備。
為了簡化請求,模組作者可以使用 提供的掛勾,即時中斷請求週期,或繞過無關(而且會耗費 CPU 成本)的核心掛勾。
在內部請求處理的開始處,請求的 parsed_uri
路徑會取消一次且僅取消一次的跳脫字元。
如果設定 proxyreq 標誌,則略過此步驟,或未設定 parsed_uri.path
元素。模組無法進一步控制此一次性解除跳脫運算,進行解除跳脫失敗或將 URL 多次解除跳脫都會導致安全後果。
ap_getparents()
會移除所有 /../
和 /./
元素,以及任何尾隨 /.
或 /..
元素。這有助於確保在請求處理繼續之前,路徑(幾乎)是絕對路徑。(請參閱 RFC 1808 第 4 章了解進一步說明。)
此步驟無法略過。
每個請求都會呼叫 ap_location_walk()
。這可確保對所有請求一致執行 <Location>
區段。如果請求是內部重新導向或子請求,它可以借用先前或父請求的 ap_location_walk 的部分或全部處理作業,因此在處理主要請求後,此步驟通常會非常有效率。
模組可以在此步驟中判斷檔案名稱,或變更指定的 URI。例如,mod_vhost_alias
會將 URI 的路徑轉譯成已設定的虛擬主機,mod_alias
會將路徑轉譯成別名路徑,如果請求返回至核心,DocumentRoot
會預先加到請求資源中。
如果所有模組都拒絕此階段,則會傳回錯誤 500 給瀏覽器,並自動記錄「無法轉譯名稱」錯誤。
在判斷出檔案或正確 URI 之後,會將適當的每目錄設定合併在一起。例如,mod_proxy
會比較並合併適當的 <Proxy>
區段。如果 URI 僅為本機(非代理伺服器的)TRACE
請求,核心會處理請求並傳回 DONE
。如果沒有模組以 OK
或 DONE
回答此鉤子,核心會對照 <Directory>
和 <Files>
區段執行請求檔名。如果請求「檔名」不是絕對的合法檔名,會設定一個註記以供稍後終止。
每個請求都會透過第二次 ap_location_walk()
呼叫而加固。這可確保已傳譯請求仍然會遵循已設定的 <Location>
區段。請求再次從其先前的 location_walk
中借用部分或全部處理作業,因此此步驟幾乎總是會很有效率,除非已傳譯 URI 已對應到顯著不同的路徑或虛擬主機。
然後,主請求會分析客戶端的標頭。這會準備後續請求處理步驟以更好地服務於客戶端的請求。
需要文件記錄。代碼是
if ((access_status = ap_run_access_checker(r)) != 0) { return decl_die(access_status, "check access", r); } if ((access_status = ap_run_check_user_id(r)) != 0) { return decl_die(access_status, "check user", r); } if ((access_status = ap_run_auth_checker(r)) != 0) { return decl_die(access_status, "check authorization", r); }
這些模組有機會測試 URI 或檔名以針對目標資源,並設定請求的 Mime 資訊。mod_mime
和 mod_mime_magic
都會使用此階段將檔名或內容與管理員的設定進行比較並設定內容類型、語言、字元集和要求處理常式。某些模組可能會在此時設定它們的篩選器或其他要求處理參數。
如果所有模組都對這個階段進行 DECLINE
,錯誤 500 會傳回給瀏覽器,且「找不到類型」錯誤會自動記錄下來。
許多模組會在上述某些階段被「踐踏」。模組會使用修復階段來「重新宣示」它們的所有權或強制請求欄位使用適當的值。這並不總是最乾淨的機制,但有時它是唯一的選項。
這個階段並非 ap_process_request_internal()
中處理的一部分。許多模組會在建立任何內容之前準備一個或多個子請求。核心或模組呼叫 ap_process_request_internal()
之後,它會呼叫 ap_invoke_handler()
以產生請求。
以某種方式轉換內容的模組可以插入其值並覆寫現有的篩選器,以便如果使用者設定了一個更高級的失序篩選器,則該模組可以視需要變更其順序。這裡沒有結果代碼,因此最好信任掛鉤中的動作能永遠成功。
該模組終於可以在它的處理常式掛鉤中服務請求了。請注意,並非每個已準備好的請求都會傳送到處理常式掛鉤。許多模組,例如 mod_autoindex
,會為給定的 URI 建立子請求,然後永遠不會為子請求服務,但只會為使用者列出該請求。請記住,不要將上方的掛鉤中需要的卸載放入這個模組,而是針對請求池註冊池清理以根據需要釋放資源。
可使用語言: en