ISAPI详细分析

ISAPI详细分析ISAPI 包括扩展和过滤器两种形式 都可以利用来开发动态动态 Web 内容 ISAPI 扩展和过滤器都以 DLL 形式实现 供 IIS 进程调用 扩展按规范必须实现两个函数接口 GetExtension HttpExtensio 和一个可选函数接口 TerminateExt 扩展和 Web 服务器中特定虚拟目录下的文件类型关联 可以和特定的文件后缀 比如 txt 关联 也

 ISAPI包括扩展和过滤器两种形式,都可以利用来开发动态动态Web内容。ISAPI扩展和过滤器都以DLL形式实现,供IIS进程调用。

  扩展按规范必须实现两个函数接口:GetExtensionVersionHttpExtensionProc和一个可选函数接口:TerminateExtension;扩展和Web服务器中特定虚拟目录下的文件类型关联,可以和特定的文件后缀,比如.txt关联,也可以使用通配符*和所有文件关联。比如ASP就是一个扩展,它的实现文件是asp.dll,.asp文件关联,客户端所有的对.asp文件的请求都将进入asp.dll扩展来处理。

  过滤器按规范也必须实现两个函数接口:GetFilterVersionHttpFilterProc和一个可选函数接口:TerminateFilter;过滤器分为站点级和全局级两种类型,前者只处理被装载的特定网站的事件,后者处理该IIS服务器上所有网站的事件。


ISAPI
扩展
ISAPI
扩展的可能用途

  IIS6.0之前的版本只有ISAPI过滤器能接收某特定URL的所有请求,但在6.0开始后ISAPI扩展也可以截获、改变、重定向或者拒绝对某特定URL空间的所有HTTP请求。现在ISAPI扩展基本可以实现所有过滤器的功能,并且运行得更快,效率更高。所以如非特别需要,微软推荐尽量少用过滤器。请参见过滤器用途。


ISAPI
扩展与IIS交互的典型流程


      
如果DLL不在内存中的时候,IIS装载DLL。装载DLLwindows自动调用DLL的进入,退出点函数DllMain。接着IIS调用扩展的进入点函数GetExtensionVersion。如果DLL已经装载到内存中则略过此过程。
IIS
对进入的请求做最小化预处理。
IIS
创建并填充一个EXTENSION_CONTROL_BLOCK结构来传输请求数据和回调函数指针到ISAPI扩展。
IIS
以一个为该次请求创建的EXTENSION_CONTROL_BLOCK结构指针为参数,调用ISAPI扩展的HttpExtensionProc函数。 
ISAPI
根据原始设计来完成处理工作:例如,从客户端读取更多数据(在一个POST操作中),或者写http头和数据返回客户端。
ISAPI
扩展退出HttpExtensionProc函数,通知IIS它完成了该次处理。对于同步操作,该函数返回HSE_STATUS_SUCCESS值;对于异步操作,返回HSE_STATUS_PENDING值。

如果Keep-Alive功能没有激活的话,当请求完成关闭连接后,IIS执行该次请求连接的相关清理工作。

如果ISAPI提供了TerminateExtension函数,一旦ISAPI扩展不再需要的时候,IIS调用TerminateExtension函数。如果IIS配置了缓存ISAPI扩展项,那么除非IIS服务器被关闭或重启,否则都不会调用TerminateExtension结束函数(IIS默认配置成缓存ISAPI扩展)。

注意:GetExtensionVersion函数不会每次请求时都调用,如果IIS配置了缓存ISAPI扩展选项,该函数将只调用一次。而对该扩展来说HttpExtensionProc函数则会在每次客户请求的时候被调用一次。


ISAPI
扩展的开发要点


ISAPI
扩展必须以DLL形式实现。
ISAPI
扩展必须实现两个接口函数GetExtensionVersion HttpExtensionProc;可选实现函数TerminateExtension
GetExtensionVersion
函数是进入点函数,在IIS装载该扩展时被调用一次。ISAPI扩展的初始化工作建议在GetExtensionVersion中进行,如内存分配,线程池创建,数据库连接等。也可以放在DLL的初始化函数DLLMAIN中,相关知识参见DLL初始化知识。
HttpExtensionProc
函数是功能处理进入点函数,每次有数据需要处理时会被IIS调用。这个函数接收一个EXTENSION_CONTROL_BLOCK数据结构,其中包含了要处理的数据,函数结束返回后也使用该结构和IIS通讯。
TerminateExtension
函数退出函数,当IIS卸载该DLL时被调用一次(如停止IIS),是可选实现,其中放置清理代码,如内存释放,线程池释放,数据库连接释放等。
ISAPI
扩展设计必须是线程安全的,必须处理线程同步问题,但在设计时需考虑性能问题,比如关键代码段等范围尽量小。另外在DLL的进入点和退出点DllMain函数中避免使用同步算法,比如windowswaitfor…等函数。
ISAPI
扩展中你可以创建自己的工作线程池。这个功能只有ISAPI扩展支持。
ISAPI
扩展支持异步操作。IIS支持异步读和写,所以ISAPI扩展推荐使用异步操作,这样可以最大限度利用CPU和工作线程池等。

