日期:2014-05-16 浏览次数:20903 次
上节中我们从Http请求在Asp.net中的运行过程进行了分析,但是对于真正核心的东西我们并没有说明,那接下来我们将问题上抛,从底层类和对象的创建层面上来看Asp.net的运行机制。
HTTP.SYS:运行于Windows核心(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求(通常来自网络中另一台计算机上的浏览器),根据请求的URL将其转发给相应的应用程序池 (Application Pool)。当此HTTP请求处理完成时,它又负责将处理结果发送出去(其接收者通常为发出HTTP请求的浏览器)。为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来。
通俗点说,HTTP.SYS 判断了哪些 URL 是可以访问的, 哪些是不可以访问的。 举个简单的例子,为什么你访问不存在的文件会出现 404 错误呢,就是在这一步确定的。如果请求的是一个可访问的 URL,HTTP.SYS会将这个请求交给 IIS 工作者进程。
首先来看张图,我们可以把HTTP请求画在一张图上来看。
HTTP请求进入Web服务器后,首先由HTTP.SYS来判断请求的页面是否存在,如果存在的话将把请求信息转交给.NET Runtime。在这部分实际是完成两个步骤,在将请求转交给.NET Runtime的同时将请求信息封存在HTTPWorkRequest类中供其它步骤调用。
Note:HttpWorkRequest类在以后的操作中至关重要,它第一次将Http请求信息转换为类信息。
当请求到达.NET Runtime后,接下来的操作将会在托管环境中完成,这时请求就真正进入了.NET中,对请求信息的操作是由.NET的底层类库来实现。首先.NET Runtime将会针对请求信息做两个动作,一是准备HostingEnvironment;二是调用ApplicationManager类为HTTP请求动态的分配AppDomain,并把处理权交给AppDomain。
HTTP请求进入AppDomain后,将由对象ISAPIRuntime来接管,一方面经方法ProcessRequest()得到HttpWorkerRequest对象,另一方面由方法StartProcessing()生成HttpRuntime对象,接下来把处理权交给了HttpRuntime(HttpWorkerRequest对象将作为HttpRuntime方法中的参数被使用)。
HTTPRuntime接收到Http请求后,方法ProcessRequest处理请求。还记得步骤1中的HTTPWorkRequest类吗,此时将会针对该类中的信息进行操作,具体的实现由ProcessRequest方法实现。内部代码如下:
[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)] public static void ProcessRequest(HttpWorkerRequest wr) { if (wr == null) { throw new ArgumentNullException("wr"); } if (UseIntegratedPipeline) { throw new PlatformNotSupportedException(System.Web.SR.GetString("Method_Not_Supported_By_Iis_Integrated_Mode", new object[] { "HttpRuntime.ProcessRequest" })); } ProcessRequestNoDemand(wr); } internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) { RequestQueue queue = _theRuntime._requestQueue; if (queue != null) { wr = queue.GetRequestToExecute(wr); } if (wr != null) { CalculateWaitTimeAndUpdatePerfCounter(wr); wr.ResetStartTime(); ProcessRequestNow(wr); } } internal static void ProcessRequestNow(HttpWorkerRequest wr) { _theRuntime.ProcessRequestInternal(wr); }
Note:在上面的请求中是不是看到有很多ProcessRequest()方法,该方法在很多类里面出现,但是所处理的请求并不相同。实际上我们可以理解为一个驱动,在处理的过程中通过该方法加工请求信息,然后驱动请求向下进行。
&