zoukankan      html  css  js  c++  java
  • Asp.Net请求处理机制中IsApiRuntime解析

    今天看了web请求的生命周期,看完了还有些不懂,就是用反编译工具,查看封装内库的内部实现。

    从计算机内部查到web.dll,使用反编译工具打开

    打开后

    public int ProcessRequest(IntPtr ecb, int iWRType)
            {
                IntPtr intPtr = IntPtr.Zero;
                if (iWRType == 2)
                {
                    intPtr = ecb;
                    ecb = UnsafeNativeMethods.GetEcb(intPtr);
                }
    //首先创建ISAPIWorkerRequest,将请求报文封装在内,调用CreateWorkerRequest方法来实现, ISAPIWorkerRequest iSAPIWorkerRequest
    = null; int result; try { bool useOOP = iWRType == 1; iSAPIWorkerRequest = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP); iSAPIWorkerRequest.Initialize(); string appPathTranslated = iSAPIWorkerRequest.GetAppPathTranslated(); string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal; if (appDomainAppPathInternal == null || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal)) {
    //调用ProcessRequestNoDemand方法,并将封装的请求报文传入进去 HttpRuntime.ProcessRequestNoDemand(iSAPIWorkerRequest); result
    = 0; } else { HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated })); result = 1; } } catch (Exception ex) { try { WebBaseEvent.RaiseRuntimeError(ex, this); } catch { } if (iSAPIWorkerRequest == null || !(iSAPIWorkerRequest.Ecb == IntPtr.Zero)) { throw; } if (intPtr != IntPtr.Zero) { UnsafeNativeMethods.SetDoneWithSessionCalled(intPtr); } if (ex is ThreadAbortException) { Thread.ResetAbort(); } result = 0; } return result; }
    在CreateWorkerRequest内部,根据不同的IIS版本创建不同的对象

    // System.Web.Hosting.ISAPIWorkerRequest

    internal static ISAPIWorkerRequest CreateWorkerRequest(IntPtr ecb, bool useOOP)
    {
        ISAPIWorkerRequest result;
        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);
            }
            result = new ISAPIWorkerRequestOutOfProc(ecb);
        }
        else
        {
            int num = UnsafeNativeMethods.EcbGetVersion(ecb) >> 16;
            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)
            {
                result = new ISAPIWorkerRequestInProcForIIS7(ecb);
            }
            else
            {
                if (num == 6)
                {
                    result = new ISAPIWorkerRequestInProcForIIS6(ecb);
                }
                else
                {
                    result = new ISAPIWorkerRequestInProc(ecb);
                }
            }
        }
        return result;
    }

    进入ProcessRequestNoDemand内部

    // System.Web.HttpRuntime
    internal static void ProcessRequestNoDemand(HttpWorkerRequest wr)
    {
        RequestQueue requestQueue = HttpRuntime._theRuntime._requestQueue;
        wr.UpdateInitialCounters();
        if (requestQueue != null)
        {
            wr = requestQueue.GetRequestToExecute(wr);
        }
        if (wr != null)
        {
            HttpRuntime.CalculateWaitTimeAndUpdatePerfCounter(wr);
            wr.ResetStartTime();
    //调用ProcessRequestNow方法,并将封装的请求报文传入 HttpRuntime.ProcessRequestNow(wr); } }
    // System.Web.HttpRuntime
    internal static void ProcessRequestNow(HttpWorkerRequest wr)
    {
        HttpRuntime._theRuntime.ProcessRequestInternal(wr);
    }

    进入ProcessRequestInternal方法内部

    // System.Web.HttpRuntime
    private void ProcessRequestInternal(HttpWorkerRequest wr)
    {
        Interlocked.Increment(ref this._activeRequestCount);
        if (this._disposingHttpRuntime)
        {
            try
            {
                wr.SendStatus(503, "Server Too Busy");
                wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
                byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>");
                byte[] expr_45 = bytes;
                wr.SendResponseFromMemory(expr_45, expr_45.Length);
                wr.FlushResponse(true);
                wr.EndOfRequest();
            }
            finally
            {
                Interlocked.Decrement(ref this._activeRequestCount);
            }
            return;
        }
        HttpContext httpContext;
        try
        {
    //根据请求报文创建HttpContext对象,如果创建出错误就会返回404
    httpContext
    = new HttpContext(wr, false); } catch { try { wr.SendStatus(400, "Bad Request"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] bytes2 = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>"); byte[] expr_A5 = bytes2; wr.SendResponseFromMemory(expr_A5, expr_A5.Length); wr.FlushResponse(true); wr.EndOfRequest(); return; } finally { Interlocked.Decrement(ref this._activeRequestCount); } } wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, httpContext); HostingEnvironment.IncrementBusyCount(); try { try {
    //将第一次请求设置为false
    this.EnsureFirstRequestInit(httpContext); } catch { if (!httpContext.Request.IsDebuggingRequest) { throw; } }
    //初始化Response httpContext.Response.InitResponseWriter();
    //根据HttpApplicationFactory创建Application实例 IHttpHandler applicationInstance
    = HttpApplicationFactory.GetApplicationInstance(httpContext); if (applicationInstance == null) { throw new HttpException(SR.GetString("Unable_create_app_object")); } if (EtwTrace.IsTraceEnabled(5, 1)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, httpContext.WorkerRequest, applicationInstance.GetType().FullName, "Start"); } if (applicationInstance is IHttpAsyncHandler) { IHttpAsyncHandler httpAsyncHandler = (IHttpAsyncHandler)applicationInstance; httpContext.AsyncAppHandler = httpAsyncHandler; httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext); } else { applicationInstance.ProcessRequest(httpContext); this.FinishRequest(httpContext.WorkerRequest, httpContext, null); } } catch (Exception e) { httpContext.Response.InitResponseWriter(); this.FinishRequest(wr, httpContext, e); } }

    //进入EnsureFirstRequestInit

    // System.Web.HttpRuntime
    private void EnsureFirstRequestInit(HttpContext context)
    {
        if (this._beforeFirstRequest)
        {
            bool flag = false;
            try
            {
                Monitor.Enter(this, ref flag);
                if (this._beforeFirstRequest)
                {
    
                   //设置第一次请求为false
                    this._firstRequestStartTime = DateTime.UtcNow;
                    this.FirstRequestInit(context);
                    this._beforeFirstRequest = false;
                    context.FirstRequest = true;
                }
            }
            finally
            {
                if (flag)
                {
                    Monitor.Exit(this);
                }
            }
        }
    }

    Application中有26个方法,从上到下有19个请求管道事件

    1.熟悉请求管道实现程序运行的全过程:

    (1):BeginRequest: 开始处理请求。当ASP.NET运行时接收到新的HTTP请求的时候引发这个事件
    (2):AuthenticateRequest授权验证请求,获取用户授权信息。当ASP.NET 运行时准备验证用户身份的时候引发这个事件
    (3):PostAuthenticateRequest获取成功
    (4): AunthorizeRequest 授权,一般来检查用户是否获得权限。当ASP.NET运行时准备授权用户访问资源的时候引发这个事件
    (5):PostAuthorizeRequest:获得授权
    (6):ResolveRequestCache:获取页面缓存结果
    (7):PostResolveRequestCache 已获取缓存
    (8):PostMapRequestHandler 创建页面对象
    (9):AcquireRequestState 获取Session-----先判断当前页面对象是否实现了IRequiresSessionState接口,如果实现了,则从浏览器发来的请求报文体中获得SessionID,并到服务器的Session池中获得对应的Session对象,最后赋值给HttpContext的Session属性
    (10)PostAcquireRequestState 获得Session
    (11)PreRequestHandlerExecute:准备执行页面对象执行页面对象的ProcessRequest方法。在ASP.NET开始执行HTTP请求的处理程序之前引发这个事件。在这个事件之后,ASP.NET 把该请求转发给适当的HTTP处理程序。

    (12)PostRequestHandlerExecute 执行完页面对象了。在HTTP处理程序结束执行的时候引发这个事件
    (13)ReleaseRequestState 释放请求状态
    (14)PostReleaseRequestState 已释放请求状态
    (15)UpdateRequestCache 更新缓存
    (16)PostUpdateRequestCache 已更新缓存
    (17)LogRequest 日志记录
    (18)PostLogRequest 已完成日志
    (19)EndRequest 完成。把响应内容发送到客户端之前引发这个事件。

     转载一篇比较详细的生命周期文章:http://www.cnblogs.com/Cwj-XFH/p/6752177.html

  • 相关阅读:
    源码安装mysql-5.6.32.tar.gz
    linux 小喇叭 没了
    [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
    ARP协议和DNS协议对比
    subversion 版本库数据迁移 从一台服务器迁移到另一台新有服务器
    局域网通过ip查mac地址、通过mac地址查ip方法
    kmv xml 文件配置vnc 端口冲突 会无法启动
    kvm xxx.xml文件的位置
    select into from 提示 Undeclared variable.....错误的解决办法 && select into from 和 insert into select 的用法和区别
    Redux 入门教程
  • 原文地址:https://www.cnblogs.com/xiaoyaodijun/p/5133347.html
Copyright © 2011-2022 走看看