.NET處理HTTP請求

ForTechnology發表於2011-08-17

.NET處理HTTP請求

20110209 星期三 下午 05:05

轉載自 27115

最終編輯 27115

.NET平臺處理HTTP請求的過程大致如下:

1 IIS得到一個請求;

2查詢指令碼對映擴充套件,然後把請求對映到aspnet_isapi.dll檔案

3程式碼進入工作者程式(IIS5裡是aspnet_wp.exeIIS6裡是w3wp.exe),工作者程式也叫輔助程式;

4.NET執行時被載入;

5非託管程式碼呼叫IsapiRuntime.ProcessRequest()方法;

6每一個請求呼叫一個IsapiWorkerRequest

7使用WorkerRequest呼叫HttpRuntime.ProcessRequest()方法;

8通過傳遞進來的WorkerRequest建立一個HttpContext物件

9通過把上下文物件作為引數傳遞給HttpApplication.GetApplicationInstance(),然後呼叫該方法,從應用程式池中獲取一個HttpApplication例項;

10呼叫HttpApplication.Init(),啟動管道事件序列,鉤住模組和處理器;

11呼叫HttpApplicaton.ProcessRequest,開始處理請求;

12觸發管道事件;

13呼叫HTTP處理器和ProcessRequest方法;

14把返回的資料輸出到管道,觸發處理請求後的事件。

當客戶端向Web伺服器請求一個頁面檔案時,這個HTTP請求會被inetinfo.exe程式截 獲(WWW服務),它判斷檔案字尾,如果是*.aspx*.asmx等,就把這個請求轉交給aspnet_isapi.dll,而 aspnet_isapi.dll則會通過一個Http PipeLine的管道,將這個HTTP請求傳送給w3wq.exe程式,當這個HTTP請求進入w3wq.exe程式之後,Asp.Net framework就會通過HttpRuntime來處理這個HTTP請求,處理完畢後將結果返回給客戶端。

當一個HTTP請求被送入到HttpRuntime之後,這個HTTP請求通過HTTP管道 (HttpRuntimeHTTP管道的入口)被送入到一個被稱之為HttpApplication Factory的一個容器當中,而這個容器會給出一個HttpApplication例項來處理傳遞進來的HTTP請求,同時 HttpApplication例項會建立一個HttpContext物件來記錄HTTP請求的上下文,而後這個HTTP請求會依次進入到如下幾個容器 中:
HttpModule --&gt HttpHandler Factory --&gt HttpHandler
當系統內部的HttpHandlerProcessRequest方法處理完畢之後,整個Http Request就被處理完成了。

如果想在中途截獲一個httpRequest並做些自己的處理,就應該在HttpRuntime執行時內部來做到這一點,確切的說時在HttpModule這個容器中做到這個的。

過程詳解:

從本質上講,Asp.Net主要是由一系列的類組成,這些類的主要目的就是將Http請求轉變為對 客戶端的響應。HttpRuntime類是Asp.Net的一個主要入口,它有一個ProcessRequest方法,這個方法以一個 HttpWorkerRequest 類作為引數。HttpRuntime類幾乎包含著關於單個Http請求的所有資訊:所請求的檔案、伺服器端變數、QueryStringHttp頭資訊 等等。Asp.Net 使用這些資訊來載入、執行正確的檔案,並且將這個請求轉換到輸出流中,一般來說,就是HTML頁面(二般來說,也可以是張圖片)

對於IIS來說,它依賴於一個叫做HTTP.SYS的內建驅動程式來監聽來自外部的HTTP請求。 在作業系統啟動的時候,IIS首先在HTTP.SYS中註冊自己的虛擬路徑(實際上相當於告訴HTTP.SYS哪些URL是可以訪問的,哪些是不可以訪問 的。舉個簡單的例子:為什麼你訪問不存在的檔案會出現404 錯誤呢?就是在這一步確定的)

伺服器處理一個.htm頁面和一個.aspx頁面肯定是不一樣的,那IIS依據什麼去處理呢?―― 根據檔案的字尾名。能夠處理各種字尾名的應用程式,通常被稱為 ISAPI 應用程式(Internet Server Application Program Interface網際網路伺服器應用程式介面),它的主要工作是對映所請求的頁面(檔案) 和與此字尾名相對應的實際的處理程式。

所有的.aspx檔案實際上都是由aspnet_isapi.dll這個程式來處理的,當IIS把對於.aspx頁面的請求提交給了aspnet_isapi.dll以後,它就不再關心這個請求隨後是如何處理的了。

