Asp.net请求处理之 管道处理

来源:互联网 发布:linux地址随机 编辑:程序博客网 时间:2024/05/20 08:00

在了解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);

我想大家看到这里就会明白为什么IIS7会有集成模式和经典模式了吧。可能大家不怎么重视此代码,让我们来看看经典模式的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;}

在MapHttpHandler里创建了IHttpHandlerFactory,进而创建了httphandler。

在ApplicationStepManager中BuildSteps的方法有steps.Add(new HttpApplication.CallHandlerExecutionStep(app));这么一句,这就是注册调用我们hanndler的地方。

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;}

里面调用了ResumeSteps方法

private void ResumeSteps(Exception error)
{
this._stepManager.ResumeSteps(error);
}

回到我们先前的ApplicationStepManager的ResumeSteps方法,里面有一句

error = application.ExecuteStep(this._execSteps[this._currentStepIndex], ref completedSynchronously);

Ahhpaplication的ExecuteStep方法


internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously){    Exception exception = null;    try    {        try        {            if (step.IsCancellable)            {                this._context.BeginCancellablePeriod();                try                {                    step.Execute();                }                finally                {                    this._context.EndCancellablePeriod();                }                this._context.WaitForExceptionIfCancelled();            }            else            {                step.Execute();            }            if (!step.CompletedSynchronously)            {                completedSynchronously = false;                return null;            }        }        catch (Exception exception2)        {            exception = exception2;            if (ImpersonationContext.CurrentThreadTokenExists)            {                exception2.Data["ASPIMPERSONATING"] = string.Empty;            }            if ((exception2 is ThreadAbortException) && ((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.Running))            {                exception = null;                this._stepManager.CompleteRequest();            }        }        catch        {        }    }    catch (ThreadAbortException exception3)    {        if ((exception3.ExceptionState != null) && (exception3.ExceptionState is CancelModuleException))        {            CancelModuleException exceptionState = (CancelModuleException) exception3.ExceptionState;            if (exceptionState.Timeout)            {                exception = new HttpException(SR.GetString("Request_timed_out"), null, 0xbb9);                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT);            }            else            {                exception = null;                this._stepManager.CompleteRequest();            }            Thread.ResetAbort();        }    }    completedSynchronously = true;    return exception;}

是真正执行IExecutionStep的Execute方法。

通过以上的分析我们可以简单的理解asp.net在管道模式下管道主要是通过ApplicationStepManager来注册和调用的。集成模式下的PipelineStepManager和ApplicationStepManager结构类似。

个人在这里只是抛砖引玉,希望大家拍砖。


原创粉丝点击