zoukankan      html  css  js  c++  java
  • Asp.net请求处理之 管道处理

    在了解Asp.net请求处理流程的过程中,个人认为有必要从源代码的角度来了解asp.net管道是怎么实现的。

    在此之前大家有必要了解一些asp.net请求流程的基本东东,如ASP.NET 请求处理流程Asp.net管道ASP.NET管线与应用程序生命周期 

    我们大家都知道HttpRuntime主要的方法是

    public static void ProcessRequest(HttpWorkerRequest wr)

    而它最终调用的是

    private void ProcessRequestInternal(HttpWorkerRequest wr)
    {
        HttpContext context;
        try
        {
            context = new HttpContext(wr, false);
        }
        catch
        {
            wr.SendStatus(400, "Bad Request");
            wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
            byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
            wr.SendResponseFromMemory(bytes, bytes.Length);
            wr.FlushResponse(true);
            wr.EndOfRequest();
            return;
        }
        wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);
        Interlocked.Increment(ref this._activeRequestCount);
        HostingEnvironment.IncrementBusyCount();
        try
        {
            try
            {
                this.EnsureFirstRequestInit(context);
            }
            catch
            {
                if (!context.Request.IsDebuggingRequest)
                {
                    throw;
                }
            }
            context.Response.InitResponseWriter();
            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;
                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);
        }
    }

    我们看到里面有这么一句

    IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);用来获取HttpApplication,而HttpApplication实现了IHttpAsyncHandler接口public class HttpApplication : IHttpAsyncHandler, IHttpHandler, IComponent, IDisposable,最后调用application的BeginProcessRequest方法。
    首先我们来看看HttpApplicationFactory.GetApplicationInstance(context)都干了什么

    internal static IHttpHandler GetApplicationInstance(HttpContext context)
    {
        if (_customApplication != null)
        {
            return _customApplication;
        }
        if (context.Request.IsDebuggingRequest)
        {
            return new HttpDebugHandler();
        }
        _theApplicationFactory.EnsureInited();
        _theApplicationFactory.EnsureAppStartCalled(context);
        return _theApplicationFactory.GetNormalApplicationInstance(context);
    }

    哦,它调用了GetNormalApplicationInstance这个方法,

    private HttpApplication GetNormalApplicationInstance(HttpContext context)
    {
        HttpApplication application = null;
        lock (this._freeList)
        {
            if (this._numFreeAppInstances > 0)
            {
                application = (HttpApplication) this._freeList.Pop();
                this._numFreeAppInstances--;
                if (this._numFreeAppInstances < this._minFreeAppInstances)
                {
                    this._minFreeAppInstances = this._numFreeAppInstances;
                }
            }
        }
        if (application == null)
        {
            application = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType);
            using (new ApplicationImpersonationContext())
            {
                application.InitInternal(context, this._state, this._eventHandlerMethods);
            }
        }
        return application;
    }

    里面有一个比较关键的方法application.InitInternal(context, this._state, this._eventHandlerMethods);

    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();
                            goto Label_006B;
                        }
                        finally
                        {
                            context.HideRequestResponse = false;
                            this._hideRequestResponse = false;
                        }
                    }
                    this.InitModules();
                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);
                }
                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;
        }
    }

    这个方法关键的代码在于:

     if (HttpRuntime.UseIntegratedPipeline)
                {
                    this._stepManager = new PipelineStepManager(this);
                }
                else
                {
                    this._stepManager = new ApplicationStepManager(this);
                }
                this._stepManager.BuildSteps(this._resumeStepsWaitCallback);

    可能大家不怎么重视此代码,让我们来看看ApplicationStepManager

    internal class ApplicationStepManager : HttpApplication.StepManager
    {
        // Fields
        private int _currentStepIndex;
        private int _endRequestStepIndex;
        private HttpApplication.IExecutionStep[] _execSteps;
        private int _numStepCalls;
        private int _numSyncStepCalls;
        private WaitCallback _resumeStepsWaitCallback;
    
        // Methods
        internal ApplicationStepManager(HttpApplication app) : base(app)
        {
        }
    
        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(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;
        }
    
        internal override void InitRequest()
        {
            this._currentStepIndex = -1;
            this._numStepCalls = 0;
            this._numSyncStepCalls = 0;
            base._requestCompleted = false;
        }
    
        [DebuggerStepperBoundary]
        internal override void ResumeSteps(Exception error)
        {
            bool flag = false;
            bool completedSynchronously = true;
            HttpApplication application = base._application;
            HttpContext context = application.Context;
            HttpApplication.ThreadContext context2 = null;
            AspNetSynchronizationContext syncContext = context.SyncContext;
            lock (base._application)
            {
                try
                {
                    context2 = application.OnThreadEnter();
                }
                catch (Exception exception)
                {
                    if (error == null)
                    {
                        error = exception;
                    }
                }
                try
                {
                    try
                    {
                    Label_0045:
                        if (syncContext.Error != null)
                        {
                            error = syncContext.Error;
                            syncContext.ClearError();
                        }
                        if (error != null)
                        {
                            application.RecordError(error);
                            error = null;
                        }
                        if (syncContext.PendingOperationsCount > 0)
                        {
                            syncContext.SetLastCompletionWorkItem(this._resumeStepsWaitCallback);
                        }
                        else
                        {
                            if ((this._currentStepIndex < this._endRequestStepIndex) && ((context.Error != null) || base._requestCompleted))
                            {
                                context.Response.FilterOutput();
                                this._currentStepIndex = this._endRequestStepIndex;
                            }
                            else
                            {
                                this._currentStepIndex++;
                            }
                            if (this._currentStepIndex >= this._execSteps.Length)
                            {
                                flag = true;
                            }
                            else
                            {
                                this._numStepCalls++;
                                context.SyncContext.Enable();
                                error = application.ExecuteStep(this._execSteps[this._currentStepIndex], ref completedSynchronously);
                                if (completedSynchronously)
                                {
                                    this._numSyncStepCalls++;
                                    goto Label_0045;
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (context2 != null)
                        {
                            try
                            {
                                context2.Leave();
                            }
                            catch
                            {
                            }
                        }
                    }
                }
                catch
                {
                    throw;
                }
            }
            if (flag)
            {
                context.Unroot();
                application.AsyncResult.Complete(this._numStepCalls == this._numSyncStepCalls, null, null);
                application.ReleaseAppInstance();
            }
        }
    }

    说简单一点这个类中的internal override void BuildSteps(WaitCallback stepCallback)方法就是为我们注册那19个管道事件, internal override void ResumeSteps(Exception error)就是依次执行此管道事件,而  steps.Add(new HttpApplication.MapHandlerExecutionStep(app));是映射我们的handler

    internal class MapHandlerExecutionStep : HttpApplication.IExecutionStep
    {
        // Fields
        private HttpApplication _application;
    
        // Methods
        internal MapHandlerExecutionStep(HttpApplication app)
        {
            this._application = app;
        }
    
        void HttpApplication.IExecutionStep.Execute()
        {
            HttpContext context = this._application.Context;
            HttpRequest request = context.Request;
            if (EtwTrace.IsTraceEnabled(5, 1))
            {
                EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest);
            }
            context.Handler = this._application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false);
            if (EtwTrace.IsTraceEnabled(5, 1))
            {
                EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest);
            }
        }
    
        // Properties
        bool HttpApplication.IExecutionStep.CompletedSynchronously
        {
            get
            {
                return true;
            }
        }
    
        bool HttpApplication.IExecutionStep.IsCancellable
        {
            get
            {
                return false;
            }
        }
    }

    里面调用了_application.MapHttpHandler

    internal IHttpHandler MapHttpHandler(HttpContext context, string requestType, VirtualPath path, string pathTranslated, bool useAppConfig)
    {
        IHttpHandler handler = (context.ServerExecuteDepth == 0) ? context.RemapHandlerInstance : null;
        using (new ApplicationImpersonationContext())
        {
            if (handler != null)
            {
                return handler;
            }
            HttpHandlerAction mapping = this.GetHandlerMapping(context, requestType, path, useAppConfig);
            if (mapping == null)
            {
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND);
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED);
                throw new HttpException(SR.GetString("Http_handler_not_found_for_request_type", new object[] { requestType }));
            }
            IHttpHandlerFactory factory = this.GetFactory(mapping);
            try
            {
                IHttpHandlerFactory2 factory2 = factory as IHttpHandlerFactory2;
                if (factory2 != null)
                {
                    handler = factory2.GetHandler(context, requestType, path, pathTranslated);
                }
                else
                {
                    handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated);
                }
            }
            catch (FileNotFoundException exception)
            {
                if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                {
                    throw new HttpException(0x194, null, exception);
                }
                throw new HttpException(0x194, null);
            }
            catch (DirectoryNotFoundException exception2)
            {
                if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                {
                    throw new HttpException(0x194, null, exception2);
                }
                throw new HttpException(0x194, null);
            }
            catch (PathTooLongException exception3)
            {
                if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                {
                    throw new HttpException(0x19e, null, exception3);
                }
                throw new HttpException(0x19e, null);
            }
            if (this._handlerRecycleList == null)
            {
                this._handlerRecycleList = new ArrayList();
            }
            this._handlerRecycleList.Add(new HandlerWithFactory(handler, factory));
        }
        return handler;
    }

    在这里创建了IHttpHandlerFactory,进而创建了httphandler
    而  steps.Add(new HttpApplication.CallHandlerExecutionStep(app));这句就是注册我们的handler,其源代码

    internal class CallHandlerExecutionStep : HttpApplication.IExecutionStep
    {
        // Fields
        private HttpApplication _application;
        private AsyncCallback _completionCallback;
        private IHttpAsyncHandler _handler;
        private bool _sync;
    
        // Methods
        internal CallHandlerExecutionStep(HttpApplication app)
        {
            this._application = app;
            this._completionCallback = new AsyncCallback(this.OnAsyncHandlerCompletion);
        }
    
        private void OnAsyncHandlerCompletion(IAsyncResult ar)
        {
            if (!ar.CompletedSynchronously)
            {
                HttpContext context = this._application.Context;
                Exception error = null;
                try
                {
                    try
                    {
                        this._handler.EndProcessRequest(ar);
                    }
                    finally
                    {
                        context.Response.GenerateResponseHeadersForHandler();
                    }
                }
                catch (Exception exception2)
                {
                    if ((exception2 is ThreadAbortException) || ((exception2.InnerException != null) && (exception2.InnerException is ThreadAbortException)))
                    {
                        this._application.CompleteRequest();
                    }
                    else
                    {
                        error = exception2;
                    }
                }
                if (EtwTrace.IsTraceEnabled(4, 4))
                {
                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);
                }
                this._handler = null;
                context.SetStartTime();
                if (HttpRuntime.IsLegacyCas)
                {
                    this.ResumeStepsWithAssert(error);
                }
                else
                {
                    this.ResumeSteps(error);
                }
            }
        }
    
        private void ResumeSteps(Exception error)
        {
            this._application.ResumeStepsFromThreadPoolThread(error);
        }
    
        [PermissionSet(SecurityAction.Assert, Unrestricted=true)]
        private void ResumeStepsWithAssert(Exception error)
        {
            this.ResumeSteps(error);
        }
    
        void HttpApplication.IExecutionStep.Execute()
        {
            HttpContext context = this._application.Context;
            IHttpHandler handler = context.Handler;
            if (EtwTrace.IsTraceEnabled(4, 4))
            {
                EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_ENTER, context.WorkerRequest);
            }
            if ((handler != null) && HttpRuntime.UseIntegratedPipeline)
            {
                IIS7WorkerRequest workerRequest = context.WorkerRequest as IIS7WorkerRequest;
                if ((workerRequest != null) && workerRequest.IsHandlerExecutionDenied())
                {
                    this._sync = true;
                    HttpException exception = new HttpException(0x193, SR.GetString("Handler_access_denied"));
                    exception.SetFormatter(new PageForbiddenErrorFormatter(context.Request.Path, SR.GetString("Handler_access_denied")));
                    throw exception;
                }
            }
            if (handler == null)
            {
                this._sync = true;
            }
            else if (handler is IHttpAsyncHandler)
            {
                IHttpAsyncHandler handler2 = (IHttpAsyncHandler) handler;
                this._sync = false;
                this._handler = handler2;
                IAsyncResult result = handler2.BeginProcessRequest(context, this._completionCallback, null);
                if (result.CompletedSynchronously)
                {
                    this._sync = true;
                    this._handler = null;
                    try
                    {
                        handler2.EndProcessRequest(result);
                    }
                    finally
                    {
                        context.Response.GenerateResponseHeadersForHandler();
                    }
                    if (EtwTrace.IsTraceEnabled(4, 4))
                    {
                        EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);
                    }
                }
            }
            else
            {
                this._sync = true;
                context.SyncContext.SetSyncCaller();
                try
                {
                    handler.ProcessRequest(context);
                }
                finally
                {
                    context.SyncContext.ResetSyncCaller();
                    if (EtwTrace.IsTraceEnabled(4, 4))
                    {
                        EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);
                    }
                    context.Response.GenerateResponseHeadersForHandler();
                }
            }
        }
    
        // Properties
        bool HttpApplication.IExecutionStep.CompletedSynchronously
        {
            get
            {
                return this._sync;
            }
        }
    
        bool HttpApplication.IExecutionStep.IsCancellable
        {
            get
            {
                return !(this._application.Context.Handler is IHttpAsyncHandler);
            }
        }
    }

    大家看到

    handler2.BeginProcessRequest(context, this._completionCallback, null);
    handler.ProcessRequest(context);

    这2句代码是不是很熟悉啊。

    在让我们回头看看HttpApplication的BeginProcessRequest方法

    IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
        this._context = context;
        this._context.ApplicationInstance = this;
        this._stepManager.InitRequest();
        this._context.Root();
        HttpAsyncResult result = new HttpAsyncResult(cb, extraData);
        this.AsyncResult = result;
        if (this._context.TraceIsEnabled)
        {
            HttpRuntime.Profile.StartRequest(this._context);
        }
        this.ResumeSteps(null);
        return result;
    }
    private void ResumeSteps(Exception error)
    {
        this._stepManager.ResumeSteps(error);
    }

    看到这里我想我们大家都应该明白asp.net管道处理了吧。
    看了asp.net管道的代码,我们不得不感叹一句asp.net源代码值得大家一读。

     

  • 相关阅读:
    2017年8月27日 星期日 --出埃及记 Exodus 29:6
    2017年8月26日 星期六 --出埃及记 Exodus 29:5
    2017年8月25日 星期五 --出埃及记 Exodus 29:4
    2017年8月24日 星期四 --出埃及记 Exodus 29:3
    2017年8月23日 星期三 --出埃及记 Exodus 29:2
    2017年8月22日 星期二 --出埃及记 Exodus 29:1
    2016年12月总结
    2016年11月总结
    2016年10月总结
    项目风险说明
  • 原文地址:https://www.cnblogs.com/majiang/p/2574754.html
Copyright © 2011-2022 走看看