ISAPI開發心得

 
問:如何創建一個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;

發佈了66 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章