線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1867
推到 Plurk!
推到 Facebook!

[推薦] 用C++Builder開發ISAPI擴展應用程序

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-07-24 16:45:00 IP:61.218.xxx.xxx 未訂閱

用C Builder開發ISAPI擴展應用程序

作者不詳: 資料來源:http://bcbdev.myetang.com/bcjq/bcjq063.htm 一、ISAPI概述 Microsoft的WEB服務器提供了不同的ISAPI,應用ISAPI能夠開發出高性能的應用程序。 ISAPI具有兩類組件:ISAPI擴展和ISAPI過濾器,本文著重介紹ISAPI擴展的應用和開發。 ISAPI應用程序通過DLL實現,DLL的特性使它能夠作為WEB服務器自身的擴充來裝載。在 WEB服務器的地址空間運行, 而且只在第一次請求時裝載一次,以後每一個後續請求通 過創建一個線程(僅用一個簡單的函數調用) 來完成,這比CGI創建一個進程要節約大量 的時間和空間等資源。 ISAPI擴展通常代替傳統Web應用程序中CGI腳本的位置,由客戶觸發,為其特殊請求服務。 ------清單1-------------- 1.<html> 2. myGetGrp.dll"> 3.</html> 如清單1所示代碼,服務器將調用myGetGrp.dll中提供的函數得到一GIF圖像文件數據發 送給客戶瀏覽器,在這裡,myGetGrp.dll就是一個ISAPI擴展。 如果服務器確定將執行一個ISAPI擴展, 他首先檢查此擴展是否已經裝入高速緩存,若 沒有,則指定的DLL被裝載﹔裝入DLL後,服務器就調用DLL中的HttpExtensionProc()函 數對請求提供服務, 這裡是ISAPI程序員放置具體功能操作的位置,服務器將所有必要 的信息通過一結構類型參數傳遞給這個函數,包括請求本身的內容和程序員將用到的回 調函數等,用回調函數,可以將數據傳遞給用戶以及執行其他的操作。 注意:必須牢記服務器是啟動多線程來處理同時接收到的多個請求的,所以必須正 確處理線程間的同步,否則將會導致數據破壞甚至系統崩潰。 二、用C Builder開發ISAPI擴展應用程序 C Builder是Inprise公司繼Delphi之後開發的又一個通用的客戶/服務器結構的 開發工具。 它使用了C 語言,可以產生更快速和更高效的代碼。目前已成為繼Visual Basic、Delphi之後,在32位Windows環境下最具有吸引力的開發工具之一。 啟動C Builder後,用File→New菜單項打開New Items對話框,在New頁面下選中 Web Server Application選項,單擊按紐,彈出一New Web Server Application對 話框,選中ISAPI/NSAPI Dynamic將生成一ISAPI擴展應用程序框架,其主模塊缺省名為 Project.cpp,其中主要實現了DLL的三個輸出函數,說明如下: 1.1 GetExtensionVersion()函數 這是一個非常簡單的函數, 它唯一的目的是指定ISAPI版本,並給出擴展的描述。 當DLL第一次被裝載時,由服務器調用。這發生在HttpExtensionProc()函數第一次調用 前, 在此函數中, 你所需做的全部就是用常量HSE_VERSION_MAJOR和HSE_VERSION_ MINOR(在Isapi2.hpp中定義)設置擴展版本域。並且返回一true值。 GetExtensionVersion()函數實現實例見清單2。 ---------清單2----------------- BOOL_export WINAPI GetextensionVersion(Isapi2::THSE_VERSION_INFO &Ver) { /*設置擴展版本域*/ Ver.dwExtensionVersion=MAKELONG(HSE_VERSION_MAJOR,HSE_VERSION_MINOR); Ver.lpszExtensionDesc="Example ISAPI extension";//設置擴展描述域 return true; //返回true } 在此函數中,程序員還可以加入初始化代碼,如全局變量的初始化等。 1.2 HttpExtensionProc()函數 HttpExtensionProc() 函數是擴展的功能實現部分,每次產生對擴展的請求,服務 器就調用這個函數,同時傳遞一類型為TEXTENSION_CONTROL_BLOCK結構的參數(ECB) , 這個結構在Isapi2.hpp中定義: struct TEXTENSION_CONTROL_BLOCK { unsigned cbSize;//結構大小 unsigned dwVersion;//版本信息 unsigned ConnID; /*正在被服務的連接的ID;調用回調函數時必須作為一參數傳遞*/ unsigned dwHttpStatusCode;/*在HttpExtensionProc () 函數返回前,在此放置HTTP狀態碼,參見HTTP1.0規範定義*/ char lpszLogData[80];//接收一記錄信息字符串 char *lpszMethod;//命名請求方式的字符串的指針 char *lpszQueryString;//含一個GET請求查詢的字符串指針 char *lpszPathInfo;//請求的字符串的指針 char *lpszPathTranslated;//把請求的字符串指針翻譯為服務器的物理路徑 unsigned cbTotalBytes;//請求中字節的全部數目 unsigned cbAvailable;//lpbData緩衝區長度 void *lpbData;//POST請求的數據緩衝區指針 char *lpszContentType;//識別請求的MIME內容類型的指針 TGetServerVariableProc GetServerVariable; /*檢索服務器變量值的回調函數指 針*/ TWriteClientProc WriteClient;//寫數據給用戶的回調函數的指針 TReadClientProc ReadClient;//檢索用戶數據的回調函數指針 TServerSupportFunctionProc ServerSupportFunction; /*支持其他操作的回調函數指針*/ } 這種結構包含服務請求和回調函數指針所需得信息,你可以調用它來獲取信息或執 行操作,下面對其中的回調函數作一說明: (1)GetServerVariable函數 原型為: typedef BOOL _stdcall (*TgetServerVarableProc) (int hConn,*VariableName, void *Buff,int &Size); 調用這個函數來獲取服務器變量(如CONTEXT_TYPE)和同請求一起收到的頭部。如通 過請求, 則得到HTTP_COOKIE來檢索Cookies頭部的內容。參數說明:hConn為傳入參數 ECB的連接句柄ConnID;VariableName為要檢索的變量的名字(如HTTP_COOKIE);Buffer為 接收變量的緩衝區指針﹔Size為緩衝區大小,若由於緩衝區空間不夠而失敗,該值被改 變為必要的緩衝區大小。 (2)WriteClient函數 原型為: typedef BOOL _stdcall (*TWriteClientProc) (int ConnID,void *Buffer,int & Bytes,int dwReserver) 調用這個函數來發送響應內容給用戶, 參數說明:ConnID為傳入參數ECB中的連接 句柄ConnID﹔ Buffer為包含寫數據緩衝區的指針﹔ Bytes為緩衝區數據的字節數﹔ dwReserver保留。 (3)ReadClient函數 原型為: typedef BOOL _stdcall (*TReadClientProc) (int ConnID, void *Buffer,int & Size) 調用這個函數讀取用戶的附加數據,通過檢驗ECB中cbAvailable和cbTotalBytes的 值來確定是否調用此函數, 若cbTotalBytes大於cbAvailable﹔就表明有更多的數據需 要調用該函數去讀取。 參數說明:ConnID為傳入參數ECB中的連接句柄ConnID﹔Buffer 為讀入數據存放的緩衝區﹔Size在調用時,傳入Buffer緩衝區的大小,返回時,等於實 際讀取的字節數。 (4)ServerSupportFunction函數 原型為: typedef BOOL _stdcall (*TServerSupportFunctionProc) (int hConn, int HSERRequest,void buffer,int &Size,PDWORD DataType); 這個函數實現其他一些操作,參數說明:hConn為傳入參數ECB的連接句柄ConnID, HSERRequest為要實現操作的常量值。Size為Buffer緩衝區的大小,Buffer緩衝區指針; DataType為數據類型指針﹔其中Buffer和DataType的含義根據HSERRequest的值變化。 下面說明這個函數的幾個主要操作(也就是HSERRequest的可用值,在Isapi2.hpp中 定義),以及對應不同的操作,參數Buffer,Size,DataType的不同含義: ●HSE_REQ_SEND_URL_REDIRECT_RESP: 重定向客戶瀏覽器到另一個網址上的URL。 Buffer:指向一重定向目標URL字符串﹔DataType被忽略。 ●HSE_REQ_SEND_URL: 重定向到本服務器上的一個URL,Buffer: 指向一重定向目標 URL字符串﹔DataType被忽略。 ●HSE_REQ_SEND_RESPONSE_HEADER:發送響應頭部給用戶﹔Buffer: 指向包含頭部的 字符串﹔DataType被忽略。 ●HSE_REQ_DONE_WITH_SESSION: 通知服務器, 異步的請求處理已經完成。 Size, Buffer,DataType均被忽略。 ●HSE_REQ_MAP_URL_TO_PATH: 映射一個邏輯路徑到一個物理路徑。Buffer:映射在 此緩衝區上完成﹔DataType被忽略。 HttpExtensionProc()函數的返回值必須使以下四個值(在Isapi2.hpp中定義)中的一個: ●HSE_STATUS_SUCCESS:所有進程已完成。 ●HSE_STATUS_SUCCESS_AND_KEEP_CONN:所有進程已經完成,但希望保持連接以繼 續進一步的交互。 ●HSE_STATUS_PENDING: 進程未完成。 當擴展異步完成進程時, 將以參數 HSERRequest=HSE_REQ_DONE_WITH_SESSION調用ServerSupportFunction(),以提醒服務 器進程已完成。 ●HSE_STATUS_ERROR:進程由於錯誤已異常終止。 清單3包含了處理一個"Hello World"網頁請求的簡單 但必要的邏輯。 ---------清單3------------------------ int _export WINAPI HttpExtensionProc(Isapi2::TEXTENSION_CONTROL_BLOCK &ECB) { char my_string[256]; int length; strcpy(my_string,"200 OK/r/nContext-Type:text/html"); length=strlen(my_string); ECB.dwHttpStatusCode=200; ECB.ServerSupportFunction(ECB.ConnID, HSE_REQ_SEND_RESPONSE_HEADER, my_ string,length,NULL);//發送頭部 strcpy(my_string,"Hello World!"); length=strlen(my_string); ECB.WriteClient(ECB.ConnID,my_string,length,0); //發送數據給客戶瀏覽器 return(HSE_STATUS_SUCCESS); } 這是一個簡單的例子,實際應用的ISAPI擴展將需要做比這更多的工作。 與GetExtenVersion()函數和TerninateExtension()函數不同,HttpExtensionProc ()函數對用戶的行為產生作用。 1.3 TerminateExtension()函數 TerminateExtension() 函數在用戶將卸載DLL時被調用,它是可選擇的。傳入參數 為dwFlages,類型為int,是以下兩個值(在Isapi2.hpp中定義)中的一個: ●請求同意卸載DLL的HSE_TERM_ADVISORY_UNLOAD值。 函數返回true將允許服務器 卸載該DLL。 ●強迫DLL清除並準備被卸載的HSE_TERM_MUST_UNLOAD值。 TerminateExtension()函數對服務器行為產生作用。 編寫完ISAPI擴展應用程序後,用C Builder的Project->菜單項功能,為ISAPI擴 展生成一個DLL,這個DLL就可以直接被作為ISAPI擴展使用。 2.結束語 本文介紹的是一種在C Builder開發環境下較為復雜的ISAPI擴展的實現方法,這 種方法對理解ISAPI擴展的工作方式有很大幫助,除此以外,在C Builder中有更簡單 的方法來實現, 即通過使用WebModule, 以及TISAPIApplication、 TISAPIRequest、 TISAPIResponse等類。詳細方法參見C Builder文檔。 時間就是金錢---[ 發問前請先找找舊文章] 發表人 - axsoft 於 2002/07/24 16:47:54
系統時間:2024-04-23 19:03:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!