看看下面的例子吧
转载自《计算机世界日报》 (文/林海)
作 为 一 个WWW 服 务 器 软 件, 微 软 公 司 的Internet Information Server(IIS) 简 单 易 学, 得 到 了 广 泛 的 使 用。 您 还 可 以 通 过ISAPI 过 滤 器, 自 己 定 制 处 理 来 增 强IIS 的 功 能。ISAPI 过 滤 器 可 以 定 制 以 下 的 处 理: 接 收HTTP 协 议 头 预 处 理、 发 送HTTP 协 议 头 预 处 理、 发 送 生 数 据 预 处 理、 获 得 生 数 据 预 处 理、HTTP 会 话 结 束 信 息 处 理、 自 定 义 的 安 全 认 证 机 制、URL 映 射 信 息 处 理、 日 志 记 录 处 理 等。 灵 活 利 用 这 些 定 制 处 理, 您 可 以 完 成 许 多 看 似 难 以 实 现 的 功 能, 得 到 意 想 不 到 的 效 果。 但 是ISAPI 过 滤 器 使 用 不 当 也 会 影 响 服 务 器 的 性 能。
----ISAPI 过 滤 器 的 开 发 非 常 简 单, 只 需 要 完 成 三 个 接 口DLL 函 数 即 可。 它 们 是GetFilterVersion()、HttpFilterProc()、 TerminateFilter(), 大 家 可 以 查 看MSDN 了 解 详 细 的 用 法。ISAPI 过 滤 器 是DLL 文 件, 一 般 用C/C + + 语 言 开 发。 为 使ISAPI 过 滤 器 能 够 运 行, 您 需 要 在 注 册 表 的 HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/
W3SVC/Parameters 下 建 立 一 个 字 符 串 项, 其 名 称 为“Filter Dlls”, 值 为ISAPI 过 滤 器 文 件 的 全 路 径 名 称。 若 这 个 字 符 串 项 已 经 存 在, 只 需 把 它 的 全 路 径 名 称 加 入 其 中, 不 同 的ISAPI 过 滤 器 文 件 之 间 用“;” 分 隔, 您 可 以 根 据 执 行 的 优 先 顺 序 加 在 适 当 的 位 置。 设 置 好 后 重 新 启 动IIS 服 务, 您 的ISAPI 过 滤 器 就 发 挥 作 用 了。
----下 面 举 二 个 具 体 的 应 用 例 子。
一、 虚 拟 主 机WWW 站 点 的 实 现
----所 谓 虚 拟 主 机WWW 站 点, 是 指 不 同 的 域 名 占 用 同 一 个IP 地 址, 各 自 拥 有 自 己 的 主 页。 这 样 您 可 以 在 同 一 台 机 器 上 为 几 个 甚 至 几 十 个 公 司 建 立 各 自 的WWW 站 点。IIS 3.0 不 提 供 虚 拟 主 机WWW 站 点 的 功 能, 但 是 我 们 可 以 通 过 ISAPI 过 滤 器 来 实 现 它。 其 原 理 是 通 过URL 映 射 信 息 处 理, 将 不 同 的 域 名 重 新 映 射 到 不 同 的 物 理 文 件。 下 面 是 它 的 源 程 序。
fmulti.def:
LIBRARY fmulti
EXPORTS GetFilterVersion
HttpFilterProc
TerminateFilter
fmulti.c:
#include
#include
#include
#include
#define baseroot “C://InetPub//wwwroot//"
BOOL WINAPI GetFilterVersion(HTTP_FILTER_VERSION *pVer)
{
pVer ->dwFilterVersion=HTTP_FILTER_REVISION;
strcpy(pVer ->lpszFilterDesc, “fmulti");
pVer ->dwFlags = SF_NOTIFY_URL_MAP |
SF_NOTIFY_ORDER_HIGH; / * 过 滤 的 内 容 */
return TRUE;
}
DWORD WINAPI HttpFilterProc(HTTP_FILTER_CONTEXT
*pfc, DWORD noteType, VOID *pvNote)
{
DWORD namelen = 256;
char svrname[256];
char phyfile[280];
*svrname = 0;
(pfc ->GetServerVariable)(pfc, “SERVER_NAME",
svrname, &namelen);
_strlwr(svrname);
strcpy(phyfile, ((PHTTP_FILTER_URL_MAP)pvNote)
->pszPhysicalPath + strlen(baseroot));
/ * 以 下 根 据 域 名 设 置 需 访 问 的 物 理 文 件 */
if (strcmp(svrname, “ca.best.net")==0) {
sprintf(((PHTTP_FILTER_URL_MAP)pvNote) ->
pszPhysicalPath, “C://InetPub//caroot// %s", phyfile);
}
else if (strcmp(svrname, “cb.best.net")==0) {
sprintf(((PHTTP_FILTER_URL_MAP)pvNote)
->pszPhysicalPath, “C://InetPub//cbroot// %s", phyfile);
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
BOOL WINAPI TerminateFilter(DWORD dwFlags)
{
return TRUE;
}
二、 对 访 问 内 容 进 行 统 计 分 析
----通 常 我 们 在 需 要 计 数 的 页 面 内 放 一 个 计 数 器, 或 者 使 用ASP 文 件 来 实 现 计 数 功 能。 这 种 方 法 不 能 适 用 于 如README.TXT 等 其 他 非HTML 格 式 的 文 件。 如 果 使 用IIS 的 日 志 功 能 又 太 占 用 空 间 而 不 方 便。 作 者 通 过 定 制URL 映 射 信 息 处 理 来 跟 踪 感 兴 趣 的 几 个 文 件 的 计 数 统 计, 将 结 果 记 录 在 一 个 文 件 中。 下 面 是 它 的 源 程 序。
fcount.def:
LIBRARY fcount
EXPORTS GetFilterVersion
HttpFilterProc
TerminateFilter
fcount.c:
#include < stdio.h >
#include < string.h >
#include < windows.h >
#include < httpfilt.h >
#define logfile “C://InetPub//fcount.log"
#define pages 5
char * urls[] = {
“/default.htm",
“/banner.gif",
“/product/readme.txt",
“/product/product1.htm",
“/product/product2.htm"
};
int counts[pages];
BOOL WINAPI GetFilterVersion
(HTTP_FILTER_VERSION *pVer)
{
int i;
pVer ->dwFilterVersion=HTTP_FILTER_REVISION;
strcpy(pVer ->lpszFilterDesc, “fcount");
pVer ->dwFlags = SF_NOTIFY_URL_MAP;
/ * 过 滤 的 内 容 */
for (i=0; ipszURL);
_strlwr(lurl);
for (i=0; i
----以 上 二 个 例 子 使 用VC 6.0 编 译, 在WIN NT 4.0 + SP3 和 IIS 3.0 上 调 试 通 过。