除了對映檔案與其對應的處理程式以外,ISAPI還需要做一些其他的工作:  1. HTTP.SYS中獲取當前的Http請求資訊,並且將這些資訊儲存到

HttpWorkerRequest 類中。

2. 在相互隔離的應用程式域AppDomain中載入HttpRuntime

3. 呼叫HttpRuntimeProcessRequest方法。

接下來才是程式設計師通常編寫的程式碼所完成的工作了,然後,IIS接收返回的資料流,並重新返還給 HTTP.SYS,最後,HTTP.SYS 再將這些資料返回給客戶端瀏覽器。

名詞解釋:

     IIS: Internet Information Server是一種基於Windows平臺的網頁服務(World Wide Web server)元件,其中包括WWW伺服器、FTP伺服器、NNTP伺服器和SMTP伺服器,分別用於網頁瀏覽、釋出資訊、檔案傳輸、新聞服務和郵件傳送 等方面。

IIS4個核心元件:

HTTP.sys:將 HTTP 請求傳送到使用者模式應用程式的核心模式裝置驅動程式。

WWW服務管理和監視元件:配置全球資訊網釋出服務“(WWW 服務)並管理工作程式。

工作程式:處理提交到分配給它們的 Web 應用程式的請求。

Inetinfo.exe:主控配置資料庫和非 Web 服務。

MSILMicrosoft Intermediate Language,微軟中間語言。MSIL是將.Net程式碼轉化為機器語言的一箇中間過程,它是一種介於高階語言和基於Intel的組合語言的偽彙編語 言。同一段MSIL程式碼可以被不同的編譯器實時編譯並執行在不同的結構上,因此MSIL本身與機器無關,可以在裝有CLR的任一計算機上執行。

