HttpRuntime的認識與加深理解

作者: FengLang  來源: 博客園  發布時間: 2009-10-21 10:21  閱讀: 1906 次  推薦: 0   原文鏈接   [收藏]  

下面最先介紹HttpRuntime的Web.config里的配置

<httpRuntime
   executionTimeout 
= "number" 
   maxRequestLength 
= "number" 
   requestLengthDiskThreshold 
= "number" 
   useFullyQualifiedRedirectUrl 
= "[True|False]" 
   minFreeThreads 
= "number" 
   minLocalRequestFreeThreads 
= "number" 
   appRequestQueueLimit 
= "number"
   enableKernelOutputCache = "[True|False]" 
   enableVersionHeader 
= "[True|False]" 
   apartmentThreading 
= "[True|False]"
   requireRootedSaveAsPath = "[True|False]"
   enable = "[True|False]" 
   sendCacheControlHeader 
= "[True|False]" 
   shutdownTimeout 
= "number"
   delayNotificationTimeout = "number"
   waitChangeNotification = "number" 
   maxWaitChangeNotification 
= "number" 
   enableHeaderChecking 
= "[True|False]" 
/>

通過上面的配置說明, 下面是在Web.Config里節點的設置

<configuration>
  <system.web>
  <httpRuntime maxRequestLength="4000"
    enable = "True"
    requestLengthDiskThreshold="512
    useFullyQualifiedRedirectUrl="True"
    executionTimeout="45"
    versionHeader="1.1.4128"/>
  system.web>
configuration>

IIS 所收到的對某 Microsoft ASP.NET 頁面的每個請求都被移交給 ASP.NET HTTP 管線。HTTP 管線由一系列托管對象組成,這些對象按順序處理該請求,并完成從 URL 到普通 HTML 文本的轉換。HTTP 管線的入口點是 HttpRuntime 類。ASP.NET 基礎結構為輔助進程中所承載的每個 AppDomain 創建此類的一個實例請注意,該輔助進程為當前正在運行的每個 ASP.NET 應用程序維護一個不同的 AppDomain。

要激活 HTTP 管道,可以創建一個 HttpRuntime 類的新實例,然后調用其 ProcessRequest 方法。一個完整的頁面請求會包括下面的流程:
首先被WWW服務器截獲(inetinfo.exe進程), 該進程首先判斷頁面后綴, 然后根據IIS中配置決定調用具體的擴展程序。aspx就會調用aspnet_isapi.dll,
然后由aspnet_isapi.dll發送給w3wp.exe(iis 工作者進程,IIS6.0中叫做 w3wq.exe,IIS5.0中叫做 aspnet_wp.exe)。

接下來在w3wp.exe調用.NET類庫進行具體處理,順序如下:ISAPIRuntim, HttpRuntime, HttpApplicationFactory, HttpApplication, HttpModule, HttpHandlerFactory, HttpHandler

ISAPIRuntime:主要作用是調用一些非托管代碼生成HttpWorkerRequest對象,HttpWorkerRequest對象包含當前請求的所有信息,然后傳遞給HttpRuntime
HttpRuntime:根據HttpWorkerRequest對象生成HttpContext,HttpContext包含request、response等屬性, 再調用HttpApplicationFactory來生成IHttpHandler, 調用HttpApplication對象執行請求
HttpApplicationFactory: 生成一個HttpApplication對象
HttpApplication:進行HttpModule的初始化,HttpApplication創建針對此Http請求的 HttpContext對象
HttpModule: 當一個HTTP請求到達HttpModule時,整個ASP.NET Framework系統還并沒有對這個HTTP請求做任何處理,也就是說此時對于HTTP請求來講,HttpModule是一個HTTP請求的“必經之路”,所以可以在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)之前附加一些需要的信息在這個HTTP請求信息之上,或者針對截獲的這個HTTP請求信息作一些額外的工作,或者在某些情況下干脆終止滿足一些條件的HTTP請求,從而可以起到一個Filter過濾器的作用。
HttpHandlerFactory:把用戶request 轉發到HttpHandlerFactory,再由HttpHandlerFactory實例化HttpHandler對象來相應request
HttpHandle:Http處理程序,處理頁面請求

從上面看出HttpRuntime其中有一個ProcessRequest 方法
public static void ProcessRequest(HttpWorkerRequest wr);  //驅動所有 ASP.NET Web 處理執行。偽代碼如下:

public static void HttpRuntime.ProcessRequest(HttpWorkerRequest wr)
 {
   
// 檢查當前調用者有沒有作為ASP.NET宿主(Host)的權限
   InternalSecurityPermissions.AspNetHostingPermissionLevelMedium.Demand(); 

   
if(wr == null)
   {
     
throw new ArgumentNullException("custom");
   }

   RequestQueue queue 
= HttpRuntime._theRuntime._requestQueue;

   
if(queue != null)
   {
     
// 將參數中的Web頁面請求放入請求隊列中, 并從隊列中使用FIFO策略獲取一個頁面請求
     wr = queue.GetRequestToExecute(wr);
   }

   
if(wr != null)
   {     
     HttpRuntime.CalculateWaitTimeAndUpdatePerfCounter(wr); 
// 更新性能計數器     
      HttpRuntime.ProcessRequestNow(wr); // 實際完成頁面請求工作
   }
 }

ProcessRequestNow函數則直接調用缺省HttpRuntime實例的ProcessRequestInternal函數完成實際頁面請求工作,偽代碼如下:

internal static void HttpRuntime.ProcessRequestNow(HttpWorkerRequest wr)
{
   HttpRuntime._theRuntime.ProcessRequestInternal(wr);
}

ProcessRequestInternal函數邏輯稍微復雜一些,大致可分為四個部分:
檢查當前HttpRuntime實例是否第一次被調用,如果是第一次調用則通過FirstRequestInit函數初始化
調用HttpResponse.InitResponseWriter函數初始化頁面請求的返回對象HttpWorkerRequest.Response
調用HttpApplicationFactory.GetApplicationInstance函數獲取當前 Web 應用程序實例
使用Web應用程序實例完成實際的頁面請求工作
偽代碼如下:

Code

HttpRuntime.ProcessRequestInternal函數中調用了HttpApplicationFactory.GetApplicationInstance函數獲取當前 Web 應用程序實例。至少HttpRuntime已經完完成,將轉進HttpApplicationFactory階段流程。大家可以看到,圍繞HttpRuntime的函數都有一個HttpWorkerRequest參數,下面簡單介紹一下這個參數的作用。在ISAPIRuntime階段,調用一些非托管代碼生成HttpWorkerRequest對象,該對象包含當前請求的所有信息,然后傳遞給HttpRuntime,這里生成的HttpWorkerRequest對象可以直接在我們的頁面里調用.
IServiceProvider provider=(IServiceProvider)HttpContext.Current;
HttpWorkerRequest wr=(HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
然后可以通過wr來調用里面的方法。關于HttpWorkerRequest類里面包含的方法,從其元數據里面可以看到,如下:

Code

 

0
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()