ASP.NET从源码看实现(三):HttpApplication

IIS处理流程:HttpApplication   

        当HttpApplication对象经由HttpApplicationFactory.GetApplicationInstance方法从HttpApplication对象池中获取到实例后,直接调用了  state.InitInternal(context, this._state, this._eventHandlerMethods)方法;

   InitInternal方法的主要功能如下:

   1.InitIntegratedModules():会加载IIS7集成模式下在服务器上设定的HttpModuels和Web.config里system.webserver下的HttpModuels。
   2. InitModules():根据Web.Config的设置,创建相应的HttpModules。

   3. HookupEventHandlersForAppplicationAndModules:根据发生的事件,调用HttpApplication实例中相应的事件处理函数。

   4. 创建很多实现IExecutionStep接口的类的实例并添加到当前HttpApplication实例的_execSteps中,等待回调时执行。从 这里我们可以看到HttpApplication是以异步的方式处理请求, 对请求的很多处理工作都放入了    _execStep等待回调时执行。
     _execStep中主要的处理工作如下:
    1) 对请求的路径进行安全检查,禁止非法路径访问(ValidatePathExecutionStep)。
    2) 如果设置了UrlMappings, 进行RewritePath(UrlMappingsExecutionStep)。
    3) 执行事件处理函数,比如:BeginRequest、AuthenticateRequest等等。

      InitInternal方法也是一个比较复杂的方法,里面对于IIS采用的是Integrated(集成)模式还是Classic(经典)模式进行分别的处理,主要完成的工作时HttpModule的初始化和处理请求过程中每个步骤触发事件处理程序的准备。       在经典模式下,IIS会用ISAPI扩展(ISAPI extension aspnet_isapi.dll)和 ISAPI过滤器(ISAPI filter aspnet_filter.dll)来调用ASP.NET运行库来出来请求。如果使用经典模式的话,服务器会用两种管道来处理请求一个负责源代码,另外一个负责托管代码。在这种模式下,应用程序不能充分使用IIS7.X提供的服务。

     集成模式是一种统一的请求处理管道,它将ASP.NET请求管道与IIS核心管道组合在一起。在集成模式下,ASP.NET从IIS插件(IIS extension)的角色进入了IIS的核心去监测每个请求和操作。在集成模式下,ASP.NET能更有效的在IIS下运行,并且可以有效的提高网站的性能。

 关于IIS的经典模式与集成模式的详细介绍请参考 IIS 7.0的集成模式和经典模式

 

       ///HttpApplication类
        internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers)
        {
            this._state = state;
            PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES);
            try
            {
                try
                {
                    this._initContext = context;
                    this._initContext.ApplicationInstance = this;
                    context.ConfigurationPath = context.Request.ApplicationPathObject;
                    using (new DisposableHttpContextWrapper(context))
                    {
                        if (HttpRuntime.UseIntegratedPipeline)
                        {
                            try
                            {
                                context.HideRequestResponse = true;
                                this._hideRequestResponse = true;
                                this.InitIntegratedModules();//Integrate模式下Module的初始化
                                goto Label_006B;
                            }
                            finally
                            {
                                context.HideRequestResponse = false;
                                this._hideRequestResponse = false;
                            }
                        }
                        this.InitModules();//根据Web.Config的设置,创建相应的HttpModules
                    Label_006B:
                        if (handlers != null)
                        {
                            this.HookupEventHandlersForApplicationAndModules(handlers);
                        }
                        this._context = context;
                        if (HttpRuntime.UseIntegratedPipeline && (this._context != null))
                        {
                            this._context.HideRequestResponse = true;
                        }
                        this._hideRequestResponse = true;
                        try
                        {
                            this.Init();
                        }
                        catch (Exception exception)
                        {
                            this.RecordError(exception);
                        }
                    }
                    if (HttpRuntime.UseIntegratedPipeline && (this._context != null))
                    {
                        this._context.HideRequestResponse = false;
                    }
                    this._hideRequestResponse = false;
                    this._context = null;
                    this._resumeStepsWaitCallback = new WaitCallback(this.ResumeStepsWaitCallback);
                    if (HttpRuntime.UseIntegratedPipeline)
                    {
                        this._stepManager = new PipelineStepManager(this);//Integrate模式下
                    }
                    else
                    {
                        this._stepManager = new ApplicationStepManager(this);//经典模式
                    }
                    this._stepManager.BuildSteps(this._resumeStepsWaitCallback);
                }
                finally
                {
                    this._initInternalCompleted = true;
                    context.ConfigurationPath = null;
                    this._initContext.ApplicationInstance = null;
                    this._initContext = null;
                }
            }
            catch
            {
                throw;
            }
        }

 

