1. 程式人生 > >helonSY歡迎您的到來!

helonSY歡迎您的到來!

法,是由微軟和Process軟體公司聯合提出的Web伺服器上的API標準。ISAPI與Web伺服器結合緊
密,功能強大,能夠獲得大量的資訊,因此利用ISAPI可以開發出靈活高效的Web伺服器增強程式
。由於ISAPI程式與Web伺服器的關係,使得ISAPI介面在安全方面有一定的研究價值。本文主要
討論ISAPI在IIS和VC++ 6.0中的實現。


一、ISAPI介面和CGI介面的不同。

ISAPI程式和CGI程式完成類似的功能,但是實現方法不同。

1、ISAPI程式以DLL形式被Web伺服器載入到自己的程序空間中,因此和伺服器共用同一個地址空
間,且在沒有客戶請求時可以將其從記憶體中解除安裝;而對客戶端發來的每個對CGI程式的請求則需
要伺服器為它單獨啟動一個程序,這需要耗費大量的時間和記憶體。當併發的請求數目很大時,使
用CGI在效率上不如ISAPI。

2、CGI程式通過環境塊和標準輸入輸出與Web伺服器進行通訊,而ISAPI程式與伺服器結合得更為
緊密,與伺服器共享同一個程序上下文,主要通過一個引數塊與伺服器進行互動,可以從伺服器
那裡獲得關於當前HTTP連線的大量資訊。

ISAPI主要分為ISA和ISAPI Filter兩部分。ISA方法相對而言要傳統一些,利用一些特殊的連結
,指向伺服器的作業,供程式開發人員設計一些擴充套件功能;而ISAPI過濾器則傾向於構造伺服器
直接呼叫的模組,提供一種無縫連結部件用於監測直接來自於伺服器的HTTP請求。


二、ISA

ISA(Internet Server Application)也可稱為ISAPI DLL,其功能和CGI程式的功能直接相對應
,使用方法和CGI也類似,由客戶端在URL中指定其名稱而啟用。例如下面的請求將呼叫伺服器的
虛擬可執行目錄Scripts下的function.dll(ISAPI DLL必須放在伺服器的虛擬可執行目錄下):
                              http://www.abc.com/Scripts/function.dll?
                              
ISA和伺服器之間的介面主要有兩個:GetExtentionVersion( )和HttpExtentionProc( )。任何
ISA都必須在其PE檔案頭的引出表中定義這兩個引出函式,以供Web伺服器在適當的時候呼叫。

1、當伺服器剛載入ISA時,它會呼叫ISA提供的GetExtentionVersion( )來獲得該ISA所需要的服
務器版本,並與自己的版本相比較,以保證版本相容。函式原型如下:

BOOL WINAPI GetExtentionVersion(HSE_VERSION_INFO *version);
typedef struct   _HSE_VERSION_INFO
{
    DWORD  dwExtensionVersion;                          //版本號
    CHAR   lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN]; //關於ISA的描述字串
}   HSE_VERSION_INFO, *LPHSE_VERSION_INFO;

2、ISA的真正入口是HttpExtentionProc( ),它相當於普通C程式的main( )函式,在這個函式中
根據不同的客戶請求作不同的處理。伺服器和HttpExtentionProc( )之間是通過擴充套件控制塊(
Extention Control Block)來進行通訊的,即ECB中存放入口引數和出口引數,包括伺服器提供
的幾個回撥函式的入口地址。函式原型如下:

DWORD HttpExtensionProc( EXTENSION_CONTROL_BLOCK *pECB );

ECB的結構定義如下(IN表示入口引數,OUT表示出口引數):

typedef struct _EXTENSION_CONTROL_BLOCK
{
   DWORD     cbSize;        //IN,本結構的大小,只讀
   DWORD     dwVersion      //IN,版本號,高16位為主版本號,低16位為次版本號
   HCONN     ConnID;        //IN,連線控制代碼,由伺服器分配,ISA只能讀取該值
   DWORD     dwHttpStatusCode;                 //OUT,當前完成的事務狀態
   CHAR      lpszLogData[HSE_LOG_BUFFER_LEN];  //OUT,需要寫入到日誌檔案中的內容
   LPSTR     lpszMethod;    //IN,等價於CGI的環境變數REQUEST_METHOD
   LPSTR     lpszQueryString;                  //IN,等價於環境變數QUERY_STRING
   LPSTR     lpszPathInfo;