ASP.Net请求处理机制初步探索之旅 - Part 2 核心

开篇:上一篇我们了解了一个请求从客户端发出到服务端接收并转到ASP.Net处理入口的过程,这篇我们开始探索ASP.Net的核心处理部分,借助强大的反编译工具,我们会看到几个熟悉又陌生的名词(类):HttpRuntime、HttpWorkerRequest、HttpContext、HttpApplication等。

 

(1)Part 1:前奏

(2)Part 2:核心

(3)Part 3:管道

(4)Part 4:WebForm页面生命周期

(5)Part 5:MVC页面声命周期

 

一、第一个入口:ISAPIRuntme.ProcessRequest()

  ISAPIRuntime是进入NET托管环境的入口,它在方法中通过一个ecb句柄指向了当前请求报文体的内存地址,将HTTP请求报文简单封装为一个HttpWorkerRequest对象,然后就是各种我们经常听到的PR(ProcessRequest)方法了。

①调用ISAPIRuntime对象的ProcessRequest方法进入ASP.NET处理流程

  通过Reflector,我们可以看到在ISAPIRuntime中的这个入口方法:ProcessRequest

ASP.Net请求处理机制初步探索之旅 - Part 2 核心

 

 

 

②首先根据ecb句柄创建HttpWorkerRequest对象封装原始请求报文

ASP.Net请求处理机制初步探索之旅 - Part 2 核心

 

关于HttpWorkerRequest:

在Asp.Net中准备用于处理的请求,都必须封装为HttpWorkerRequest类型的对象,HttpWorkerRequest是一个抽象类型。这里创建的是一个ISAPIWorkerRequest类型,它继承于HttpWorkerRequest类。

ASP.Net请求处理机制初步探索之旅 - Part 2 核心
[ComVisible(false)]
public abstract class HttpWorkerRequest
{
    // Fields
    private DateTime _startTime;
    private Guid _traceId;
    ......
}
ASP.Net请求处理机制初步探索之旅 - Part 2 核心

 

 

 

 

 转到ISAPIWorkerRequest类的CreateWorkerRequest方法中,看到首先判断当前IIS服务器的版本(IIS6 or IIS7?),然后创建适合不同IIS的具体WorkerRequest对象,默认都是InProc进程内的,当然,也有OutOfProc进程外的。

ASP.Net请求处理机制初步探索之旅 - Part 2 核心
internal static ISAPIWorkerRequest CreateWorkerRequest(IntPtr ecb, bool useOOP)
{
    if (useOOP)
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
        if (EtwTrace.IsTraceEnabled(5, 1))
        {
            EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, false);
        }
        return new ISAPIWorkerRequestOutOfProc(ecb);
    }
    int num = UnsafeNativeMethods.EcbGetVersion(ecb) >> 0x10;
    if (num >= 7)
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.IIS7_ISAPI, ecb);
    }
    else
    {
        EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
    }
    if (EtwTrace.IsTraceEnabled(5, 1))
    {
        EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, true);
    }
    if (num >= 7)
    {
        return new ISAPIWorkerRequestInProcForIIS7(ecb);
    }
    if (num == 6)
    {
        return new ISAPIWorkerRequestInProcForIIS6(ecb);
    }
    return new ISAPIWorkerRequestInProc(ecb);
}
ASP.Net请求处理机制初步探索之旅 - Part 2 核心

  由于HttpWorkerRequest类封装的请求报文很原始,很复杂,所以微软没有将其公开出来。

二、第二个入口:HttpRuntime.ProcessRequest()

  HttpRuntime是ASP.NET请求处理的第二个入口。当请求进来,首先进入HttpRuntime,由HttpRuntime来决定如何处理请求。默认情况下,在machine.config和Web.config中并没有显式定义httpRuntime节点,但该节点是有默认值的,如下:

ASP.Net请求处理机制初步探索之旅 - Part 2 核心
ASP.Net请求处理机制初步探索之旅 - Part 2 核心
<httpRuntime 
   apartmentThreading="false"
   appRequestQueueLimit="5000"
   delayNotificationTimeout="5"
   enable="true"
   enableHeaderChecking="true"
   enableKernelOutputCache="true"
   enableVersionHeader="true"
   encoderType = "System.Web.Util.HttpEncoder"
   executionTimeout="110"
   maxQueryStringLength = "2048"
   maxRequestLength="4096"
   maxUrlLength = "260"
   maxWaitChangeNotification="0"
   minFreeThreads="8"
   minLocalRequestFreeThreads="4"
   relaxedUrlToFileSystemMapping = "False"
   requestLengthDiskThreshold="80"
   requestPathInvalidCharacters = "<,>,*,%,&,:,\"
   requestValidationMode = "4.0"
   requestValidationType = "System.Web.Util.RequestValidator"
   requireRootedSaveAsPath="true"
   sendCacheControlHeader="true"
   shutdownTimeout="90"
   useFullyQualifiedRedirectUrl="false"
   waitChangeNotification="0" />
ASP.Net请求处理机制初步探索之旅 - Part 2 核心

  通常情况下,我们可以在Web.config中更改httpRuntime节点的默认值,如下:

ASP.Net请求处理机制初步探索之旅 - Part 2 核心

上一篇:webpack_webpack-dev-server用法


下一篇:Linux平台Weblogic的简单安装