注意 

必须牢记服务器是启动多线程来处理同时接收到的多个请求的,所以ISAPI处理函数必须是线程安全的。

IIS配置了缓存ISAPI扩展后(默认配置),GetExtensionVersion函数只会调用一次,所以初始化代码可放置在此处,如果没有配置该项就会多次调用。

ISAPI扩展中可以异步读写,可以创建自己的线程池


ISAPI
扩展的安装(以IIS6.0为例)



Dll文件拷贝到相应的虚拟目录。

IIS管理器中的“web服务扩展中增加该扩展,并允许。

 IIS 管理器中,展开本地计算机,展开网站文件夹,右键单击所需的网站或虚拟目录,然后单击属性

单击相应的选项卡:主目录虚拟目录、或目录

应用程序设置区域中,单击配置,然后单击映射选项卡。

选择应用程序扩展或通配符扩展。 

映射选项卡上,单击添加(应用程序扩展)或插入(通配符扩展)。

可执行文件文本框中键入 DLL 的路径或单击浏览以找到该文件,如果该 DLL 文件是脚本引擎,选择应用程序引擎复选框,然后单击确定

要编辑或删除通配符应用程序映射,请进行以下操作: 

应用程序扩展列表中,单击想更改的脚本映射。

单击编辑更改脚本映射,或单击删除删除脚本映射。

要更改通配符应用程序执行的顺序,在通配符应用程序映射(执行顺序)框中重新安排通配符应用程序映射,其方法是单击上移下移按钮直到符合您想要的顺序为止。

注意:请不要在通配符应用程序映射列表中多次列出同一应用程序。

简单ISAPI扩展示例代码


ISAPI
过滤器
ISAPI
过滤器的可能用途



改变客户端发送的请求数据(URL和头)。

控制URL映射到那个具体的物理文件。

控制匿名和基础认证时使用的用户名和密码。

认证完成后修改或分析一个请求。

修改一个返回到客户端的相应。

当出现访问拒绝应答时执行相应处理。

当一个请求完成后,执行一些处理。

当客户端连接被关闭后,执行一些处理。

记录特别日志或交互分析。

执行普通认证。

处理加密和压缩。


ISAPI
过滤器与IIS交互的典型流程

IIS初始化装载一个ISAPI过滤器,它同时创建并部分填充一个HTTP_FILTER_VERSION结构。接着它调用过滤器的GetFilterVersion函数,并传输一个指向该内存的指针为参数。
ISAPI
过滤器用版本信息和描叙信息填充HTTP_FILTER_VERSION结构。最重要的是过滤器也利用该结构来定义它接收的感兴趣的通知事件,并申明过滤器的通用优先级。另外,过滤器也在此时表明它是否只对安全端口事件感兴趣或只对非安全端口事件感兴趣,或者两者都有。

在客户端浏览器和IIS服务器之间的每一次交互过程中会产生很多不同的时间。每次当一个已经注册的过滤器事件出现的时候,IIS就会调用该过滤器的HttpFilterProc进入点函数。如果多个过滤器注册个该事件,IIS将通知所有感兴趣的过滤器,通知将按照高、中、低优先级顺序来排序。如果多个过滤器申明了同一个优先级,IIS将根据过滤器在FilterLoadOrder属性中出现的顺序来通知。
ISAPI
过滤器利用IIS传输给HttpFilterProc参数中的通知类型来判断pvNotification参数指向的实际数据是什么。然后根据上下文结构内容HTTP_FILTER_CONTEXT,来做一些通用处理。

一次处理完成后,过滤器返回SF_STATUS状态中的一个给IIS,接着IIS继续处理HTTP请求和应答,知道该过滤器感兴趣的另一个通知事件出现。

Web服务被停止或卸载时,IIS调用过滤器提供的TerminateFilter函数,多数过滤器都提供改函数的实现。TerminateFilter经常用于清理和释放已分配的资源。

注意:GetFilterVersion函数确定只有在初始装载过滤器时才被调用一次。如果开发者想做每次连接的初始化工做就应该在HttpFilterProc的上下文中处理。


ISAPI
过滤器的开发要点


