• ASP.NET底层原理


    上图基本上演示了IIS 6整个处理过程。在User Mode下,http.sys接收到一个基于aspx的http request,然后它会根据IIS中的Metabase查看该基于该Request的Application属于哪个Application Pool,如果该Application Pool不存在,则创建之。否则直接将request发到对应Application Pool的Queue中。我上面已经说了,每个Application Pool对应着一个Worker Process:w3wp.exe,毫无疑问他是运行在User Mode下的。在IIS Metabase中维护着Application Pool和worker process的Mapping。WAS(Web Administrative service)根据这样一个mapping,将存在于某个Application Pool Queue的request 传递到对应的worker process(如果没有,就创建这样一个进程)。在worker process初始化的时候,加载ASP.NET ISAPI,ASP.NET ISAPI进而加载CLR。从而为ASP.NET Application创建一个托管的运行环境,在CLR初始化的使用会加载两个重要的dll:AppManagerAppDomainFactory和ISAPIRuntime。通过AppManagerAppDomainFactory的Create方法为Application创建一个Application Domain;通过ISAPIRuntime的ProcessRequest处理Request,进而将流程拖入到ASP.NET Http Runtime Pipeline的范畴,ASP.NET Http Runtime Pipeline对Http Request的处理是一个相对复杂的过程,相关的介绍会放在本篇文章的下一部份。在这里我们可以把它看成是一个黑盒,它接管Request,最终生成Html。

    ISAPIRuntime会首先创建一个ISAPIWorkRequest对象,对请求报文进行了简单的封装,并将该ISAPIWorkRequest对象传递给HttpRuntime。

    HttpRuntime会根据ISAPIWorkRequest创建用于封装Http请求上下文的对象HttpConetxt。

      HttpContext主要包括HttpRequest(当前请求)和HttpResponse(服务器响应)

    [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
    public int ProcessRequest(IntPtr ecb, int iWRType)
    {
        IntPtr zero = IntPtr.Zero;
        if (iWRType == 2)
        {
            zero = ecb;
            ecb = UnsafeNativeMethods.GetEcb(zero);
        }
        //创建了ISAPIWorkRquest空对象
        ISAPIWorkerRequest wr = null;
        try
        {
            bool useOOP = iWRType == 1;
        //通过ecb句柄创建了ISAPIWorkRequest对象
            wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
            wr.Initialize();
            string appPathTranslated = wr.GetAppPathTranslated();
            string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
            if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
            {
            //IsapiRuntime把WR交给了HttpRuntime
                HttpRuntime.ProcessRequestNoDemand(wr);
                return 0;
            }
            HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated }));
            return 1;
        }
        catch (Exception exception)
        {
            try
            {
                WebBaseEvent.RaiseRuntimeError(exception, this);
            }
            catch
            {
            }
            if ((wr == null) || !(wr.Ecb == IntPtr.Zero))
            {
                throw;
            }
            if (zero != IntPtr.Zero)
            {
                UnsafeNativeMethods.SetDoneWithSessionCalled(zero);
            }
            if (exception is ThreadAbortException)
            {
                Thread.ResetAbort();
            }
            return 0;
        }
    }
    
     
    
    ISAPIRuntime
    View Code

     HttpRuntime通过HttpApplicationFactory获取一个新的或现有的HttpApplication对象。

    private void ProcessRequestInternal(HttpWorkerRequest wr)
    {
        Interlocked.Increment(ref this._activeRequestCount);
        if (this._disposingHttpRuntime)
        {
            try
            {
                wr.SendStatus(0x1f7, "Server Too Busy");
                wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
                byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>");
                wr.SendResponseFromMemory(bytes, bytes.Length);
                wr.FlushResponse(true);
                wr.EndOfRequest();
            }
            finally
            {
                Interlocked.Decrement(ref this._activeRequestCount);
            }
        }
        else
        {
            HttpContext context;
            try
            {
            //通过wr创建了上下文对象
                context = new HttpContext(wr, false);
            }
            catch
            {
                try
                {
                    wr.SendStatus(400, "Bad Request");
                    wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
                    byte[] data = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
                    wr.SendResponseFromMemory(data, data.Length);
                    wr.FlushResponse(true);
                    wr.EndOfRequest();
                    return;
                }
                finally
                {
                    Interlocked.Decrement(ref this._activeRequestCount);
                }
            }
            wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);
            HostingEnvironment.IncrementBusyCount();
            try
            {
                try
                {
                    this.EnsureFirstRequestInit(context);
                }
                catch
                {
                    if (!context.Request.IsDebuggingRequest)
                    {
                        throw;
                    }
                }
                context.Response.InitResponseWriter();
            
            //通过HttpApplicationFactory获取HttpApplication实例
                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;
    
                //执行HttpApplication的BeginProcessRequest方法
                    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);
            }
        }
    }
    
    HttpRuntime
    View Code
  • 相关阅读:
    PHP计算近1年的所有月份
    mysql的索引和锁
    深度解析 https 协议
    linux 常用命令大全
    为什么Python3.6字典变得有序了?
    oddo
    RESTful接口开发规范
    python中的 __inti__ 和 __new__ 方法的区别
    十大经典算法 Python实现
    MongoDB journal 与 oplog,究竟谁先写入?--转载
  • 原文地址:https://www.cnblogs.com/jiangdd/p/3843849.html
Copyright © 2020-2023  润新知