• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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)主要是调用GetNormalApplicationInstance
    复制代码 代码如下:

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

    复制代码 代码如下:

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

    在GetNormalApplicationInstance里面有一个比较关键的方法application.InitInternal(context, this._state, this._eventHandlerMethods);我们猜测它是做Application初始化的工作,包括http管道的初始化。
    复制代码 代码如下:

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

    里面的调用主要是

    context.Handler = this._application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false);

    而HttpApplication的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结构类似。

    个人在这里只是抛砖引玉,希望大家拍砖。
    您可能感兴趣的文章:
    • Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
    • ASP.NET Core 3.0 gRPC拦截器的使用
    • asp.net mvc core管道及拦截器的理解
    上一篇:HttpResponse的Output与OutputStream、Filter关系与区别介绍
    下一篇:asp.net Ajax之无刷新评论介绍
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Asp.net请求处理之管道处理介绍 Asp.net,请求,处理,之,管道,