ISAPI
过滤器必须以DLL形式实现
ISAPI
过滤器必须提供GetFileVersionHttpFilterProc函数,TerminateFilter函数是可选实现。
GetFileterVersion
函数中需要提供版本信息和注册感兴趣的时间,在IIS装载该DLL时被调用一次,过滤器的初始化代码可放在此函数中进行。或放在dll的初始化函数DllMain中进行。
HttpFilterProc
是事件处理进入点函数,当有该过滤器感兴趣的事件时,IIS会调用该函数。
TerminateFilter
该函数在IIS卸载该过滤器时被调用(如停止IIS时),是可选实现。过滤器的清理代码可以放在此处。

过滤器事件列表事件 出现时间
SF_NOTIFY_READ_RAW_DATA Occurs when data is being read from the client. May occur more than once per request.
SF_NOTIFY_PREPROC_HEADERS Occurs immediately after IIS has pre-processed headers, but before IIS has begun to process header content.
SF_NOTIFY_URL_MAP Occurs after IIS has translated a URL to a physical path on the server.
SF_NOTIFY_AUTHENTICATION Occurs just before IIS authenticates the client.
SF_NOTIFY_ACCESS_DENIED Occurs just after IIS has determined that access is denied for the requested resource, but before IIS has sent a response to the client.
SF_NOTIFY_SEND_RESPONSE Occurs after the request has been processed by IIS, but before any headers are sent back to the client.
SF_NOTIFY_SEND_RAW_DATA Occurs as IIS sends raw data back to the client. May occur more than once per request.
SF_NOTIFY_END_OF_REQUEST Occurs at the end of the request.
SF_NOTIFY_LOG Occurs at the end of a request, just before IIS writes the transaction to the IIS log.
SF_NOTIFY_END_OF_NET_SESSION Occurs when the network session with the client is ending.









ISAPI过滤器安装(以IIS6.0为例)



 IIS 管理器中,展开本地计算机,右键单击要添加筛选器的 Web 服务器或网站,然后单击属性

单击“ISAPI 筛选器选项卡,然后单击添加 

注意 如果将筛选器添加到网站,您将无法看到从 Web 服务器的主属性继承的全局筛选器。而只能看到为网站安装的筛选器,尽管这两组筛选器都在运行。

筛选器名称文本框中,键入筛选器的名称。

可执行文件文本框中,键入 DLL 文件的名称或单击浏览以找到该文件,然后单击确定

单击向上或向下箭头以更改筛选器的装载顺序。 

注意:只能更改具有相同优先级的筛选器的加载顺序。

如果已经添加或更改了全局筛选器,则必须终止并重新启动 Web 服务器以便将新筛选器加载到内存中。在网站级别添加的筛选器将在添加时自动加载。

注意:如果 HTTP 请求触发了一个筛选器已注册的事件,则筛选器将接收包含在请求中的数据,无论该请求是针对文件、CGI 应用程序或是 ISAPI 扩展。



ISAPI过滤器的调用顺序

  当几个筛选器注册给同一事件时,将按顺序对其进行调用。优先级较高的筛选器在优先级较低的筛选器之前运行。如果几个筛选器的优先级相同,则在主属性中设置的全局筛选器将在站点级别设置的筛选器之前运行。在同一继承级别具有相同优先级的筛选器将根据其加载顺序运行。可以通过调整 Web 服务器或网站的属性来改变筛选器的加载顺序。

简单ISAPI过滤器示例代码



客户端请求的路由过程



传入的请求由安装在根网站上的任何现有的 ISAPI 过滤器处理。ISAPI 过滤器依次执行。

请求被发送到任何现有的通配符应用程序映射的应用程序,这些程序也是依次执行的。如果传入的请求是对虚拟目录中的 Web 文件进行请求的,且通配符应用程序映射已安装在了该虚拟目录和根网站上,那么只有安装在该虚拟目录的通配符应用程序映射才被执行。如果该虚拟目录上没有安装通配符应用程序映射,则将执行安装在网站上的通配符应用程序映射。换句话说,通配符应用程序映射只在所请求的 Web 文件所处的应用程序中不存在映射时才会被继承。
IIS 
服务器会查看应用程序映射表,以确定由哪个 ISAPI 应用程序或 CGI 脚本专门处理所请求的文件。

每个阶段都可以附加响应,然后传回给客户端。


ISAPI
扩展、过滤器和Asp.dll的关系


Asp.dll
是一个典型的应用程序扩展。

扩展可以针对虚拟目录层次,过滤器只能到网站层次。

每个虚拟目录中一种类型的后缀文件只能映射一个应用程序扩展,如.asp文件只能映射asp.dll扩展。

