問:如何創建一個ISAPI Filter工程?
答:Vc++6.0->工程->ISAPI Extension Wizard 然後根據嚮導提示和自己的實際需求,一步一步進行
要注意的地方:
你希望創建什麼類型的IIS對象?我們應該選"產生一個過濾器對象"
你的過濾器擁有的通知優先級?根據自己的需要,如果向讓我們的程序最先處理客戶的請求就要選擇"高"
你的過濾器將處理那些通知?一般選擇“URL映射請求”
問:我的處理代碼應該加在什麼地方?
答:一般放在OnUrlMap函數中(這與上面的選擇有關係)
問:如何取得客戶端請求的URL?
答:在OnUrlMap函數中使用pMapInfo->pszURL即可獲得,類型char *
問:如何取得HTTP請求報文中的參數?
答:在OnUrlMap函數中使用pCtxt->GetServerVariable(LPTSTR ,LPVOID,LPDWORD )即可取得,該函數的原型如下:
GetServerVariable( LPTSTR lpszVariableName, LPVOID lpvBuffer, LPDWORD lpdwSize )
簡單解釋一下參數,
參數(1) lpszVariableName-要取得的參數的名稱,例如"ALL_HTTP",將取得所有客戶發送的HTTP請求頭;"QUERY_STRING",取得客戶端以Get方式提交的參數。至於其它的,可以到MSND中查閱,裏面有詳細的說明。
參數(2) lpvBuffer-接收緩衝區,存放取得的參數的緩衝區。
參數(3) lpdwSize-函數成功調用後,該參數存放成功獲取的參數的字節數。
問:如何向客戶端輸出HTML?
答:在OnUrlMap函數中使用pCtxt的WriteClient方法即可實現,函數原型如下:
BOOL WriteClient( LPVOID lpvBuffer, LPDWORD lpdwBytes, DWORD dwReserved = 0 );參數不解釋了,大家可以望文生義。
問:如何重定向客戶的請求?
答:看個例子,自然明白
//將用戶請求的URL重定向到http://www.baidu.com/
char szRedirect [256];
sprintf(szRedirect, "Location: http://%s/r/n/r/n", "www.baidu.com");
pCtxt->ServerSupportFunction ( SF_REQ_SEND_RESPONSE_HEADER, (LPVOID) "302 Redirect", (DWORD *) szRedirect,0 );
補充一下,ServerSupportFunction這個函數可以實現修改向客戶端發出的HTTP報文頭信息,詳情,敬請查看MSDN
問:如何將寫好的程序(DLL),添加到IIS?
答:follow me,打開Internet信息服務管理,在需要保護的站點上點擊鼠標右鍵,打開屬性頁,切換到ISAPI篩選器標籤,然後,添加即可。
問:我寫的篩選器怎麼在沒有安裝VC++的機器上不工作?
答:以release方式發佈即可
Ok,總結完了。我就知道這麼多了。最後再把我最近寫的一個程序附上,僅供參考:
先說一下這個過濾器實現的功能:防數據庫被下載,防SQL注入
//水品有限,不當之處還望高手指出:
DWORD CSafeWebFilter::OnUrlMap(CHttpFilterContext* pCtxt,
PHTTP_FILTER_URL_MAP pMapInfo)
{
//By RedIce 2008.4.12
char c_url[256];//客戶端請求的URL
char c_VariableName[256];
char c_exten[5];
char c_response[256];
DWORD response_len;
unsigned long l_Variable_len;
memset(c_VariableName,0,256);
//取得客戶端請求的參數
pCtxt->GetServerVariable("QUERY_STRING",c_VariableName,&l_Variable_len);
//如果請求的URL(包括參數)過長則給做警告
if(strlen(pMapInfo->pszURL) +strlen(c_VariableName)>=256)
{
memset(c_response,0,256);
sprintf(c_response,"<p align=center><font color=red>注意:客戶端請求的URL過長!</font>");
response_len=strlen(c_response);
pCtxt->WriteClient(c_response,&response_len);
return SF_STATUS_REQ_FINISHED;
}
memset(c_url,0,256);
strcpy(c_url,pMapInfo->pszURL);//取得客戶端請求的URL
if(strlen(c_VariableName)) strcat(c_url,"?");
strcat(c_url,c_VariableName);//將用戶請求的URL和參數連接起來
strlwr(c_url);//將url中所有字母轉換爲小寫
memset(c_exten,0,5);
strcpy(c_exten,&c_url[strlen(c_url)-4]);
//防數據庫被下載
if(!strcmp(c_exten,".mdb"))
{
memset(c_response,0,256);
sprintf(c_response,"<p align=center><font color=red>注意:你沒有訪問該資源的權限!</font>");
response_len=strlen(c_response);
pCtxt->WriteClient(c_response,&response_len);
return SF_STATUS_REQ_FINISHED;
}
//防SQL注入
if(strstr(c_url,"'")||
strstr(c_url,";")||
strstr(c_url,"select")||
strstr(c_url,"where")||
strstr(c_url,"count")||
strstr(c_url,"update")||
strstr(c_url,"insert")||
strstr(c_url,"delete")||
strstr(c_url,"and")||
strstr(c_url,"exec"))
{
memset(c_response,0,256);
sprintf(c_response,"<p align=center><font color=red>注意:你提交的URL中含有非法參數!</font>");
response_len=strlen(c_response);
pCtxt->WriteClient(c_response,&response_len);
return SF_STATUS_REQ_FINISHED;
}
// TODO: React to this notification accordingly and
// return the appropriate status code
return SF_STATUS_REQ_NEXT_NOTIFICATION;
ISAPI開發心得
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.