• http的请求和响应过程管道


    以IIS 6.0为例,在工作进程w3wp.exe中,利用aspnet_isapi.dll加载.NET运行时(如果.NET运行时尚未加载),IIS 6.0引入了应用程序池的概念,一个工作进程对应着一个应用程序池。一个应用程序池可以承载一个或多个Web应用,每个Web应用映射到一个IIS虚拟目录。与IIS 5.x一样,每一个Web应用运行在各自的应用程序域中。

    如果HTTP.SYS接收到的HTTP请求是对该Web应用的第一次访问,在成功加载了运行时后,会通过AppDomainFactory为该Web应用创建一个应用程序域,随后一个特殊的运行时IsapiRuntime被加载。IsapiRuntime定义在程序集System.Web中,对应的命名空间为System.Web.Hosting,被加载的IsapiRuntime会接管该HTTP请求。

    IsapiRuntime会首先创建一个IsapiWorkerRequest对象,用于封装当前的HTTP请求,并将该IsapiWorkerRequest对象传递给ASP.NET运行时HttpRuntime。从此时起,HTTP请求正式进入了ASP.NET管道。HttpRuntime会根据IsapiWorkerRequest对象创建用于表示当前HTTP请求的上下文(Context)对象HttpContext。

    随着HttpContext被成功创建,HttpRuntime会利用HttpApplicationFactory创建新的或获取现有的HttpApplication对象。实际上ASP.NET维护着一个HttpApplication对象池,HttpApplicationFactory从池中选取可用的HttpApplication用于处理HTTP请求,处理完毕后将其释放到对象池中。HttpApplicationFactory负责处理当前的HTTP请求。

    在HttpApplication初始化过程中,会根据配置文件加载并初始化相应的HttpModule对象。对于HttpApplication来说,在它处理HTTP请求的不同阶段会触发不同的事件(Event),而HttpModule的意义在于通过注册HttpApplication的相应的事件,将所需的操作注入整个HTTP请求的处理流程。ASP.NET的很多功能,比如身份验证、授权、缓存等,都是通过相应的HttpModule实现的。

    最终完成对HTTP请求的处理实现在HttpHandler中。对于不同的资源类型,具有不同的HttpHandler。比如.aspx页面对应的HttpHandler为System.Web.UI.Page,WCF的.svc文件对应的HttpHandler为System.ServiceModel.Activation.HttpHandler。上面整个处理流程如图1-11所示。


     

    HttpApplication

    HttpApplication是整个ASP.NET基础架构的核心,它负责处理分发给它的HTTP请求。由于一个HttpApplication对象在某个时刻只能处理一个请求,只有完成对某个请求的处理后,HttpApplication才能用于后续的请求的处理,所以ASP.NET采用对象池的机制来创建或获取HttpApplication对象。

    当第一个请求抵达时,ASP.NET会一次创建多个HttpApplication对象,并将其置于池中,选择其中一个对象来处理该请求。处理完毕后,HttpApplication不会被回收,而是释放到池中。对于后续的请求,空闲的HttpApplication对象会从池中取出,如果池中所有的HttpApplication对象都处于繁忙的状态,ASP.NET会创建新的HttpApplication对象。

    HttpApplication处理请求的整个生命周期是一个相对复杂的过程,在该过程的不同阶段会触发相应的事件。我们可以注册相应的事件,将处理逻辑注入到HttpApplication处理请求的某个阶段。表1-1按照实现的先后顺序列出了HttpApplication在处理每一个请求时触发的事件名称。

    表1-1  HttpApplication事件列表

    名    称 描    述
    BeginRequest HTTP管道开始处理请求时,会触发BeginRequest事件
    AuthenticateRequest,PostAuthenticateRequest ASP.NET先后触发这两个事件,使安全模块对请求进行身份验证
    AuthorizeRequest,PostAuthorizeRequest ASP.NET先后触发这两个事件,使安全模块对请求进程授权
    ResolveRequestCache,PostResolveRequestCache ASP.NET先后触发这两个事件,以使缓存模块利用缓存的内容对请求直接进行响应(缓存模块可以将响应内容进行缓存,对于后续的请求,直接将缓存的内容返回,从而提高响应能力)
    PostMapRequestHandler 对于访问不同的资源类型,ASP.NET具有不同的HttpHandler对其进行处理。对于每个请求,ASP.NET会通过扩展名选择匹配相应的HttpHandler类型,成功匹配后,该实现被触发
    AcquireRequestState,PostAcquireRequestState ASP.NET先后触发这两个事件,使状态管理模块获取基于当前请求相应的状态,如SessionState
    PreRequestHandlerExecute,PostRequestHandlerExecute ASP.NET最终通过与请求资源类型相对应的HttpHandler实现对请求的处理,在实行HttpHandler前后,这两个实现被先后触发
    ReleaseRequestState,PostReleaseRequestState ASP.NET先后触发这两个事件,使状态管理模块释放基于当前请求相应的状态
    UpdateRequestCache,PostUpdateRequestCache ASP.NET先后触发这两个事件,以使缓存模块将HttpHandler处理请求得到的内容得以保存到输出缓存中
    LogRequest,PostLogRequest ASP.NET先后触发这两个事件为当前请求进行日志记录
    EndRequest 整个请求处理完成后,EndRequest事件被触发

    对于一个ASP.NET应用来说,HttpApplication派生于Global.asax文件,我们可以通过创建global.asax文件对HttpApplication的请求处理行为进行定制。Global.asax采用一种很直接的方式实现了这样的功能,这种方式不是我们常用的方法重写或事件注册,而是直接采用方法名匹配。在Global.asax中,我们按照“Application_{Event Name}”这样的方法命名规则进行事件注册。比如Application_BeginRequest方法用于处理HttpApplication的BeginRequest事件。如果通过VS创建一个Global.asax文件,将采用如下的默认定义。
    <%@ Application Language="C#" %>
    <script runat="server">
        void Application_Start(object sender, EventArgs e){}   
        void Application_End(object sender, EventArgs e){}       
        void Application_Error(object sender, EventArgs e){}
        void Session_Start(object sender, EventArgs e){}
        void Session_End(object sender, EventArgs e){}
    </script>
    HttpModule

    ASP.NET拥有一个具有高度可扩展性的引擎,并且能够处理对于不同资源类型的请求,那么是什么成就了ASP.NET的高可扩展性呢? HttpModule功不可没。

    当请求转入ASP.NET管道时,最终负责处理该请求的是与请求资源类型相匹配的HttpHandler对象,但是在Handler正式工作之前,ASP.NET会先加载并初始化所有配置的HttpModule对象。HttpModule在初始化的过程中,会将一些功能注册到HttpApplication相应的事件中,在HttpApplication请求处理生命周期中的某个阶段,相应的事件会被触发,通过HttpModule注册的事件处理程序也得以执行。

    所有的HttpModule都实现了具有如下定义的System.Web.IHttpModule接口,其中Init方法用于实现HttpModule自身的初始化,该方法接受一个HttpApplication对象,有了这个对象,事件注册就很容易了。
    public interface IHttpModule
    {
        void Dispose();
        void Init(HttpApplication context);
    }

    ASP.NET提供的很多基础功能都是通过相应的HttpModule实现的,下面列出了一些典型的HttpModule。

    OutputCacheModule:实现了输出缓存(Output Caching)的功能。

    SessionStateModule:在无状态的HTTP协议上实现了基于会话(Session)的状态。

    WindowsAuthenticationModule+FormsAuthenticationModule+PassportAuthentication Module:实现了Windows、Forms和Passport这3种典型的身份认证方式。

    UrlAuthorizationModule + FileAuthorizationModule:实现了基于URI和文件ACL(Access Control List)的授权。

    除了这些系统定义的HttpModule之外,我们还可以自定义HttpModule,通过Web.config可以很容易地将其注册到Web应用中。

    HttpHandler

    对于不同资源类型的请求,ASP.NET会加载不同的Handler来处理,也就是说.aspx 页面与.asmx web 服务对应的Handler是不同的。所有的HttpHandler都实现了具有如下定义的接口System.Web.IHttpHandler,方法ProcessRequest提供了处理请求的实现。
    public interface IHttpHandler
    {  
        void ProcessRequest(HttpContext context);
        bool IsReusable { get; }
    }

    某些HttpHandler具有一个与之相关的HttpHandlerFactory,它实现了具有如下定义的接口System.Web.IHttpHandlerFactory,方法GetHandler用于创建新的HttpHandler,或者获取已经存在的HttpHandler。
    public interface IHttpHandlerFactory
    {
        IHttpHandler GetHandler(HttpContext context, string requestType,
          string url, string pathTranslated);
        void ReleaseHandler(IHttpHandler handler);
    }

    HttpHandler和HttpHandlerFactory的类型都可以通过相同的方式配置到Web.config中。下面一段配置包含对.aspx、.asmx和.svc这3种典型的资源类型的HttpHandler配置。
    <configuration>
      <system.web>
        <httpHandlers>
          <add path="*.svc"
                verb="*"
                type="System.ServiceModel.Activation.HttpHandler,
                        System.ServiceModel, Version=4.0.0.0, Culture=neutral,
                        PublicKeyToken=b77a5c561934e089"
                validate="false"/>
          <add path="*.aspx"
                verb="*"
                type="System.Web.UI.PageHandlerFactory"
                validate="true"/>
          <add path="*.asmx"
                verb="*"
                type="System.Web.Services.Protocols.WebServiceHandlerFactory,
                        System.Web.Services, Version=4.0.0.0, Culture=neutral,
                        PublicKeyToken=b03f5f7f11d50a3a"
                validate="False"/>
        </httpHandlers>
      </system.web>
    </configuration>

  • 相关阅读:
    「Vue」nrm
    「Vue」路由
    「Vue」父子组件之间的传值及调用方法
    「Vue」vue生命周期
    「Vue」自定义指令
    「Vue」自定义按键修饰符
    「Vue」过滤器
    常用断点设置
    BUUCTF 不一样的flag writeup
    好久没有写东西,最近在看逆向相关的东西,做点记录
  • 原文地址:https://www.cnblogs.com/wupeiqi/p/2944354.html
Copyright © 2020-2023  润新知