|
|
|
|
|
我們用IIS搭建網(wǎng)站時(shí),會(huì)看到兩個(gè)地方的設(shè)置:ISAPI 篩選器、ISAPI 擴(kuò)展。其中 ISAPI 篩選器我們一般用不到,而 ISAPI 擴(kuò)展我們就很可能要用到,比如搭建php環(huán)境時(shí)就要用到 ISAPI 擴(kuò)展。親自搭建過php環(huán)境的人可能已經(jīng)對(duì) ISAPI 擴(kuò)展有了一定的了解,但是對(duì)于 ISAPI 篩選器還可能未曾去了解過。我們?cè)谑裁辞闆r下要用到 ISAPI 篩選器呢?ISAPI 擴(kuò)展與 ISAPI 篩選器的區(qū)別是什么呢?它們又有什么不同之處?這些都是本文要探討的問題。
在討論問題之前,我們先來了解一下 ISAPI 擴(kuò)展。
ISAPI 擴(kuò)展是運(yùn)行在IIS上并有權(quán)訪問其提供所有函數(shù)的真實(shí)應(yīng)用程序。典型 ISAPI 擴(kuò)展示例: ISAPI 擴(kuò)展通過調(diào)用Asp.dll進(jìn)行ASP頁面處理。通常情況下,ISAPI 擴(kuò)展與客戶端訪問靜態(tài)HTML文件或動(dòng)態(tài)ASP文件方式相同。
ISAPI 擴(kuò)展以 DLL 形式被IIS加載到進(jìn)程空間中。客戶端在URL請(qǐng)求中指定其名稱激活 ISAPI 擴(kuò)展并調(diào)用文件系統(tǒng)中虛擬可執(zhí)行目錄下的dll文件。
使用 ISAPI 可以開發(fā)兩種類型應(yīng)用程序:擴(kuò)展和過濾器。ISAPI擴(kuò)展與HTML、ASP請(qǐng)求運(yùn)行方式相同。由于ISAPI應(yīng)用程序使用編譯方式,所以處理速度比Asp文件或調(diào)用COM+組件的文件處理快。
擴(kuò)展和過濾器可以使用C或C++開發(fā)。Visual Studio包含ISAPI向?qū)Ъ涌扉_發(fā)。
Web Server請(qǐng)求應(yīng)用程序映射(或腳本映射)方式與Windows中相同。如當(dāng)你打開一個(gè)以".txt"結(jié)尾的文件,因?yàn)門XT文件映射至Notepad.exe,所以在記事本中打開。
ISAPI擴(kuò)展通過調(diào)用ASP.dll處理Asp函數(shù)。任何以.asp文件結(jié)尾的請(qǐng)求在被輸出至客戶端窗口顯示前都將被iis服務(wù)器映射至asp.dll。
客戶端請(qǐng)求ISAPI擴(kuò)展方式如下:
http://Server_name/ISAPI_name.dll/Parameter
請(qǐng)求asp文件,客戶端URL請(qǐng)求如 http://Server_name/ASP.dll/File_name.asp 由于asp被%windir%\system32\inetsrv\ASP.dll 的擴(kuò)展處理。為簡化asp請(qǐng)求,iis使用腳本映射.asp與ASP.dll擴(kuò)展。http://Server_name/File_name.asp 的請(qǐng)求接獲時(shí),iis運(yùn)行asp.dll 服務(wù)請(qǐng)求加載處理文件。iis上應(yīng)用程序都通過腳本進(jìn)行特定文件名與擴(kuò)展映射。
當(dāng)iis接收請(qǐng)求映射至擴(kuò)展時(shí),將發(fā)生如下事件:
1、如果不是已經(jīng)在內(nèi)存中,IIS 將加載 DLL。當(dāng)加載 DLL 時(shí),Windows 將自動(dòng)調(diào)用 entry/exit 函數(shù) (通常為 DllMain)。然后調(diào)用擴(kuò)展的 GetExtensionVersion 入口點(diǎn)函數(shù)。
2、iis 對(duì)傳入請(qǐng)求進(jìn)行預(yù)處理
3、iis 通過擴(kuò)展傳遞請(qǐng)求數(shù)據(jù)和回調(diào)函數(shù) 創(chuàng)建和填充 EXTENSION_CONTROL_BLOCK 結(jié)構(gòu)
4、.iis 調(diào)用 HttpExtensionProc 函數(shù),傳遞一個(gè)指針到 EXTENSION_CONTROL_BLOCK 結(jié)構(gòu)創(chuàng)建該請(qǐng)求
5、執(zhí)行更多isapi擴(kuò)展操作:如從客戶端讀取更多數(shù)據(jù)(post操作),或向客戶端寫標(biāo)題和數(shù)據(jù)
6、通過HttpExtensionProc 函數(shù)完成擴(kuò)展信息處理。同步操作,函數(shù)返回HSE_STATUS_SUCCESS返回代碼;異步操作,返回代碼是HSE_STATUS_PENDING .如需有關(guān)異步操作的信息,請(qǐng)參閱異步I/O處理
7、iis執(zhí)行清理請(qǐng)求連接,若 Keep-Alive 請(qǐng)求未啟用,將關(guān)閉這個(gè)連接
8、不再需要ISAPI擴(kuò)展時(shí),IIS 若提供 TerminateExtension 函數(shù),則調(diào)用執(zhí)行。如果IIS配置為緩存ISAPI擴(kuò)展,則不調(diào)用TerminateExtension 函數(shù),直到IIS web 服務(wù)器關(guān)閉或重啟。
注釋:不要求每個(gè)請(qǐng)求調(diào)用GetExtensionVersion。相反,ISAPI 擴(kuò)展對(duì)于每個(gè)請(qǐng)求只調(diào)用一次HttpExtensionProc。此外,EXTENSION_CONTROL_BLOCK結(jié)構(gòu)用于每個(gè)傳入請(qǐng)求。
我們先來看看 ISAPI 篩選器和 ISAPI 擴(kuò)展的屬性在哪設(shè)置,如下面兩圖所示:
▲ ISAPI 篩選器
▲ ISAPI 擴(kuò)展
Internet 服務(wù)器擴(kuò)展 (ISA) 是您為擴(kuò)展服務(wù)器功能而編寫的程序。當(dāng)某客戶端發(fā)送請(qǐng)求調(diào)用 DLL 的 URL 從而顯式請(qǐng)求調(diào)用 ISA 時(shí),將調(diào)用 ISA。例如,http://yourserver/wwwquote.dll? 請(qǐng)求名為 yourserver 的服務(wù)器運(yùn)行 DLL wwwquote。當(dāng)用戶單擊 Web 頁上的按鈕時(shí),也會(huì)發(fā)送 HTTP 請(qǐng)求。當(dāng) Web 頁作為收集信息的窗體,而這些信息作為參數(shù)傳遞給 DLL 時(shí),經(jīng)常使用這種方法。例如,http://yourserver/wwwquote.dll?Issues?Method=ByCUSIP 調(diào)用 DLL 并將參數(shù) Method=ByCUSIP 傳遞給函數(shù) Issues。
相反,每次指定的事件發(fā)生時(shí)都調(diào)用 ISAPI 篩選器,無論服務(wù)器正在處理什么請(qǐng)求。如果包括了 SF_NOTIFY_URL_MAP(用于 URL 映射的標(biāo)記),那么在請(qǐng)求通知時(shí),每次 URL 映射到服務(wù)器時(shí)都將調(diào)用 OnURLMap 函數(shù),與 URL 命令的內(nèi)容無關(guān)。篩選器可以根據(jù)對(duì)服務(wù)器的每個(gè)請(qǐng)求來處理、檢查和更改數(shù)據(jù)。
服務(wù)器擴(kuò)展: | 篩選器: |
---|---|
在 URL 中引用時(shí)運(yùn)行。 | 為服務(wù)器處理的每個(gè) URL 調(diào)用。 |
被顯式調(diào)用,例如用 http://myserver/myprog.dll?。 | 如果發(fā)生已注冊(cè)事件,自動(dòng)為任何發(fā)送到服務(wù)器的 URL 運(yùn)行。 |
被用戶第一次調(diào)用時(shí)根據(jù)請(qǐng)求加載。 | 服務(wù)因其注冊(cè)表項(xiàng)而啟動(dòng)時(shí)加載。 |
ISAPI 擴(kuò)展和 ISAPI 篩選器都:
在同一 DLL 中可以有一個(gè)篩選器(如果需要,可接收多個(gè)通知)和一個(gè)服務(wù)器擴(kuò)展。這在篩選器和服務(wù)器擴(kuò)展彼此相關(guān)時(shí)會(huì)很有用。例如,您可能希望在將數(shù)據(jù)發(fā)送到客戶端之前執(zhí)行數(shù)據(jù)的后處理,以便自定義特定瀏覽器的外觀。另一個(gè)實(shí)例是在篩選器和擴(kuò)展之間通信??梢詫⒑Y選器和應(yīng)用程序放在同一 DLL 中,并在篩選器 SF_NOTIFY_PREPROC_HEADERS 通知期間添加一個(gè)鍵值標(biāo)題。應(yīng)用程序可以通過查找相應(yīng)的上下文獲取此鍵。
本文討論針對(duì)在 Microsoft Internet 信息服務(wù) (IIS) 上運(yùn)行 ISAPI 擴(kuò)展或篩選器的編程提示。如果在其他支持 ISAPI 的 Web 服務(wù)器上運(yùn)行,這些服務(wù)器可能以不同的方式處理注冊(cè)表項(xiàng)、內(nèi)存和應(yīng)用程序的加載。有關(guān)更多信息,請(qǐng)參見您正在使用的 Web 服務(wù)器的文檔。
從 IIS 1.0 開始,ISAPI 篩選器在該服務(wù)啟動(dòng)時(shí)加載,并且直到該服務(wù)停止時(shí)才卸載。ISAPI 服務(wù)器擴(kuò)展在第一次被調(diào)用時(shí)加載并保留在內(nèi)存中,直到服務(wù)關(guān)閉或者內(nèi)存被其他進(jìn)程需要為止。由于 DLL 將長時(shí)間保留在內(nèi)存中,因此需考慮何時(shí)分配資源、何時(shí)解除分配資源以及何時(shí)同數(shù)據(jù)源等資源連接或斷開連接。
若要安裝篩選器或 ISA 的新版本,必須關(guān)閉該服務(wù)、將 DLL 復(fù)制到適當(dāng)?shù)哪夸?、更新注?cè)表(如果它是新的篩選器)并重新啟動(dòng)該服務(wù)。
注冊(cè)表項(xiàng) HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/W3SVC/Parameters/FilterDLLs 控制該服務(wù)啟動(dòng)時(shí)加載的篩選器。它包含一個(gè)以逗號(hào)分隔的篩選器列表,其中包含它們的完整路徑。若要加載其他篩選器,請(qǐng)停止該服務(wù),將篩選器添加到注冊(cè)表并重新啟動(dòng)該服務(wù)。
ISAPI 擴(kuò)展在第一次被客戶端調(diào)用時(shí)加載。
該服務(wù)啟動(dòng)后,篩選器將保留在內(nèi)存中,直到關(guān)閉計(jì)算機(jī)或該服務(wù)為止。同樣,服務(wù)器擴(kuò)展一經(jīng)加載便可能保留在內(nèi)存中,直到關(guān)閉計(jì)算機(jī)或該服務(wù)為止。通過指定注冊(cè)表設(shè)置 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/W3SVC/Parameters/CacheExtensions=0,可以強(qiáng)制重新加載擴(kuò)展 DLL(例如,出于調(diào)試的目的)。此設(shè)置直到該服務(wù)重新啟動(dòng)時(shí)才生效。注意此設(shè)置應(yīng)該只在調(diào)試時(shí)使用。它對(duì)性能有負(fù)面影響,決不要在生產(chǎn)服務(wù)器上使用。
我的應(yīng)用程序必須是線程安全的嗎?
是的。ISAPI 是作為 Web 服務(wù)器的一部分運(yùn)行的。在像 Microsoft Internet 信息服務(wù)這樣的多線程服務(wù)器上,您的應(yīng)用程序在 Windows NT 服務(wù)的上下文中運(yùn)行。您的應(yīng)用程序可能從不同的線程同時(shí)被調(diào)用多次。數(shù)據(jù)必須受臨界區(qū)的保護(hù)。
如何為處理同時(shí)請(qǐng)求進(jìn)行計(jì)劃?
ISAPI DLL 支持多個(gè)同時(shí)請(qǐng)求,確保臨界數(shù)據(jù)受到保護(hù)是 ISAPI DLL 開發(fā)人員的責(zé)任。
Web 服務(wù)器天生可以同時(shí)處理多個(gè)請(qǐng)求。您的應(yīng)用程序加上許多其他應(yīng)用程序都將一直使用此服務(wù)器。在像 www.microsoft.com 這樣的繁忙站點(diǎn)和一些流行的搜索引擎上,每天都可以看到數(shù)百萬用戶的客戶端通信量。用戶希望得到快速響應(yīng),如果響應(yīng)時(shí)間過長他們將取消請(qǐng)求。
正如前面提到的,應(yīng)用程序是線程安全的。除非需要,否則一定掛斷資源或連接。不要使用全局變量。
當(dāng)收到篩選器通知時(shí):
文章擴(kuò)展
IIS中 ISAPI 擴(kuò)展、ISAPI 篩選器
在IIS的文檔中經(jīng)常會(huì)提到兩個(gè)術(shù)語:ISAPI擴(kuò)展和ISAPI篩選器。
“ISAPI擴(kuò)展(ISAPI Extension)”是一種可以添加到IIS中以增強(qiáng)Web服務(wù)器功能的程序,其載體為DLL文件。通常直接負(fù)責(zé)響應(yīng)HTTP請(qǐng)求。
根據(jù)HTTP請(qǐng)求要訪問的資源擴(kuò)展名(通過URL獲?。?,IIS會(huì)選取特定的 ISAPI 擴(kuò)展來處理這一請(qǐng)求,這一過程被稱為“程序映射”。 而用于響應(yīng)HTTP請(qǐng)求的被稱為“HTTP Handler(HTTP處理程序)”。 下圖展示了IIS 6中的程序映射。
▲ ISAPI 擴(kuò)展
在圖中可以看到,IIS指定對(duì)php網(wǎng)頁(其擴(kuò)展名為.php)的請(qǐng)求將由php5isapi.dll處理。
IIS 7中的程序映射與IIS 6略有不同。當(dāng)IIS 7以“經(jīng)典模式”運(yùn)行時(shí),與IIS 6一樣使用 php5isapi.dll 響應(yīng)針對(duì)“.php”的請(qǐng)求。但當(dāng)IIS 7以“集成模式”運(yùn)行時(shí),則使用托管處理程序(System.Web.UI.PageHandlerFactory)響應(yīng)針對(duì)“.php”的請(qǐng)求(圖 8?13)。
IIS 7 程序映射
“ISAPI篩選器(ISAPI Filter)”也是一種DLL但不負(fù)責(zé)處理HTTP請(qǐng)求,主要作用是響應(yīng)某些特定的事件。當(dāng)這些事件發(fā)生時(shí) ISAPI 篩選器被調(diào)用,它可以修改傳入或傳出的HTTP數(shù)據(jù)。在IIS 7中,使用“HTTP模塊(HTTP Module)”取代了傳統(tǒng) ISAPI 篩選器的功能。
ISAPI 擴(kuò)展與 ISAPI 篩選器名字很相近,但其在IIS中的地位和所起的作用是不同的。