CLRCommon Language Runtime,公共語言執行時。簡單的理解,就是一個翻譯,把.NET平臺的各種語言(C#VBJS)翻譯為機器可以執行的語言。.NET編譯器將程式程式碼編譯成MSIL(Microsoft Intermediate Language ,微軟中間語言),然後再由CLR中的JIT(Just In Time,實時)編譯器去編譯成機器語言來執行。CLR在功能上就如同一塊虛擬的CPU,它執行MSIL程式碼、運算元據。CLR和真實的CPU類似之處在 於它們都不直接操作記憶體中的變數而是使用程式變數的臨時拷貝,CLR把這些程式變數存放在堆疊上。從記憶體拷貝某個變數到堆疊的行為稱作裝載 (loading),而從堆疊拷回某個變數到記憶體的行為則被稱作儲存(storing)

HttpRuntime:配置 ASP.NET HTTP 執行時設定,這些設定確定如何處理對 ASP.NET 應用程式的請求,HttpRuntime類幾乎包含了單個HTTP請求的所有資訊,HttpRuntimeHTTP管道的入口。HTTP請求到達 時,ASP.NET 將執行時庫載入到要處理請求的程式中,還為將在 Web 伺服器上執行的每個 Web 應用程式建立一個應用程式域(AppDomain)HttpRuntimeProcessRequest 方法驅動所有後續的 ASP.NET Web 處理。

AppDomainAppDomain物件表示應用程式域,即一個應用程式執行的獨立環境,為執 行託管程式碼提供隔離、解除安裝和安全邊界。它是是微軟基於.NET框架設計的概念,找不到其他技術體系中貼切的參照概念。輔助程式為每個當前正在執行的 ASP.NET應用程式維護一個特定的AppDomain。一個程式中可以有多個AppDomain,但是一個AppDomain只能存在於某個程式中。 執行緒執行可以涉及多個AppDomain,但某個特定時刻執行緒僅存在於一個AppDomain中,且執行緒可以進入其他的AppDomain

哪些情境下要使用AppDomain

1、需要隔離的程式集,譬如一些特別容易引起崩潰的程式碼可以考慮單獨執行於一個特定的AppDomain

2、不同安全級別的程式集,如果需要為自己的程式碼劃分安全執行的邊界,可以考慮將不同安全級別的程式碼單獨建立於某個設定了不同安全資訊的AppDomain

3、從效能上考慮,有些程式集可能會消耗大量資源,儘管在託管環境下,基本上不存在資源消耗漏洞, 但是總會存在特定時間訪問密集造成消耗大量資源的情況,這時可以考慮建立單獨的AppDomain,在資源消耗超過臨界點後進行AppDomain的卸 載,適應系統執行要求。ASP.NET中利用不同得AppDomain來提供支援就是為了防止一個應用程式的崩潰影響其他ASP.NET應用程式,同時, 在不重新啟動的系統不重新啟動IIS不影響ASP.NET自身服務提供的情況下將一個AppDomain卸掉同時啟動新的AppDomain,理想情況下 可以實現web系統的長時間線上(這以往是昂貴的UNIX的特性,終於被MS借鑑了)

4、不同版本的同一應用程式集的同時執行。這個在COM時代是一個大問題,現在通過AppDomain,實現了在一個程式中執行版本不同的兩個程式集,可以做到良好的相容性。

5、動態載入一些程式。

HttpApplication:定義了所有ASP.Net應用程式的通用的方法、屬性和事件。是 你實際可以看到的進入HTTP執行時(HttpRuntime)的第一個登入點,它對應到Global.asax檔案裡定義的基類。 HttpApplication擔當主容器,負責載入Web程式,當請求到來時觸發事件以及在管道之間傳輸請求(事件訊息的郵遞者),然後通過傳遞 HttpContext物件,把事件訊息傳送給呼叫的方法(HttpModuleHttpHandler)。每一個請求都將被路由到一個 HttpApplication物件。HttpApplicationFactory類會為你的ASP.NET程式建立一個 HttpApplication物件池,它負責載入程式和給每一個到來的請求分發HttpApplication的引用。這個 HttpApplication物件池的大小可以通過machine.config裡的ProcessModel節點中的 MaxWorkerThreads選項配置,預設值是20(此處可能有誤,根據Reflector反編譯的程式碼,池的大小應該是100) HttpApplication物件池開始啟動時通常只有一個HttpApplication物件。但是當同時有多個請求需要處理時,池中的物件將會隨之 增加。而HttpApplication物件池,也將會被監控,目的是保持池中物件的數目不超過設定的最大值。當請求的數量減小時,池中的數目就會跌回一個較小的值。HttpApplication物件執行在AppDomain裡。

HttpApplication的主要職責是作為HTTP管道的事件控制器,所以它的介面主要包含的是事件。事件掛接是非常廣泛的,包括以下這些:

l BeginRequest

l AuthenticateRequest

l AuthorizeRequest

l ResolveRequestCache

l AquireRequestState

l PreRequestHandlerExecute

l …Handler Execution…

l PostRequestHandlerExecute

l ReleaseRequestState

l UpdateRequestCache

l EndRequest

     HttpModule:實現了System.Web.IhttpModule介面的.NET元件。

這些元件通過在某些事件中註冊,把自己插入ASP.NET請求處理管道中 (HttpApplication事件鏈)。當這些事件(HttpApplication物件觸發的事件)發生時,HttpModule就會去處理事件 (一般是截獲請求),所以HttpModule本質上就是過濾器(當一個HTTP請求到達HttpModule時,整個ASP.NET Framework並未對這個HTTP請求做過任何處理)HttpModule有訪問HttpContext物件的許可權(但某些物件可能還不能使用), 可以修改請求,輸出響應的內容以及提供自定義的身份驗證,另外還可以在特定的程式裡,針對ASP.NET的每一個請求提供響應前處理和響應後處理。多個 HttpModule可以鉤住相同的事件,事件被處理的順序是它們在web.config裡配置的順序。

ASP.NET系統中預設的HttpModule

DefaultAuthenticationModule:確保上下文中存在Authentication 物件,無法繼承此類。
FileAuthorizationModule:驗證遠端使用者是否具有訪問所請求檔案的 NT 許可權,無法繼承此類。
FormsAuthenticationModule:啟用ASP.NET應用程式以使用Forms身份驗證,無法繼承此類。
PassportAuthenticationModule:提供環繞PassportAuthentication服務的包裝,無法繼承此類。
SessionStateModule:為應用程式提供會話狀態服務。
UrlAuthorizationModule:提供基於 URL 的授權服務以允許或拒絕對指定資源的訪問,無法繼承此類。
WindowsAuthenticationModule:啟用 ASP.NET 應用程式以使用 Windows/IIS 身份驗證,無法繼承此類。

     HttpHandlerHttpHandler(HTTP處理器)HTTP請求的處理中心,它可以完全使用HttpContext物件,真正地對客戶 端請求的頁面進行編譯和執行,並將處理後的資訊附加在HTTP請求資訊流中返回到HttpModule中。HttpHandler通過一個簡單 IHttpHandler介面實現(或者它的非同步版本IHttpAsyncHandler),此介面僅僅只有一個方法ProcessRequest()和一個屬性IsReusable

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25897606/viewspace-705191/,如需轉載,請註明出處,否則將追究法律責任。

相關文章