用ISAPI看ASP的实现

来源:互联网 发布:淘宝请大师请的情蛊 编辑:程序博客网 时间:2024/05/01 17:36

 

ISAPIASP的实现

一.        前言

 

IASPIIIS的的扩展接口,可以用它来实现动态网页。ASP就是使用ISAPI实现起来的一个扩展程序。本文是在了解了ISAPI技术后,来思考ASP是如何实现的。

 

 “假如我做,我该如何实现”,每个程序员在了解了一个程序的功能和原理之后都会有这种想法。本文就是基于这样的想法。注意:并没有参考源码,仅是思考和假设。

 

二.        ISAPI

 

ISAPI是一种IIS服务器上的一个API标准。它分为ISAPI扩展和ISAPI过滤。前者读者可以参看本人翻译的《什么是ISAPI?》;后者读者可以找文章自行学习。

 

我们知道ISAPI是通过DLL来实现的。对于ISAPI扩展程序,它的DLL只要导出三个函数:GetExtensionVersionHttpExtensionProcTerminateExtension(可选)。

 

将编译好的DLL文件(假设为test.dll)拷贝至制定目录,然后在浏览器中直接调用http://localhost/test.dll便可以调用这个ISAPI程序了。还有一个方法,我们可以在IIS中定义好映射:将扩展名映射到ISAPI扩展程序中。例如:

我们看到.asa.asp文件映射到asp.dll文件。asp.dll也是一个ISAPI扩展程序。它是ASP技术的核心。

 

三.        ASP

 

ASPActive Server Pages ISAPI扩展程序(ASP.DLL)。ASP这个扩展程序到底有什么功能?它们是怎样实现的呢?

ASP提供了几个内置对象:ApplicatonSessionRequestResponseServer。下面我们来详细了解它们是如何实现的。

 

1.  Application

 

我们可以把IIS的虚拟目录或者物理目录设置成“应用程序”。如下图:

 

一个“应用程序”包括本目录下的所有文件、所有的文件夹、所有子文件夹……直到下一个应用程序。

 

对于静态网页的而言,文档是否置于“应用程序”以及置于何“应用程序”都是无关紧要的;但对于动态网页就大大不同了。同一“应用程序”下的网页可以共享信息。它就像EXE应用程序中的全局变量一样,所有的函数/过程都可以访问存取它。

 

我们知道什么是应用程序以及它有什么作用了,那么ASP.DLL是如何实现的呢?

 

其实很简单:IIS将它的所有配置保存在Metabase.bin文件中(IIS6将它的配置保存在两个文件中)。ISAPI可以在HttpExtensionProc中调用GetServerVariable(APPL_MD_PATH / APPL_PHYSICAL_PATH)来获得目前的“应用程序”信息。

 

ASP.DLL 在某个“应用程序”第一次调用时,会分配一个内存块,然后执行这个程序虚拟目录下的Global.asa文件中的事件。这块内存直到服务停止会一直存在的。

 

为了标识这个“应用程序”的用户连接,ASP.DLL会生成一个ASPSESSIONIDCookies值返回给浏览器。和其它所有没有Expires属性的Cookie一样:该Cookie是不会保存在用户硬盘上的,它只是被保存在浏览器的内存中的:当窗口关闭时,Cookie便没有了。但是,若用户使用Ctrl+N打开一个新的浏览器窗口,Cookie值是会被继承的。

 

当一个访问请求到达时,IIS会检查该请求中是否包含合法的ASPSESSIONID值。若没有则生成一个新的ASPSESSIONID返回给浏览器。

 

除非服务器重新启动,否则ASP.DLL会一直认为ASPSESSIONID有效的——ASP.DLL会以为用户浏览器是一直打开着的。这个漏洞会被一些不法分子利用,他们会使用浏览器已经关闭了的ASPSESSIONID来劫持会话。

 

还要注意的是:IIS下的不同“应用程序”对同一连接(同一浏览器窗口)生成不同的ASPSESSION

 

2.  Session

 

HTTP协议是一个无状态的协议。ASP使用了会话对象Session为每个不同用户在服务器中保存状态信息。Session的核心是一个内存块,它有两个属性:

 

1)              timeout时间值。对于一个连接,若在这个时间段内不访问这个“应用程序”下的任何网页,则这个Session便过期了——所有以前保存的信息被删除,以后也不能被使用,只能重新分配。

 

2)              SessionID值。ASP.DLL给每个新生成的Session分配一个连续的唯一的序列号。有很多人将这个SessionID值和ASP.DLL返回给浏览器的ASPSESSIONID混为一谈,这需要详细说说。

 

上文说过,ASPSESSIONID是用来标识一个用户连接的,而SesssionID用来表示一个有效的会话的。ASP.DLL将每个ASPSESSIONIDSessionID对应起来,表示:在一个时间段内,ASPSESSIONID连接用户只能访问SessionID的会话内存块

 

因为这两者的生存期是不同的:ASPSESSIONID直到服务器重新启动;而SessionID直到timeout到期。当timeout到期时,会话被删除了,于是对应关系就没有了。若再用以前的ASPSESSIONID再来访问时,由于没有对应的SessionIDASP.DLL会重新分配一个会话(这样就得到一个新的SessionID)来对应,但是ASPSESSIONID是不用更新的。

 

下面的流程图是ASP.DLL对每个访问连接进行的检查:

3.  其他对象

 

上面说的两个对象是ASP比较难于理解的。而其他的像RequestResponse对象基本上都是直接调用ISAPIHttpExtensionProc中的变量和函数,比较易于实现,读者可以自行思考。

 

四.        总结

本文是我在知道了ISAPI之后对ASP实现的一些想法。希望对大家理解ASP原理有点帮助。

 

 
原创粉丝点击