原文:http://www.cnblogs.com/whtydn/archive/2009/10/16/1584418.html
 
下面最先介绍HttpRuntime的Web.config里的配置


<httpRuntime
   executionTimeout = "number" 
   maxRequestLength = "number" 
   requestLengthDiskThreshold = "number" 
   useFullyQualifiedRedirectUrl = "[True|False]" 
   minFreeThreads = "number" 
   minLocalRequestFreeThreads = "number" 
   appRequestQueueLimit = "number"
   enableKernelOutputCache = "[True|False]" 
   enableVersionHeader = "[True|False]" 
   apartmentThreading = "[True|False]"
   requireRootedSaveAsPath = "[True|False]"
   enable = "[True|False]" 
   sendCacheControlHeader = "[True|False]" 
   shutdownTimeout = "number"
   delayNotificationTimeout = "number"
   waitChangeNotification = "number" 
   maxWaitChangeNotification = "number" 
   enableHeaderChecking = "[True|False]" 
/>

通过上面的配置说明, 下面是在Web.Config里节点的设置


<configuration>
  <system.web>
  <httpRuntime maxRequestLength="4000"
    enable = "True"
    requestLengthDiskThreshold="512
    useFullyQualifiedRedirectUrl="True"
    executionTimeout="45"
    versionHeader="1.1.4128"/>
  </system.web>
</configuration>

IIS 所收到的对某 Microsoft ASP.NET 页面的每个请求都被移交给 ASP.NET HTTP 管线。HTTP 管线由一系列托管对象组成,这些对象按顺序处理该请求,并完成从 URL 到普通 HTML 文本的转换。HTTP 管线的入口点是 HttpRuntime 类。ASP.NET 基础结构为辅助进程中所承载的每个 AppDomain 创建此类的一个实例请注意,该辅助进程为当前正在运行的每个 ASP.NET 应用程序维护一个不同的 AppDomain。

要激活 HTTP 管道,可以创建一个 HttpRuntime 类的新实例,然后调用其 ProcessRequest 方法。一个完整的页面请求会包括下面的流程:
首先被WWW服务器截获(inetinfo.exe进程), 该进程首先判断页面后缀, 然后根据IIS中配置决定调用具体的扩展程序。aspx就会调用aspnet_isapi.dll, 
然后由aspnet_isapi.dll发送给w3wp.exe(iis 工作者进程,IIS6.0中叫做 w3wq.exe,IIS5.0中叫做 aspnet_wp.exe)。

接下来在w3wp.exe调用.NET类库进行具体处理,顺序如下:ISAPIRuntim, HttpRuntime, HttpApplicationFactory, HttpApplication, HttpModule, HttpHandlerFactory, HttpHandler

ISAPIRuntime:主要作用是调用一些非托管代码生成HttpWorkerRequest对象,HttpWorkerRequest对象包含当前请求的所有信息,然后传递给HttpRuntime
HttpRuntime:根据HttpWorkerRequest对象生成HttpContext,HttpContext包含request、response等属性, 再调用HttpApplicationFactory来生成IHttpHandler, 调用HttpApplication对象执行请求
HttpApplicationFactory: 生成一个HttpApplication对象
HttpApplication:进行HttpModule的初始化,HttpApplication创建针对此Http请求的 HttpContext对象
HttpModule: 当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。
HttpHandlerFactory:把用户request 转发到HttpHandlerFactory,再由HttpHandlerFactory实例化HttpHandler对象来相应request
HttpHandle:Http处理程序,处理页面请求

从上面看出HttpRuntime其中有一个ProcessRequest 方法
public static void ProcessRequest(HttpWorkerRequest wr);  //驱动所有 ASP.NET Web 处理执行。伪代码如下:


public static void HttpRuntime.ProcessRequest(HttpWorkerRequest wr)
 {
   // 检查当前调用者有没有作为ASP.NET宿主(Host)的权限
   InternalSecurityPermissions.AspNetHostingPermissionLevelMedium.Demand();     if(wr == null)
   {
     throw new ArgumentNullException("custom");
   }    RequestQueue queue = HttpRuntime._theRuntime._requestQueue;    if(queue != null)
   {
     // 将参数中的Web页面请求放入请求队列中, 并从队列中使用FIFO策略获取一个页面请求
     wr = queue.GetRequestToExecute(wr);
   }    if(wr != null)
   {     
     HttpRuntime.CalculateWaitTimeAndUpdatePerfCounter(wr); // 更新性能计数器     
      HttpRuntime.ProcessRequestNow(wr); // 实际完成页面请求工作
   }
 }