this.InitModules()方法中首先加载配置文件中所有的HttpModule,当获取到所有的HttpModule集合后在InitModulesCommon方法中循环调用每个HttpModule的Init方法;

 

       private void InitModules()
        {
            HttpModuleCollection modules = RuntimeConfig.GetAppConfig().HttpModules.CreateModules();
            HttpModuleCollection other = this.CreateDynamicModules();
            modules.AppendCollection(other);
            this._moduleCollection = modules;
            this.InitModulesCommon();
        }
        private void InitModulesCommon()
        {
            int count = this._moduleCollection.Count;
            for (int i = 0; i < count; i++)
            {
                this._currentModuleCollectionKey = this._moduleCollection.GetKey(i);
                this._moduleCollection[i].Init(this);
            }
            this._currentModuleCollectionKey = null;
            this.InitAppLevelCulture();
        }

 

对应this.HookupEventHandlersForApplicationAndModules(handlers)方法就是调用Global.asax中的方法相关实现的事件;

StepManager类是一个管理Step的抽象类,他的抽象方法BuildSteps就是将HTTP的管道时间添加到HttpApplication.IExecutionStep[] _execSteps,等待回调;

         
          //ApplicationStepManager : HttpApplication.StepManager
            internal override void BuildSteps(WaitCallback stepCallback)
            {
                ArrayList steps = new ArrayList();
                HttpApplication app = base._application;
                bool flag = false;
                UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;
                flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0);
                steps.Add(new HttpApplication.ValidateRequestExecutionStep(app));
                steps.Add(new HttpApplication.ValidatePathExecutionStep(app));
                if (flag)
                {
                    steps.Add(new HttpApplication.UrlMappingsExecutionStep(app));
                }
                app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);
                steps.Add(new HttpApplication.MapHandlerExecutionStep(app));
                app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);
                steps.Add(app.CreateImplicitAsyncPreloadExecutionStep());
                steps.Add(new HttpApplication.CallHandlerExecutionStep(app));
                app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);
                steps.Add(new HttpApplication.CallFilterExecutionStep(app));
                app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps);
                this._endRequestStepIndex = steps.Count;
                app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);
                steps.Add(new HttpApplication.NoopExecutionStep());
                this._execSteps = new HttpApplication.IExecutionStep[steps.Count];
                steps.CopyTo(this._execSteps);
                this._resumeStepsWaitCallback = stepCallback;
            }
  1. 对请求的Request进行验证,ValidateRequestExecutionStep。
  2. 对请求的路径进行安全检查,禁止非法路径访问(ValidatePathExecutionStep)。 
  3. 如果设置了UrlMappings, 进行RewritePath(UrlMappingsExecutionStep)。
  4. 执行事件处理函数,比如将BeginRequest、AuthenticateRequest转化成可执行ExecutionStep在正式调用时候执行。
  5. 在这18个事件操作处理期间,根据不同的时机加了4个特殊的ExecutionStep。
    1. MapHandlerExecutionStep:查找匹配的HttpHandler
    2. CallHandlerExecutionStep:执行HttpHandler的BeginProcessRequest
    3. CallFilterExecutionStep:调用Response.FilterOutput方法过滤输出
    4. NoopExecutionStep:空操作,留着以后扩展用

需要注意的是所有的ExecuteionStep都保存在ApplicationStepManager实例下的私有字段_execSteps里, 而HttpApplication的BeginProcessRequest方法最终会通过该实例的ResumeSteps方法来执行这些操作(就是我们 所说的那些事件以及4个特殊的Steps)。

具体这个方法的实现可以参考汤姆大叔写的MVC之前的那点事儿系列(5):Http Pipeline详细分析(下)这个博客;

至此,当HttpApplication的InitInternal方法执行完后,整个HttpApplication就从HttpApplicationFactory工厂中创建完成,并返回到HttpRuntime.ProcessRequestInternal方法中;

 

posted @ 2014-11-25 10:46  飞蛾扑火  阅读(994)  评论(1编辑  收藏  举报