针对每个虚拟目录可以设置多个通配符扩展,统配付扩展按优先级在应用程序扩展之前执行。

过滤器是事件驱动,根据注册的事件种类不同,调用的时机也将不一样,可以在通配符扩展、应用程序扩展(包括asp.dll)之前也可以在之后被调用。请参见过滤器事件列表。


ISAPI
扩展和过滤器比较

相同点


两者都可以达到很多相同的目的。

因为IIS处理客户端请求是多线程的,所以两者的处理函数入口都是多线程,处理函数都必须是线程安全的。

都以DLL形式实现,一般都导出三个规定的接口函数。

都被IIS统一调度,扩展IIS的功能。

从实现上来说,在两者的DLL中都可以创建自己的工作线程,但由于扩展支持异步操作所以能最大限度发挥多线程的作用。

不同点

过滤器只访问头,不能访问请求主体。

过滤器只能在每个站点配置,而不能在每个虚拟目录配置;而扩展可以。

过滤器不应包含长期运行的操作,因为 ISAPI 过滤器是同步进行的;而扩展支持异步操作。

过滤器灵活性较小,因为 ISAPI 过滤器 API 的功能比 ISAPI 扩展 API 少,后者用于编写 ISAPI 应用程序。

过滤器在时间上难以管理。

过滤器是事件驱动的。

扩展可以显式调用,比如:http://Server_name/asp.dll/test.asp;过滤器不可以。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221341.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午6:21
下一篇 2026年3月17日 下午6:21


相关推荐

  • 字符串匹配(多模式匹配篇)「建议收藏」

    字符串匹配(多模式匹配篇)「建议收藏」字符串匹配(多模式匹配篇)摘要:问题的提出:众所周知,KMP算法在O(n)的时间中solve单模式串匹配问题。但怎样solve多模式串匹配问题呢?Solve:本文用简要记叙了使用trie树,trie图(AC自动机)solve该问题的方法。关键字:字符串,多模式串匹配,trie树,trie图,AC自动机。前言:KMP算法是一种极其优秀的单模式串匹配算法,它通过前缀函数fail来减少匹配次数,以达到O…

    2022年8月21日
    9
  • java工程师简历模板下载待遇_项目工程师简历模板

    java工程师简历模板下载待遇_项目工程师简历模板可以到我的知乎主页(更多详细内容等你关注呦):https://www.zhihu.com/people/xing-chen-you-guang-pie-pie-pie有更多更详细的项目视频、文档、软

    2022年8月5日
    7
  • 解决numpy.core._exceptions.UFuncTypeError: ufunc ‘add‘ did not contain a loop with signature matchin问题

    解决numpy.core._exceptions.UFuncTypeError: ufunc ‘add‘ did not contain a loop with signature matchin问题

    2021年7月13日
    227
  • JAVA string转map_java怎么转业务

    JAVA string转map_java怎么转业务String转Mapstring转map的时候,很多新人可能不会去判断string的内容是什么格式的,因为map是key-value格式的,但是string就是一个字符串,想想,这个应该不能转吧,我就遇到过,想想就觉得自己傻傻的,哈哈哈。看代码 Stringcontent=””;HashMap<String,Object>map=newHashMap<>();try{map=JS

    2025年10月24日
    5
  • CPU降温软件测试自学,CPU降温软件真的有用吗工作原理是什么

    CPU降温软件测试自学,CPU降温软件真的有用吗工作原理是什么CPU 温度是一个很重要参数 我们都会采取物理和软件等方法对 CPU 降温 不过也有网友怀疑了 这些软件真的能让 CPU 降温吗 具体情况一起看看 CPU 降温软件真的有用吗如果要让 CPU 在不需要使用的时候休息 那么就得设计并安装一套 CPU 控制软件在操作系统中 并让它取得最优先的权限 接下来它需要不断地监视 CPU 的外来指令 也就是呼叫 CPU 工作 如果没有 那么它会呼叫一个 HLT 指令 此项指令就是使 CPU 进入

    2026年3月26日
    2
  • 快速导出PDF文件中所有图片(使用Adobe Acrobat 10 )「建议收藏」

    快速导出PDF文件中所有图片(使用Adobe Acrobat 10 )「建议收藏」1、用AdobeAcrobat XPro打开一个含有图片的PDF2、点击工具->文档处理->导出所有图像,这样就完成了对PDF文件中所有图片的导出。如果没看到“文档处理”,可以点击下图右上角按钮,选中文档处理即可;导出图片时最好选择一个文件夹,以免默认导出的图片扑满整个桌面。导出图像存放位置设置:导出结果如下图所

    2022年5月8日
    585

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号