HTTP协议与IIS.docx
- 文档编号:8253450
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:17
- 大小:1.13MB
HTTP协议与IIS.docx
《HTTP协议与IIS.docx》由会员分享,可在线阅读,更多相关《HTTP协议与IIS.docx(17页珍藏版)》请在冰豆网上搜索。
HTTP协议与IIS
前言
前一段在整理邮件的时候发现几年前和CDD老师交流时的一份邮件.下面是简单摘要:
“从技术角度来说,无论哪一个阵营,跟新技术都是不可避免的,也是很累的,当然作为一个程序员来说,也是必须的。
要想让技术的更新对自己的影响减小,基础就必须打牢。
所以,底层的东西和抽象层的东西需要下一番功夫。
因为说到底,无论什么技术,无非就是架构和最终的实现,技术框架只是应用开发的一个平台一种技术,如果了解了具体的东西,技术更新对你来说就没什么影响了,或者换句话说,你要学一种新的技术,速度和效率会非常之高。
”
上面一段话对自己的影响很大,可能大家在踏入“程序人生”的时候都会存在一些迷茫和彷徨。
尽管我是属于那种相当热爱Proramming的一份子,但是面对万花筒般的技术分支也曾徘徊犹豫过.徘徊之余要做的事情便是夯实基础,寻找自己的兴趣与方向.对技术的迭代,以不变应万变才是王道.
正因为如此,所以也不会存在银弹之说.如果真的有银弹的话那么我信奉的是:
程序=数据结构+算法
我选择的方向是Web,也相信Web终究会是互联网的未来.这篇文章简单谈一下自己对.NET平台下Web基础的一些浅解,由于自己水平有限,不足之处烦请见谅.
HTTP协议
HTTP协议是浏览器和服务器双方共同遵循的规范.是一种基于TCP/IP(传输层协议,相对应的有UDP)的"应用层协议"
PS:
TCP/UDP是广泛使用的网络通信协议,UDP协议具有不可靠性和不安全性,
相对来说TCP协议是基于连接和三次握手的(相对可靠与安全),然而B/S架构的网站,由于同时在线的人数会很多,如果都与服务器保持连接状态.服务器的承载是相当大的,
因而衍生出HTTP协议.简单的说:
请求发起之后服务器端立刻关闭连接并释放资源.也正因为如此,HTTP协议通常被理解为”无状态”的.
当然维系"状态"的手段有很多;如Session/Cookie等这里暂且不多做讨论.
先来看一下典型的OSI七层模型图解
HTTP最通俗的理解请求/响应.
图示:
HTTP报文信息
HTTPRequestHeader
HTTPResponseHeader
当然,也可以通过设置改变浏览器的选项.这里不做详细说明.不清楚的可以Google.
给出ASP.NET下添加P3P头信息的例子
HttpContext.Current.Response.AddHeader("p3p","CP=\"IDCDSPCORADMDEViTAIiPSAPSDIVAiIVDiCONiHISOURINDCNT\"");
有兴趣详细了解的可以参考MSDN中关于部署P3P的文章。
下面是老生常谈的内容了(熟悉的朋友,自行跳过,权当温习下了:
))
请求头(消息头)包含(客户机请求的服务器主机名,客户机的环境信息等):
Accept:
用于告诉服务器,客户机支持的数据类型(例如:
Accept:
text/html,image/*)
Accept-Charset:
用于告诉服务器,客户机采用的编码格式
Accept-Encoding:
用于告诉服务器,客户机支持的数据压缩格式
Accept-Language:
客户机语言环境
Host:
客户机通过这个服务器,想访问的主机名
If-Modified-Since:
客户机通过这个头告诉服务器,资源的缓存时间
Referer:
客户机通过这个头告诉服务器,它(客户端)是从哪个资源来访问服务器的(防盗链)
User-Agent:
客户机通过这个头告诉服务器,客户机的软件环境(操作系统,浏览器版本等)
Cookie:
客户机通过这个头,将Coockie信息带给服务器
Connection:
告诉服务器,请求完成后,是否保持连接
Date:
告诉服务器,当前请求的时间
一个http响应代表服务器端向客户端回送的数据,它包括:
一个状态行,若干个响应消息头,以及实体内容
状态行:
例如:
HTTP/1.1200OK(协议的版本号是1.1响应状态码为200响应结果为OK)
响应头(消息头)包含:
Location:
这个头配合302状态吗,用于告诉客户端找谁
Server:
服务器通过这个头,告诉浏览器服务器的类型
Content-Encoding:
告诉浏览器,服务器的数据压缩格式
Content-Length:
告诉浏览器,回送数据的长度
Content-Type:
告诉浏览器,回送数据的类型
Last-Modified:
告诉浏览器当前资源缓存时间
Refresh:
告诉浏览器,隔多长时间刷新
Content-Disposition:
告诉浏览器以下载的方式打开数据。
例如:
context.Response.AddHeader("Content-Disposition","attachment:
filename=icon.jpg");context.Response.WriteFile("icon.jpg");
Transfer-Encoding:
告诉浏览器,传送数据的编码格式
ETag:
缓存相关的头(可以做到实时更新)
Expries:
告诉浏览器回送的资源缓存多长时间。
如果是-1或者0,表示不缓存
Cache-Control:
控制浏览器不要缓存数据no-cache
Pragma:
控制浏览器不要缓存数据no-cache
Connection:
响应完成后,是否断开连接。
close/Keep-Alive
Date:
告诉浏览器,服务器响应时间
IIS运行过程
有了上面的HTTP协议的知识回顾,下面来让我们看下IIS是怎样工作的?
IIS5.X已经距离我们很远了.好吧XP默认的好像是的…为万恶的IE6默哀下0.0.
这里我们来看一下IIS6的图示
根据上图简单分析下IIS6的运行过程
在UserMode下,http.sys接收到httprequest,然后它会根据IIS中的Metabase查看基于该Request的Application属于哪个ApplicationPool,如果该ApplicationPool不存在,则创建之。
否则直接将request发到对应ApplicationPool的Queue中。
每个ApplicationPool对应着一个WorkerProcess—w3wp.exe,(运行在UserMode下)。
在IISMetabase中维护着ApplicationPool和WorkerProcess的Mapping。
WAS(WebAdministrativeService)根据这样一个mapping,将存在于某个ApplicationPoolQueue的request传递到对应的WorkerProcess(如果没有,就创建这样一个进程)。
在WorkerProcess初始化的时候,加载ASP.NETISAPI,ASP.NETISAPI进而加载CLR。
最后通过AppManagerAppDomainFactory的Create方法为Application创建一个ApplicationDomain;通过ISAPIRuntime的ProcessRequest处理Request,进而将流程进入到ASP.NETHttpRuntimePipeline。
PS几个知识点:
1HTTP.SYS:
(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求,根据请求的URL将其转发给相应的应用程序池(ApplicationPool)。
当此HTTP请求处理完成时,它又负责将处理结果发送出去.为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来。
2ApplicationPool:
IIS总会保持一个单独的工作进程:
应用程序池。
所有的处理都发生在这个进程里,包括ISAPIdll的执行。
对于IIS6而言,应用程序池是一个重大的改进,因为它们允许以更小的粒度控制一个指定进程的执行。
你可以为每一个虚拟目录或者整个Web站点配置应用程序池,这可以使你很容易的把每一个应用程序隔离到各自的进程里,这样就可以把它与运行在同一台机器上其他程序完全隔离。
从Web处理的角度看,如果一个进程死掉,至少它不会影响到其它的进程。
当应用程序池接收到HTTP请求后,交由在此应用程序池中运行的工作者进程WorkerProcess:
w3wp.exe来处理此HTTP请求。
3WorkerProcess:
当工作者进程接收到请求后,首先根据后缀找到并加载对应的ISAPI扩展(如:
aspx对应的映射是aspnet_isapi.dll),工作者进程加载完aspnet_isapi.dll后,由aspnet_isapi.dll负责加载ASP.NET应用程序的运行环境即CLR(.NETRuntime)。
WorkerProcess运行在非托管环境,而.NET中的对象则运行在托管环境之上(CLR),它们之间的桥梁就是ISAPI扩展。
4WAS(WebAdminService):
这是一个监控程序,它一方面可以存取放在InetInfo元数据库(Metabase)中的各种信息,另一方面也负责监控应用程序池(ApplicationPool)中的工作者进程的工作状态况,必要时它会关闭一个老的工作者进程并创建一个新的取而代之。
再来看下网上对IIS7经典模式下的图解
IIS7应用程序池的托管管道模式“经典”模式也是这样的工作原理。
这种模式是兼容IIS6的方式,以减少升级的成本。
小插曲
场景假定:
截获客户端的请求,并对请求进行重写。
在IIS6中,请求的截获动作只能被限制在IIS加载aspnet_isapi.dll后,也就是说:
如果该请求不是明确针对资源的请求(比如这个请求只是一个静态文件的请求,如
咦,有木有人和我一样想到了URLRouting和URLRewriting?
这里不做说明,大叔手记16传送门:
这个问题先放一下~~了解II7的集成模式也许可以有一些思绪
让我们再来看下IIS官网上对IIS7的图解
传送门:
1、当客户端浏览器开始HTTP请求一个WEB服务器的资源时,HTTP.sys拦截到这个请求。
2、HTTP.sys联系WAS获取配置信息。
3、WAS向配置存储中心(applicationHost.config)请求配置信息。
4、WWW服务接收到配置信息,配置信息指类似应用程序池配置信息,站点配置信息等等。
5、WWW服务使用配置信息去配置HTTP.sys处理策略。
6、WAS为请求创建一个进程(如果不存在的话)
7、工作者进程处理请求并对HTTP.sys做出响应.
8、客户端接受到处理结果信息。
IIS7应用程序池的托管管道模式(集成模式)华丽的变身
IIS7中对的请求不再是分两条处理管道,而是将和IIS集成起来,这样做的好处是统一了请求验证工作,加强了对于请求的控制能力等等。
在IIS7中,不再像IIS6一样只限定于aspnet_isapi.dll中,而是被解放出来,从IIS接收到HTTP请求开始,即进入的控制范围,可以存在于一个请求在IIS中各个处理阶段。
甚至可以为部署在IIS7中的PHP应用提供基于的验证身份验证功能(传送门:
好吧,戛然而止一下,篇幅有限:
IIS部分告一段落留一些遐想空间.
再来分析ASP.NET的运行机制
ASP.NET运行机制
在IIS6图示中我们分析到“AppManagerAppDomainFactory的Create方法为Application创建一个ApplicationDomain;通过ISAPIRuntime的ProcessRequest处理Request,进而将流程进入到ASP.NETHttpRuntimePipeline。
”
下面我们来看一下AppDomain运行过程图示
AppDomain的作用,相信大家都很了解了吧.这里简明扼要的写几点:
一个AppDomain中的代码创建的对象不能由另一个AppDomain中的代码直接访问(只能使用按引用封送或者按值封送,起到了很好的隔离作用).
AppDomain可以卸载CLR不支持从AppDomain中卸载一个程序集的能力,但可以告诉CLR卸载一个AppDomain,从而达到卸载当前包含在该AppDomain内的所有程序集.
AppDomain可以单独保护当宿主加载一些代码之后,可以保证这些代码不会被破坏(或读取)宿主本身使用的一些重要的数据结构.
AppDomain可以单独配置设置主要影响CLR在AppDomain中加载程序集的方式,涉及搜索路径、版本绑定重定向、卷影复制及加载器的优化。
由以上几点可以看出AppDomain确保了Windows系统及其中运行的应用程序的健壮性。
AppDomain提供了保护、配置和终止其中每一个应用程序所需的隔离性。
再来看下ProcessRequest的过程
简单分析一下上图
ProcessRequest(HttpWorkerRequestwr)中判断wr是否为null,然后判断管线是否完整,再调用ProcessRequestNoDemand(wr)方法,
并判断当前RequestQueue是否为null,接着计算等待时间并更新管线数CalculateWaitTimeAndUpdatePerfCounter(wr);
重置wr开始时间wr.ResetStartTime();调用ProcessRequestNow(wr)方法,并调用ProcessRequestInternal(wr)方法
继续图例
ProcessRequestInternal方法如下:
1privatevoidProcessRequestInternal(HttpWorkerRequestwr)
2{
3HttpContextcontext;
4try
5{
6context=newHttpContext(wr,false);//由HttpWorkerRequest生成HttpContext
7}
8catch
9{
10
11//常见的400错误,就是在这里捕捉到滴
12wr.SendStatus(400,"BadRequest");
13wr.SendKnownResponseHeader(12,"text/html;charset=utf-8");
14byte[]bytes=Encoding.ASCII.GetBytes("
BadRequest");15wr.SendResponseFromMemory(bytes,bytes.Length);
16wr.FlushResponse(true);
17wr.EndOfRequest();
18return;
19}
20wr.SetEndOfSendNotification(this._asyncEndOfSendCallback,context);
21Interlocked.Increment(refthis._activeRequestCount);
22HostingEnvironment.IncrementBusyCount();
23try
24{
25try
26{
27this.EnsureFirstRequestInit(context);
28}
29catch
30{
31if(!
context.Request.IsDebuggingRequest)
32{
33throw;
34}
35}
36context.Response.InitResponseWriter();
37IHttpHandlerapplicationInstance=HttpApplicationFactory.GetApplicationInstance(context);
38//得到HttpApplication
39
40if(applicationInstance==null)
41{
42thrownewHttpException(System.Web.SR.GetString("Unable_create_app_object"));
43}
44if(EtwTrace.IsTraceEnabled(5,1))
45{
46EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER,context.WorkerRequest,applicationInstance.GetType().FullName,"Start");
47}
48if(applicationInstanceisIHttpAsyncHandler)
49{
50IHttpAsyncHandlerhandler2=(IHttpAsyncHandler)applicationInstance;
51context.AsyncAppHandler=handler2;
52handler2.BeginProcessRequest(context,this._handlerCompletionCallback,context);//届时HttpApplication处理请求
53}
54else
55{
56applicationInstance.ProcessRequest(context);
57this.FinishRequest(context.WorkerRequest,context,null);
58}
59}
60catch(Exceptionexception)
61{
62context.Response.InitResponseWriter();
63this.FinishRequest(wr,context,exception);
64}
65}
再看下GetApplicationInstance(context)实例化Application的方法
ViewCode
最后调用的GetNormalApplicationInstance方法中对当前空闲的application数目进行判断,调用
application.InitInternal(context,this._state,this._eventHandlerMethods)方法,
this.InitModules()初始化所有的Modules,包含用户自定义的HttpModules
this._stepManager.BuildSteps(this._resumeStepsWaitCallback);//管道事件序列
贴一下源码:
1internaloverridevoidBuildSteps(WaitCallbackstepCallback)
2{
3ArrayListsteps=newArrayList();
4HttpApplicationapp=base._application;
5boolflag=false;
6UrlMappingsSectionurlMappings=RuntimeConfig.GetConfig().UrlMappings;
7flag=urlMappings.IsEnabled&&(urlMappings.UrlMappings.Count>0);
8steps.Add(newHttpApplication.ValidatePathExecutionStep(app));
9if(flag)
10{
11steps.Add(newHttpApplication.UrlMappingsExecutionStep(app));
12}
13app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest,steps);
14app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest,steps);
15app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication,steps);
16app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest,steps);
17app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest,steps);
18app.CreateEventExecutionSteps(HttpApplication.EventPo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- HTTP 协议 IIS