每个ISAPI过滤器DLL必须输出两个供IIS使用的函数:
GetFilterVersion()和HttpFilterProc()。下面分别讲述。
GetFilterVersion()
用于初始化和处理事件的登记。例程没有初始工作要做,只是简单的登记了要处理的两个事件和其他一些标志。
function GetFilterVersion(var pVer:
THTTP_FILTER_VERSION):BOOL;stdcall;
begin
//过滤器要处理的事件和其他一些标志
pVer.dwFlags:=(
SF_NOTIFY_NONSECURE_PORT
//过滤器只在一般端口上使用
or SF_NOTIFY_SEND_RAW_DATA
//处理发送数据事件
or $80//SF_NOTIFY_END_OF_REQUEST
处理请求结束事件
or SF_NOTIFY_ORDER_DEFAULT
//过滤器使用缺省优先级
);
//过滤器使用的版本HTTP_FILTER_REVISION
返回当前版本
pVer.dwFilterVersion:=HTTP_FILTER_REVISION;
//过滤器的描述
pVer.lpszFilterDesc[0]:=’A’;pVer.lpszFilterDesc[1]:=#0;
result:=true;//初始化成功
end;
HttpFilterProc()
由IIS回调,是过滤器的实际处理部分。
其中参数Notificationtype是该调用的事件类型,如果过滤器处理多个事件,可以检查该值来区分事件。
PvNotification是一个根据事件类型可变结构的参数。对于SF_NOTIFY_SEND_RAW_DATA,他的结构如下:
THTTP_FILTER_RAW_DATA=record
pvInData:Pointer;//指向数据区
cbInData:DWORD;//数据大小
cbInBuffer:DWORD;//缓冲的大小
dwReserved:DWORD;//保留
end;
其中的pvInData就是要发送的数据指针。其他的结构请参看有关资料这里不再详述。
第一个参数var pfc:THTTP_FILTER_CONTEXT是过滤器的环境指针,其中的pFilterContext是一个用户使用的指针,用来保存和一个 HTTP连接相关的信息,这样过滤器可以区分出正在处理的是否是以前曾处理过的连接。因为一个请求将会产生多个 SF_NOTIFY_SEND_RAW_DATA事件,过滤器必须能够区分他们。
程序的流程是:当连接建立后,pFilterContext被IIS初始化为NIL(0),第一次SF_NOTIFY_SEND_RAW_DATA调用时,过滤器要检查返回的MIME,如果不是HTML则将pFilterContext置为pointer(2)(将指针当作变量用,因为我们只要一个标志),随后的发送事件调用将直接返回。请求结束后,发生SF_NOTIFY_END_OF_REQUEST事件,过滤程序将pFilterContext 复位为nil。
如果是HTML,则将pFilterContext置为pointer(1),随后的调用就将对数据进行内码的转换,然后将 pFilterContext置为pointer(3)。如果还有后续的调用,则再将pFilterContext置为pointer(1),直到全部数据发送完成。