上圖基本上演示了IIS 6整個處理過程。在User Mode下,http.sys接收到一個基於aspx的http request,而後它會根據IIS中的Metabase查看該基於該Request的Application屬於哪一個Application Pool,若是該Application Pool不存在,則建立之。不然直接將request發到對應Application Pool的Queue中。我上面已經說了,每一個Application Pool對應着一個Worker Process:w3wp.exe,毫無疑問他是運行在User Mode下的。在IIS Metabase中維護着Application Pool和worker process的Mapping。WAS(Web Administrative service)根據這樣一個mapping,將存在於某個Application Pool Queue的request 傳遞到對應的worker process(若是沒有,就建立這樣一個進程)。在worker process初始化的時候,加載ASP.NET ISAPI,ASP.NET ISAPI進而加載CLR。從而爲ASP.NET Application建立一個託管的運行環境,在CLR初始化的使用會加載兩個重要的dll:AppManagerAppDomainFactory和ISAPIRuntime。經過AppManagerAppDomainFactory的Create方法爲Application建立一個Application Domain;經過ISAPIRuntime的ProcessRequest處理Request,進而將流程拖入到ASP.NET Http Runtime Pipeline的範疇,ASP.NET Http Runtime Pipeline對Http Request的處理是一個相對複雜的過程,相關的介紹會放在本篇文章的下一部份。在這裏咱們能夠把它當作是一個黑盒,它接管Request,最終生成Html。html
ISAPIRuntime會首先建立一個ISAPIWorkRequest對象,對請求報文進行了簡單的封裝,並將該ISAPIWorkRequest對象傳遞給HttpRuntime。api
HttpRuntime會根據ISAPIWorkRequest建立用於封裝Http請求上下文的對象HttpConetxt。服務器
HttpContext主要包括HttpRequest(當前請求)和HttpResponse(服務器響應)app
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)] public int ProcessRequest(IntPtr ecb, int iWRType) { IntPtr zero = IntPtr.Zero; if (iWRType == 2) { zero = ecb; ecb = UnsafeNativeMethods.GetEcb(zero); } //建立了ISAPIWorkRquest空對象 ISAPIWorkerRequest wr = null; try { bool useOOP = iWRType == 1; //經過ecb句柄建立了ISAPIWorkRequest對象 wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP); wr.Initialize(); string appPathTranslated = wr.GetAppPathTranslated(); string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal; if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal)) { //IsapiRuntime把WR交給了HttpRuntime HttpRuntime.ProcessRequestNoDemand(wr); return 0; } HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated })); return 1; } catch (Exception exception) { try { WebBaseEvent.RaiseRuntimeError(exception, this); } catch { } if ((wr == null) || !(wr.Ecb == IntPtr.Zero)) { throw; } if (zero != IntPtr.Zero) { UnsafeNativeMethods.SetDoneWithSessionCalled(zero); } if (exception is ThreadAbortException) { Thread.ResetAbort(); } return 0; } } ISAPIRuntime
HttpRuntime經過HttpApplicationFactory獲取一個新的或現有的HttpApplication對象。async
private void ProcessRequestInternal(HttpWorkerRequest wr) { Interlocked.Increment(ref this._activeRequestCount); if (this._disposingHttpRuntime) { try { wr.SendStatus(0x1f7, "Server Too Busy"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>"); wr.SendResponseFromMemory(bytes, bytes.Length); wr.FlushResponse(true); wr.EndOfRequest(); } finally { Interlocked.Decrement(ref this._activeRequestCount); } } else { HttpContext context; try { //經過wr建立了上下文對象 context = new HttpContext(wr, false); } catch { try { wr.SendStatus(400, "Bad Request"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] data = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>"); wr.SendResponseFromMemory(data, data.Length); wr.FlushResponse(true); wr.EndOfRequest(); return; } finally { Interlocked.Decrement(ref this._activeRequestCount); } } wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context); HostingEnvironment.IncrementBusyCount(); try { try { this.EnsureFirstRequestInit(context); } catch { if (!context.Request.IsDebuggingRequest) { throw; } } context.Response.InitResponseWriter(); //經過HttpApplicationFactory獲取HttpApplication實例 IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); if (applicationInstance == null) { throw new HttpException(SR.GetString("Unable_create_app_object")); } if (EtwTrace.IsTraceEnabled(5, 1)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start"); } if (applicationInstance is IHttpAsyncHandler) { IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance; context.AsyncAppHandler = handler2; //執行HttpApplication的BeginProcessRequest方法 handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context); } else { applicationInstance.ProcessRequest(context); this.FinishRequest(context.WorkerRequest, context, null); } } catch (Exception exception) { context.Response.InitResponseWriter(); this.FinishRequest(wr, context, exception); } } } HttpRuntime