ProcessRequestNow函数则直接调用缺省HttpRuntime实例的ProcessRequestInternal函数完成实际页面请求工作,伪代码如下:

internal static void HttpRuntime.ProcessRequestNow(HttpWorkerRequest wr)
{
   HttpRuntime._theRuntime.ProcessRequestInternal(wr);
}

ProcessRequestInternal函数逻辑稍微复杂一些,大致可分为四个部分:
检查当前HttpRuntime实例是否第一次被调用,如果是第一次调用则通过FirstRequestInit函数初始化
调用HttpResponse.InitResponseWriter函数初始化页面请求的返回对象HttpWorkerRequest.Response
调用HttpApplicationFactory.GetApplicationInstance函数获取当前 Web 应用程序实例
使用Web应用程序实例完成实际的页面请求工作
伪代码如下:

private void HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
 {
   // 构造 HTTP 调用上下文对象
   HttpContext ctxt = new HttpContext(wr, 0);     // 设置发送结束异步回调函数
   wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, ctxt);    // 更新请求计数器
   Interlocked.Increment(&(this._activeRequestCount));    try
   {
     // 检查当前HttpRuntime实例是否第一次被调用
     if(this._beforeFirstRequest)
     {
       lock(this)
       {
         // 使用 Double-Checked 模式 避免冗余锁定
         if(this._beforeFirstRequest)
         {
           this._firstRequestStartTime = DateTime.UtcNow;
           this.FirstRequestInit(ctxt); // 初始化当前 HttpRuntime 运行时环境
           this._beforeFirstRequest = false;
         }
       }
     }      // 根据配置文件设置,扮演具有较高特权的角色
     ctxt.Impersonation.Start(true, false);
     try
     {
       // 初始化页面请求的返回对象
       ctxt.Response.InitResponseWriter();
     }
     finally
     {
       ctxt.Impersonation.Stop();
     }      // 获取当前 Web 应用程序实例
     IHttpHandler handler = HttpApplicationFactory.GetApplicationInstance(ctxt);      if (handler == null)
     {
       throw new HttpException(HttpRuntime.FormatResourceString("Unable_create_app_object"));
     }      // 使用Web应用程序实例完成实际的页面请求工作
     if((handler as IHttpAsyncHandler) != null)
     {
       IHttpAsyncHandler asyncHandler = ((IHttpAsyncHandler) handler);
       ctxt.AsyncAppHandler = asyncHandler;
       // 使用异步处理机制
       asyncHandler.BeginProcessRequest(ctxt, this._handlerCompletionCallback, ctxt);
     }
     else
     {
       handler.ProcessRequest(ctxt);
       this.FinishRequest(ctxt.WorkerRequest, ctxt, null);
     }
   }
   catch(Exception E)
   {
     ctxt.Response.InitResponseWriter();
     this.FinishRequest(wr, ctxt, E);
   }
 }

HttpRuntime.ProcessRequestInternal函数中调用了HttpApplicationFactory.GetApplicationInstance函数获取当前 Web 应用程序实例。至少HttpRuntime已经完完成,将转进HttpApplicationFactory阶段流程。大家可以看到,围绕HttpRuntime的函数都有一个HttpWorkerRequest参数,下面简单介绍一下这个参数的作用。在ISAPIRuntime阶段,调用一些非托管代码生成HttpWorkerRequest对象,该对象包含当前请求的所有信息,然后传递给HttpRuntime,这里生成的HttpWorkerRequest对象可以直接在我们的页面里调用.
IServiceProvider provider=(IServiceProvider)HttpContext.Current;
HttpWorkerRequest wr=(HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
然后可以通过wr来调用里面的方法。关于HttpWorkerRequest类里面包含的方法,从其元数据里面可以看到,如下:

Code
 
 
标签: C#HttpRuntimeAsp.Net

【转】HttpRuntime的认识与加深理解的更多相关文章

  1. 一篇RPO漏洞挖掘文章翻译加深理解。

    这是我第一次尝试翻译一篇漏洞挖掘文章,翻译它也是为了加深理解它.这是一篇很有意思的漏洞挖掘文章. 前几天在看fd的博客,偶然看到了这篇文章,虽然有点老了.但是思路真的牛皮.我决定花费时间和精力研究它们 ...

  2. 通过自己实现接口来加深理解SpringMVC的执行流程

    功能介绍 上篇文章[从源码角度了解SpringMVC的执行流程]通过接口源码向大家介绍了SpringMVC的执行流程,主要偏重于源码.这篇文件我们来自己实现那几个关键接口,来真实体验下SpringMV ...

  3. 加深理解Java异常概念并熟记5个最常见的运行时异常

    加深理解Java异常概念并熟记5个最常见的运行时异常 说明Error与Exception的联系和区别有哪些? 列举最常见的5个运用时异常. 1.Error和Exception的联系和区别: Error ...

  4. [ZigBee] 13、ZigBee基础阶段性回顾与加深理解——用定时器1产生PWM来控制LED亮度(七色灯)

    引言:PWM对于很多软件工程师可能又熟悉又陌生,以PWM调节LED亮度为例,其本质是在每个周期都偷工减料一些,整体表现出LED欠压亮度不同的效果.像大家看到的七色彩灯其原理也类似,只是用3路PWM分别 ...

  5. Sql Server之旅——第六站 使用winHex利器加深理解数据页

    这篇我来介绍一个winhex利器,这个工具网上有介绍,用途大着呢,可以用来玩数据修复,恢复删除文件等等....它能够将一个file解析成 hex形式,这样你就可以对hex进行修改,然后你就可以看到修复 ...

  6. typedef (还需经常看看加深理解)

    看了 c++primer 1,typedef名字 typedef定义以关键字typedef开始,后面是 数据类型+标示符. 并未引入新的类型,只是现有数据类型的同义词 例: typedef doubl ...

  7. java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解(勿删)

    head first java里写到“java是通过值传递的,也就是通过拷贝传递”,由此得出结论,方法无法改变调用方传入的参数.该怎么理解呢? 看例子: public class Test1 { pu ...

  8. 加深理解UIView,UIResponder,UIController

    转载出处:http://www.th7.cn/Program/IOS/201503/406514.shtml 原文地址==>自定义控件:http://objccn.io/issue-3-4/ 读 ...

  9. 【转】HttpApplication的认识与加深理解

    原文:http://www.cnblogs.com/whtydn/archive/2009/10/16/1584584.html HttpApplication对象是经由HttpApplication ...

随机推荐

  1. Spring MVC 原生API

    原生API: Servlet环境中一些有用的对象: HttpServletRequest HttpServletResponse HttpSession Reader Writer InputStre ...

  2. 基于WMI获取本机真实网卡物理地址和IP地址

    using System; using System.Collections.Generic; using System.Management; using System.Runtime.Intero ...

  3. css基础示例代码

    选择器 引入方式 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  4. 如何分析 WindowsDump:Dump 起源与初始设置

    https://www.qcloud.com/community/article/511817 转者注:让我感觉以前看蓝屏都白看了~~~原来蓝屏也可以分析具体原因. 适用场景:Windows 系列系统 ...

  5. 给Jquery easyui 的datagrid 每行增加操作链接(转)

    http://www.thinkphp.cn/code/207.html 通过formatter方法给Jquery easyui 的datagrid 每行增加操作链接我们都知道Jquery的EasyU ...

  6. linux 安装svn服务器

    一.下载 http://subversion.tigris.org/downloads/subversion-1.6.1.tar.gz http://subversion.tigris.org/dow ...

  7. Celery ---- 分布式队列神器 ---- 入门

    原文:http://python.jobbole.com/87238/ 参考:https://zhuanlan.zhihu.com/p/22304455 Celery 是什么? Celery 是一个由 ...

  8. PYTHON-进阶-装饰器小结,转载

    本文转载自:http://www.wklken.me/posts/2012/10/27/python-base-decorator.html 基本概念 具体概念自己google 装饰器是一个很著名的设 ...

  9. log4j2搭建记录

    今天新建了一个项目,自己弄的小玩意,想要做的正式点,就想引入日志.就想到了log4j2,经过几个小时的努力,还真的可以用了,下面就记录一下我是怎么做的. 下面是总的结构: 下面是MAVEN依赖: &l ...

  10. 遇到的IE不兼容问题总结

    IE浏览器兼容问题困扰多时,由于IE6不在进行修补,IE6的考虑也越来越少,有些IE遇到的不兼容的现象想做一个总结 1宽度或高度:IE的是width+border+margin+padding goo ...