管道处理模型一

本文详细介绍了HTTP请求的处理流程,从用户输入URL到IIS转发请求,再到HttpRuntime和HttpWorkerRequest的参与。重点讨论了管道处理模型的概念,以及HttpModule在请求处理中的作用。HttpModule允许开发者扩展HttpApplication事件,常用于权限认证、URL转发和反爬虫等场景。同时,文章还展示了如何自定义和扩展HttpModule。
摘要由CSDN通过智能技术生成

一.HTTP请求

我们自己写的程序,是怎样进行处理的?一个完整的HTTP请求流程:


1.用户浏览器输入地址,例如 http://www.csdn.net

2.DNS解析(域名供应商):将输入的网址解析成IP+端口

3.请求到达服务器Server:IP可以在互联网上唯一定位一台服务器,而端口是用来确定进程的,端口还可以带有协议信息,用于穿过防火墙。

4.HTTP.SYS服务接收HTTP请求:

我们可以自己用IIS部署一个网站,模拟HTTP请求。顺序是部署网站----指定一个端口监听----请求到服务器----带了端口信息和协议----被HTTP.SYS监听到。HTTP.SYS是安装IIS时自动装上去的。

5.IIS将请求转发给ISAPI

IIS不能处理我们写的代码,它只能将我们的代码转发到对应的程序进行处理,它里面有一个“处理映射程序”,这里配置的是IIS的处理方式,即请求是什么后缀名,就用哪种dll处理程序进行处理,其中*.cshtml、*.aspx、*.ashx都是由asp.net_isapi.dll来进行处理,如图



因为IIS只是将请求根据后缀转发到不同的处理程序,所以我们甚至可以给java和php指定处理程序。比如将php转发给php_ISAPI,java转发给java_ISAPI,只要配置好就可以实现。

如果是js,css,html等静态文件,IIS是直接返回的。

这里有个小问题,聪明的你可能会说,像mvc这样 Home/Index,没有后缀怎么办?

IIS6和它之前都不支持mvc的,后来出现了mvc,没有后缀怎么写匹配?IIS会给没有后缀的加一个axd的后缀再处理,如图:


到了IIS7.0,就不需要这么做了。

IIS的应用程序池分为集成和经典,如图:


经典模式表明是旧的,所以一般都用集成模式,

6.HttpWorkerRequest:在上一步,会将请求包装成一个对象,通过pipeline传到这里来,这里才是asp.net开发的入口,前面是系统帮我们做好的,我们程序员是从这里开始搞事情的!

好了,终于进到我们自己写的程序中来了,看看HttpWorkerRequest的定义,如图:


7.HttpRuntime.processrequest  

HttpRuntime:Http运行时,processrequest 是它下面的一个方法,看定义,如图:


ProcessRequest 方法需要一个HttpWorkerRequest参数,也就是上一步得到的。

public ActionResult Index()
{
   HttpRuntime.ProcessRequest(null);//web请求的入口
   return View();
}

至于ProcessRequest是怎么处理的,就要进入“管道处理模型”了。

什么是“管道处理模型”呢?就是一个请求进入到HttpRunTime之后,也就是从第7步开始,要做的事情,就叫做“管道处理模型”,因为前6步都是系统做好的,我们管不着,从第7步才开始运行我们写的代码。

我们用反编译工具打开System.Web.HttpRunTime,找到ProcessRequest


传入参数是HttpWorkerRequest类型的,如果传入null,抛出异常;如果没有使用管道模型,也抛出异常,如果都OK,就访问下一个方法 ProcessRequestNoDemand(wr)。


这里有个RequestQueue,因为Http请求也可以队列,如果队列不为空,就执行GetRequestToExecute(wr)方法进行处理,再看下面的ProcessRequestNow(wr)方法:


它调用了ProcessRequestInternal(wr)方法:


ProcessRequestInternal(wr)方法是怎么做的呢?如果被释放了(disposingHttpRuntime),那么就发送一个503的错误,"Server Too Busy",并用一个html页面来显示。如果没有被释放,就往下走,初始化一个HttpContext,它是Http请求上下文,如果初始化HttpContext失败了,就用html页面给用户返回一个400错误,下面的代码比较长,我再抓一个下面的图给大家看:


如果HttpContext初始化成功了,就把它拿到HttpApplicationFactory.GetApplicationInstance方法里面创建了一个HttpApplication对象。

每个请求都经过了上面的步骤,创建了一个HttpApplication对象,用这个HttpApplication对象来处理请求,HttpApplication是我们管道模型的核心。

通过上述步骤,终于执行到了我们写的代码,前面我们几乎没做什么,都是框架做的,我们也扩展不了。

看看HttpApplication的代码:


为什么有这么多的事件呢?因为HttpApplication要处理各种不同的请求,每个请求也许要做相同的事情,也可能不同的事情,也可能要做的事情的顺序不同,我们要把共性的部分封装起来,所以就封装成了这么多的事件(event),这样做的好处就是,遇到不同的请求,我们可以把这些事件排列和组合起来,就能完成请求的处理。

下图是对各个事件功能的介绍:

其中BeginRequest和EndRequest是方便我们做扩展的,可以在这两个方法里面加上我们要的触发动作。

PostMapRequestHandler就是把我们的请求创建一个处理器对象,我们写的MVC,Webform,都在它里面,要让它来实际执行的。


二.HttpModule

先写一段代码,用反射的方式获取所有系统自带的Http

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值