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]"
/>
<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 處理執行。偽代碼如下:
{
// 檢查當前調用者有沒有作為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函數完成實際頁面請求工作,偽代碼如下:
{
HttpRuntime._theRuntime.ProcessRequestInternal(wr);
}
ProcessRequestInternal函數邏輯稍微復雜一些,大致可分為四個部分:
檢查當前HttpRuntime實例是否第一次被調用,如果是第一次調用則通過FirstRequestInit函數初始化
調用HttpResponse.InitResponseWriter函數初始化頁面請求的返回對象HttpWorkerRequest.Response
調用HttpApplicationFactory.GetApplicationInstance函數獲取當前 Web 應用程序實例
使用Web應用程序實例完成實際的頁面請求工作
偽代碼如下:

private void HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
{
// 構造 HTTP 調用上下文對象
HttpContext ctxt = new HttpContext(wr, 0);
// 設置發送結束異步回調函數
wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, ctxt);
// 更新請求計數器
Interlocked.Increment(&(this._activeRequestCount));
try
{
// 檢查當前HttpRuntime實例是否第一次被調用
if(this._beforeFirstRequest)
{
lock(this)
{
// 使用 Double-Checked 模式 避免冗余鎖定
if(this._beforeFirstRequest)
{
this._firstRequestStartTime = DateTime.UtcNow;
this.FirstRequestInit(ctxt); // 初始化當前 HttpRuntime 運行時環境
this._beforeFirstRequest = false;
}
}
}
// 根據配置文件設置,扮演具有較高特權的角色
ctxt.Impersonation.Start(true, false);
try
{
// 初始化頁面請求的返回對象
ctxt.Response.InitResponseWriter();
}
finally
{
ctxt.Impersonation.Stop();
}
// 獲取當前 Web 應用程序實例
IHttpHandler handler = HttpApplicationFactory.GetApplicationInstance(ctxt);
if (handler == null)
{
throw new HttpException(HttpRuntime.FormatResourceString("Unable_create_app_object"));
}
// 使用Web應用程序實例完成實際的頁面請求工作
if((handler as IHttpAsyncHandler) != null)
{
IHttpAsyncHandler asyncHandler = ((IHttpAsyncHandler) handler);
ctxt.AsyncAppHandler = asyncHandler;
// 使用異步處理機制
asyncHandler.BeginProcessRequest(ctxt, this._handlerCompletionCallback, ctxt);
}
else
{
handler.ProcessRequest(ctxt);
this.FinishRequest(ctxt.WorkerRequest, ctxt, null);
}
}
catch(Exception E)
{
ctxt.Response.InitResponseWriter();
this.FinishRequest(wr, ctxt, E);
}
}
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類里面包含的方法,從其元數據里面可以看到,如下:
