上图基本上演示了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 == )
{
zero = ecb;
ecb = UnsafeNativeMethods.GetEcb(zero);
}
//创建了ISAPIWorkRquest空对象
ISAPIWorkerRequest wr = null;
try
{
bool useOOP = iWRType == ;
//通过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 ;
}
HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated }));
return ;
}
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 ;
}
} ISAPIRuntime

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(, "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(, "Bad Request");
wr.SendKnownResponseHeader(, "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(, ))
{
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

ASP.NET底层原理的更多相关文章

  1. [置顶] Asp.Net底层原理(一、浏览器和服务器的交互原理)

    …… 一.浏览器和服务器的交互原理 二.写自己的"迷你"Asp.net框架 三.Asp.Net的请求与响应过程 1.在此之前,首先简单的模拟一下我们去请求一个网址的时候,浏览器和服 ...

  2. [置顶] Asp.Net底层原理(二、写自己的Asp.Net框架)

    我们介绍过了浏览器和服务器之间的交互过程,接下来介绍Asp.net处理动态请求. 写自己的Asp.Net框架,我们不会引用System.Web这个程序集,我们只需要创建要给自己的类库,所以在接下来的程 ...

  3. (转)Asp.Net底层原理(三、Asp.Net请求响应过程)

    原文地址:http://www.cnblogs.com/liuhf939/archive/2013/09/16/3324753.html 在之前,我们写了自己的Asp.Net框架,对整个流程有了一个大 ...

  4. asp.net内部原理3

    asp.net内部原理(三) 第三个版本 (最详细的版本) 前言: 今天继续吧这个系列补齐,这几天公司的项目比较忙,回到家已经非常的累了,所以也没顾得上天天来这里分享一些东西和大家一起探讨,但是今天晚 ...

  5. MVC底层原理

    窥探ASP.Net MVC底层原理 实现跨越Session的分布式TempData 1.问题的引出 我相信大家在项目中都使用过TempData,TempData是一个字典集合,一般用于两个请求之间临时 ...

  6. 【原创】asp.net内部原理(三) 第三个版本 (最详细的版本)

    前言: 今天继续吧这个系列补齐,这几天公司的项目比较忙,回到家已经非常的累了,所以也没顾得上天天来这里分享一些东西和大家一起探讨,但是今天晚上我还是坚持打开电脑,分享一些asp.net生命周期的知识, ...

  7. ASP.NET MVC原理

    仅此一文让你明白ASP.NET MVC原理   ASP.NET MVC由以下两个核心组成部分构成: 一个名为UrlRoutingModule的自定义HttpModule,用来解析Controller与 ...

  8. ASP.NT运行原理和页面生命周期详解及其应用

    ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用.  ...

  9. [翻译]了解ASP.NET底层架构(八)

    原文地址:http://www.cnblogs.com/tmfc/archive/2006/09/04/493304.html [翻译]了解ASP.NET底层架构(完) [翻译]了解ASP.NET底层 ...

随机推荐

  1. 【nodejs原理&源码杂记(8)】Timer模块与基于二叉堆的定时器

    [摘要] timers模块部分源码和定时器原理 示例代码托管在:http://www.github.com/dashnowords/blogs 一.概述 Timer模块相关的逻辑较为复杂,不仅包含Ja ...

  2. HC大会,华为联合合作伙伴发布一站式物联网IoT开发工具小熊派BearPi

    传统的物联网产品开发步骤复杂,涉及硬件开发.软件开发.云端开发等众多流程.而且产品的开发周期长.开发成本高.产品稳定性不佳.维护成本高.而物联网设备本身市场竞争激烈,价格低,设备更新迭代快,所以在保证 ...

  3. Springboot整合webservice

    Springboot整合webservice 2019-12-10 16:34:42 星期二 WebService是什么 WebService是一种跨编程语言和跨操作系统平台的远程调用技术,服务之间的 ...

  4. 转:使用JSR-303进行校验 @Valid

    一.在SringMVC中使用 使用注解 1.准备校验时使用的JAR validation-api-1.0.0.GA.jar:JDK的接口: hibernate-validator-4.2.0.Fina ...

  5. bash中$符号的一般用法

    $一般用于获取变量的内容(字符串或数字等),用以构成命令version=$(uname -r).构成字符串echo "my name is $myname".进行算术运算等tota ...

  6. (h,v) represent (horizontal,vertical)

    函数名h,v  代表 行和列 (horizontal,vertical) numpy 中 hstack 表示横向拼接两个行数相同的数组 In [42]: np.hstack((arr3,arr4)) ...

  7. 用C在GBA上写光线追踪(0)配置开发编译环境

    前段时间用C#写了一个光线追踪程序,可以渲染圆球,平面这种基本图形,反射,光照,阴影,都大致尝试做了一下. ↑ C#实现的光线追踪     ↑ GBA上C实现的光线追踪 然而,在我打算继续深入优化的时 ...

  8. IOS之文件夹创建、删除,图片在本地的保存和加载

    本文转自http://blog.csdn.net/toddmi/article/details/8204102 = (NSCachesDirectory, NSUserDomainMask, YES) ...

  9. IO 文件夹的拷贝

    package FileCopy; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ja ...

  10. [TimLinux] Python nonlocal和global的作用

    1. 执行代码 以下实例都是通过执行以下代码,需要把以下执行代码放在后面实例代码的后面. a = outer_func()print("call a()") a() a() a() ...