一.ISAPI简介
ISAPI(Internet Server Application Programming Interface)是Microsoft推出的运用在IIS内的一类基于HTTP协议的编程接口。通常将开发出的ISAPI应用模块称为ISA。简单地说,ISAPI是IIS提供的CGI替代技术。当然,ISAPI也可被认为是一种改良的CGI技术。ISAPI应用一般被开发为.dll的进程内DLL(In-process DLL),这使ISAPI应用的各实例在运行时同HTTP server位于相同的进程空间,所以各个ISAPI应用实例可以透明地访问HTTP server输出的资源。同传统的CGI相比,ISAPI应用具有更小的负荷。因为ISAPI应用在启动时无须申请创建自己的进程,而只需绑定到HTTP server的进程空间,所以其启动过程的速度要比传统的CGI程序快得多。从另一方面讲,ISAPI应用由于具有进程内属性,所以在其访问HTTP server的资源时,无须跨进程边界,这也使其运行效率大大提高。此外,IIS在管理进程内的线程时,实现了线程池(thread-pool)机制,这使ISAPI应用各实例的创建、释放和相应的资源分配更为有效。
ISA被分为两种类型:ISAPI Server Extension和ISAPI Filter。其中,ISAPI Server Extension可实现通常CGI程序的功能;而ISAPI Filter则可为IIS提供附加的功能。ISAPI Filter
在Web server启动时被启动,在Web server停止时被卸载。用户对Web server的请求均会先通过ISAPI Filter过滤,而Web server返回浏览器的内容也会首先经ISAPI Filterwebserver接口开发过滤。由此可见,若要实现自定义的访问授权机制、数据压缩、数据加密和做日志等功能时,ISAPI Filter是一个合适的接口。
二.开发ISAPI Server Extension应用步骤
下面的例子描述了使用MFC和ISAPI Extension Wizard开发ISAPIServerExtension。
1.创建工程
⑴标识Project Name为ISASample,确定存储路径。选择ISAPI Extension Wizard,点击OK按钮。
⑵完成ISAPI Extension Wizard提供的各个选项,完成工程的创建。
2.探索ISAPI Extension Wizard生成的文件
ISAPI Extension Wizard自动生成了ISASample.cpp、ISASample.h、ISASample.DEF、IS
ASample.RC、Resource.h、StdAfx.cpp和StdAfx.h等一系列文件。
⑴ISASample.h是CISASampleExtension类的声明。CISASampleExtension类的基类是MFC类库所提供的CHttpServer。基类CHttpServer被用作创建和管理ISAPI serverextensionDLL。我们的开发任务主要是通过CHttpServer的派生类CISASampleExtension来完成的。
⑵生成的ISASample.DEF具有如下的定义:
LIBRARY"ISASAMPLE"
EXPORTS
HttpExtensionProc
GetExtensionVersion
TerminateExtension
以上的ISASample.DEF文件中定义了DLL将要输出的3个函数:HttpExtensionProc、GetExtensionVersion和TerminateExtension。程序员可以重写这些被派生来的成员函数内容。Web server在接到ISA的调用请求时将调用HttpExtensionProc方法,HttpExtensionProc可以通过回调函数读取用户数据并完成其他功能。GetExtensionVersion可用来获得ISAPIserverextensionDLL的版本号。GetExtensionVersion及HttpExtensionProc均在CHttpServer中有默认的实现。TerminateExtension为卸载提供了一个安全的途径。
3.定义parsemap
⑴什么是parse map?
通过parse map,可以将用户(浏览器)请求映射到CISASampleExtension类的成员方法。顺便提一句,别忘了CISASampleExtension类是从CHttpServer类派生出来的。MFC为ISAPI的parse map定义了一套宏,具体描述请参阅附表。
⑵声明parse map
在ISASample.cpp中完成下列代码:
BEGIN_PARSE_MAP(CISASampleExtension,CHttpServer)
//TODO: insert your ON_PARSE_COMMAND() and
//ON_PARSE_COMMAND_PARAMS() here to hookup your commands.
//For example:
ON_PARSE_COMMAND(ShowHello,CISASampleExtension,ITS_PSTRITS_PSTRITS_I4)
ON_PARSE_COMMAND_PARAMS("Name City ID")
ON_PARSE_COMMAND(Default,CISASampleExtension,ITS_EMPTY)
DEFAULT_PARSE_COMMAND(Default,CISASampleExtension)
END_PARSE_MAP(CISASampleExtension)
上面的声明使ISASample.dll具有一个命令ShowHello和一个默认命令。在调用ShowHello命令时,共有3个参数,分别为Name、City和ID。ITS_PSTR标识参数类型为字符串,而ITS_I4标识参数类型为long。有关常数所代表的数据类型请参见MSDN。
⑶实现命令
默认的命令Default已被ISAPI Extension Wizard自动生成,如果需要修改或去掉Default命令,可以对DEFAULT_PARSE_COMMAND宏及ISASample.h与ISASample.cpp中域Default成员函数有关的代码做出相应修改或删除。为了实现ShowHello命令,首先需要在类CISASampleExtension中声明成员ShowHello。请在ISASample.h中声明公共的成员函数ShowHello如下:
void ShowHello(CHttpServerContext* pCtxt,LPCSTR pstrName,LPCSTR pstrCity,LONG lID);
该函数代码如下:
void CISASampleExtension::ShowHello(CHttpServerContext* pCtxt,LPCSTR pstrName,L
PCSTR pstrCity,LONG lID)
{
StartContent(pCtxt);
WriteTitle(pCtxt);
*pCtxt<<_T(“<tableborder=1>”);
*pCtxt<<_T(“<tr><td>Name</td>”);
*pCtxt<<_T(“<td>”)<<pstrName;
*pCtxt<<_T(“</td></tr>”);
*pCtxt<<_T(“<tr><td>City</td>”);
*pCtxt<<_T(“<td>”)<<pstrCity;
*pCtxt<<_T(“</td></tr>”);
*pCtxt<<_T(“<tr><td>ID</td>”);
*pCtxt<<_T(“<td>”)<<lID;
*pCtxt<<_T(“</td></tr>”);
*pCtxt<<_T(“</table>”);
}
⑷配置ISASample.dll
用Build命令生成ISASample.dll后再将其拷贝到具有Read
和Execute权限的Web发布目录下。下面的HTML文档片段使用HTML文档中的FORM来引用ISASample.dll的ShowHello命令。
<FORM ACTION="Eric_Notebook/scripts/ISASample.dll"METHOD=POST>
<INPUT TYPE=HIDDEN NAME="MfcISAPICommand"VALUE="ShowHello">
Input your name:<br><INPUT NAME="Name"VALUE="Anonymous"><br>
Input the city in which you live:<br>
<INPUT NAME="City"VALUE="Unknown">
<br>Input your ID number:<br>
<INPUT NAME="ID"VALUE=0><br>
<INPUT TYPE=SUBMIT VALUE="CallISASample.dll">
</FORM>
附表:
宏 | 描述 |
BEGIN_PARSE_MAP | 标识开始parsemap定义。 |
ON_PARSE_COMMAND | 标识一个命令,即所要映射的成员函数。 |
ON_PARSE_COMMAND_PARA | MS定义命令的参数列表。这个宏必须紧接在ON_PARSE_COMMAND宏之后。这里的参数是指从浏览器传过来的各参数(即FORM域中各项的值)。 |
DEFAULT_PARSE_COMMAND | 表示默认的命令。 |
END_PARSE_MAP | 标识结束parsemap定义。 |
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论