ネタ元1: [ISAPI] : VS2005/2008 用 - MFC利用の「ISAPI Filter & Extension」テンプレートはどこにある? ( けろ-みお のブログ)
ネタ元2: ISAPIフィルターで環境変数を設定する方法について (techbank.jp の掲示板)
以前もこのネタを取り上げたんですが、先日、techbank.jp掲示板の方で、
「(けろ-みおさんの回答は)MFCを利用しているからうまくISAPI Filterが作れない」と言われました。
WINAPIで作ってもMFCで作っても関数プロトタイプ自体に大きな差異がないため、本質を理解していれば、
普通に作れるはずなんですが、不慣れな方から見ると、簡単な理屈ではいかないようです。。。
しかも、Visual Studio 2005 からは、ISAPIを作成するためのテンプレートやプロジェクトファイル作成用の
ウィザードが無くなっちゃいましたし。
気持ちはわからないでもないですが、
「MFCを利用しているからISAPI Filterが作れない」と言われるのは、二度と御免なので、
「Visual Studio 2005用のMFC版 ISAPI Filter テンプレートファイル」を今回ご用意させて頂きました。
下記からダウンロードできます。
入手先:
http://techbank.jp/Community/files/folders/sample/entry13950.aspx
上記をご利用頂くと、ビルドオプションやプロジェクトの設定が不要になり、コーディング作業だけに集中することができます。
また、プロジェクトファイルだけではなく、処理に必要なすべての通知タイプ
( Header読み込み、URL解析、認証時、リクエスト完了時、レスポンス完了時、セッション終了時、ログ出力時等の通知イベント)に対して、
簡単に処理が記述できるようソースファイルもある程度、テンプレート化させて頂きました。
■定義した通知タイプ(MFC_ISAPI_FilterProc.cpp)
#include "StdAfx.h"
#include "MFC_ISAPI_Filter.h" // ISAPI Filter定義用
// 通知データの処理
DWORD CIsapiFilter::HttpFilterProc(HTTP_FILTER_CONTEXT *pfc, DWORD dwNotificationType, LPVOID pvNotification)
{
DWORD ret;
switch(dwNotificationType)
{
// HTTPヘッダの読み込みを開始した時
case SF_NOTIFY_READ_RAW_DATA:
// TODO: ここに必要な処理を記述してください
ret = OnReadRawData(pfc, (PHTTP_FILTER_RAW_DATA)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// HTTPヘッダの読み込みを完了した時
case SF_NOTIFY_PREPROC_HEADERS:
// TODO: ここに必要な処理を記述してください
ret = OnPreprocHeaders(pfc, (HTTP_FILTER_PREPROC_HEADERS *)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// URLの解析が完了した時
case SF_NOTIFY_URL_MAP:
// TODO: ここに必要な処理を記述してください
ret = OnUrlMap(pfc, (PHTTP_FILTER_URL_MAP)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// ユーザ認証要求を出した時
case SF_NOTIFY_AUTHENTICATION:
// TODO: ここに必要な処理を記述してください
ret = OnAuthentication(pfc, (PHTTP_FILTER_AUTHENT)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// ユーザ認証完了時
case SF_NOTIFY_AUTH_COMPLETE:
// TODO: ここに必要な処理を記述してください
ret = OnAuthComplete(pfc, (PHTTP_FILTER_AUTH_COMPLETE_INFO)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// 要求ヘッダをクライアントに送信する時
case SF_NOTIFY_SEND_RESPONSE:
// TODO: ここに必要な処理を記述してください
ret = OnSendResponse(pfc, (PHTTP_FILTER_SEND_RESPONSE)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// サーバーが生データをクライアントに送り返している時
case SF_NOTIFY_SEND_RAW_DATA:
// TODO: ここに必要な処理を記述してください
ret = OnSendRawData(pfc, (PHTTP_FILTER_RAW_DATA)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// サーバーにログを出力する時
case SF_NOTIFY_LOG:
// TODO: ここに必要な処理を記述してください
ret = OnLog(pfc, (PHTTP_FILTER_LOG)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// セッション終了時
case SF_NOTIFY_END_OF_NET_SESSION:
// TODO: ここに必要な処理を記述してください
ret = OnEndOfNetSession(pfc);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// アクセスに失敗した時、認証に失敗した時
case SF_NOTIFY_ACCESS_DENIED:
// TODO: ここに必要な処理を記述してください
ret = OnAccessDenied(pfc, (PHTTP_FILTER_ACCESS_DENIED)pvNotification);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// 要求が終了した時
case SF_NOTIFY_END_OF_REQUEST:
// TODO: ここに必要な処理を記述してください
ret = OnEndOfRequest(pfc);
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
// それ以外
default:
// TODO: ここに必要な処理を記述してください
// ISAPIの次の処理を実行する(TODO:戻り値は必要に応じて変更してください)
ret = SF_STATUS_REQ_NEXT_NOTIFICATION;
break;
}
// 戻り値
return ret;
}
ソースコード内に記載されている「TODO」コメントの欄に必要な処理をAddonしたり、
あるいは、不要な通知タイプを削除するだけで簡単にISAPI Filterを作成することができます。
(できるだけ使用しない通知タイプについてはGetFilterVersionのマスクを削除して頂きたいです。ISAPI Filterの動きが重くなるので・・・)
また、ISAPI Filter だけではなく、ISAPI Extension についても同様のものをいずれ用意したいと思いますので、
ご要望があればおっしゃってください。
※上記テンプレートに関して、作者は一切の責任を負いませんので、あくまで自己責任においてご利用下さい。
なお、WINAPI版については、[ISAPI] : VS2005/2008 用 - MFC利用の「ISAPI Filter & Extension」テンプレートはどこにある? でも
紹介した通り、「Windows Server 2003 SP1 Platform SDK Full Download」でサンプルコードを同梱していますので
そちらをご利用下さい。