IIS與Asp.net


一、IIS

  1、綁定

  為了將特定的請求映射到相應的網站,IIS允許我們配置“綁定”。所謂“綁定”就是將一個特定的地址、端口號和HTTP主機名對應到特定的網站。

  IIS7添加綁定的代碼如下圖所示:

  

  在IIS7中,如果新設置的綁定與網站中已經存在的綁定沖突,那么將會彈出一個提示框,提示我們綁定沖突。

  

  對於每個網站來說,存在一個虛擬的網站文件系統,這個網站文件系統是相對於磁盤文件系統來說的。磁盤文件系統是存在於磁盤上的操作系統管理的文件系統,而網站文件系統是獨立於磁盤文件系統的另外一種文件系統。這種文件系統更加類似於Unix中的文件系統。我們通常稱為虛擬目錄。

  對於每一個網站文件系統,存在一個根目錄,根目錄的名字永遠使用(/)表示。

  當用戶訪問網站目錄的時候,IIS將會把網站文件系統的訪問映射到磁盤文件系統中網站根目錄映射到磁盤文件系統目錄是我們在IIS中指定的。在IIS7中,當創建新的網站的時候,我們就需要指定根目錄映射的物理文件目錄。

  

  默認情況下,網站的根目錄映射為C:\inetpub\wwwroot,也就是說,在網站中,根目錄/將會被映射到文件系統的C:\inetpub\wwwroot,當我們訪問網站中的/index.html的時候,實際上,IIS將會到C:\inetpub\wwwroot目錄中訪問index.html這個文件。在Asp.net程序中,這個映射通過HttpServerUtility方法的MapPath來完成,我們傳入一個當前網站的虛擬目錄,返回的結果就是映射到文件系統的文件目錄。當然,這個文件或者目錄可能並不存在。

  2、網站應用程序

  在IIS中,每一個網站都至少包含一個網站應用程序,即根網站應用程序。根據需要,一個網站中還可以包含更多的網站應用程序。

  網站應用程序是監聽網絡連接並進行處理的基本單位,每個網站應用程序有一個唯一的標識,對於IIS7中的默認網站Default Web Site來說,其ID是1。在IIS中,邏輯上,所有的網站都被包含在一個同樣的根目錄/W3SVC之下,所以,默認的網站在IIS內部表示為/W3SVC/1,我們通常稱為/網站應用程序。

  如果我們再默認網站中創建了一個網站應用程序demo,那么這個網站應用程序在IIS內部將被表示為/W3SVC/1/Root/demo,我們通常稱之為/demo網站應用程序。

  對於每一個網站應用程序來說,需要堅挺某個網絡端口以處理客戶端的請求,例如,處理來自80端口的HTTP請求就是網站的一個基本工作。

  對於Asp.net來說,一個網站應用程序就是一個獨立的應用程序單位,對應一個網站應用程序,Asp.net將會創建一個AppDomain來進行處理。所以,在Asp.net的世界里,網站應用程序被映射到一個AppDomain,應用程序域提供了在一個進程中的托管代碼的隔離,更重要的是,對於在部分新人環境下的應用程序提供了網站寄宿能力。

  在IIS7環境下,位於%windir%\system32\inetsrv\config\目錄下的applicationhost.config文件定義了IIS中的網站及其應用程序。

  3、虛擬目錄

  對於網站應用程序來說,內容的來源不僅可以來自其相應的物理文件目錄,還可以通過虛擬目錄來提供。這非常類似於UNIX中符號鏈接的概念,在IIS中,這種映射稱為虛擬目錄。在IIS7中,創建虛擬目錄的界面如下圖:

  

  一個網站應用程序至少包含一個虛擬目錄,這個也可以在applicationhost.config里看到。

  網站應用程序借助於虛擬目錄來獲取網站中的資源。開發中所使用的虛擬路徑就是基於虛擬目錄的路徑。

  網站應用程序和虛擬目錄可以互相嵌套,也就是說,網站應用程序中可以包含虛擬目錄,虛擬目錄中也可以包含網站應用程序,它們可以任意嵌套組合。

  對於Asp.net網站來說,父網站應用程序將會影響子網站中的應用程序,父網站應用程序中的配置參數將會被子網站應用程序所繼承,所引用的程序集也會被子網站所引用。

二、通過ISAPI擴展IIS

  IIS是一個完整的Web服務器軟件,本身就可以完成基本的Web服務任務,如果我們需要擴展IIS的話,可以通過多種方式來實現,例如CGI或者ISAPI,對於IIS服務器來說,其中最重要的就是ISAPI。

  ISAPI是微軟提供的一套面向Internet服務的基於C語言的API接口,它能實現CGI提供的全部功能,並在此基礎上進行了擴展,如提供了過濾器應用程序接口等。

  ISAPI提供了擴展Web服務器的簡單而有效的方法。開發人員可以設計ISAPI服務器動態鏈接庫(ISAPI Server Extension DLL),它可以被HTTP服務器調用。例如,客戶端用戶填寫了一個表單,按下“提交”按鈕后,輸入的數據將被傳送至HTTP服務器,激活相應的ISAPI擴展應用程序,該應用程序可以處理用戶的輸入信息,進行相應的操作,或者按照用戶的要求訪問數據庫,讀取用戶指定的數據,動態生成HTML文件,再傳回客戶端。

  考慮到性能原因,ISAPI和調用它的IIS是在同一個進程中的,這使得他們彼此間可以共享某些數據,從而大大提高了相互訪問的速度,但這種直接訪問使得ISPAI本身出現錯誤時很可能也影響到IIS,導致IIS服務器癱瘓。ECB正式基於這一考慮而出現,它是一個非托管資源包,具有對ISAPI接口完整的訪問能力,當IIS接收到一個Web請求后,首先調用自身的ProcessRequest函數進行處理,這個函數通過傳遞一個ECB的指針來間接地操作ISAPI。

  ISAPI分為兩種:ISAPI擴展和ISAPI過濾器。

  1、ISAPI擴展

  對於ISAPI擴展來說,ISAPI向IIS提供了三個方法的接口。

  • BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO*pVer);
  • DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB);
  • BOOL WINAPI TerminateExtension(DWORD dwFlags);

  對於IIS來說,一旦裝載了一個ISAPI擴展的DLL,一個用於管理ISAPI擴展的線程便啟動了,在調用入口函數DLLMain之后,將會通過調用GetExtensionVersion函數來注冊版本信息。如果函數返回為真,表示成功。

  在此之后,當需要通過ISAPI擴展處理請求的時候,IIS服務器通過之前提到的ECB指針調用ISAPI擴展中的一個名為HttpExtensionProc的函數,該函數的任務是將處理過后的數據協會到客戶端。

  返回值是下列之一:

  • HSE_STATUS_SUCCESS,擴展完成了處理,服務器應該與客戶端斷開連接,釋放分配的資源。
  • HSE_STATUS_SUCCESS_AND_KEEP_CONN,擴展完成了處理,在客戶端支持Keep-Alive的情況下,服務器等待客戶端的下一個請求進行處理。
  • HSE_STATUS_ERROR,處理出現錯誤。

  ISAPI擴展的第三個操作,同時也是ISAPI執行的最后一步,就是在ISAPI擴展從內存中卸載之前執行將會TerminateExtension操作。ISAPI使用的所有的資源應該在這個函數中釋放。

  ISAPI擴展類似於Asp.net中的處理程序,效率很高,但是實現比較復雜。

  2、ISAPI過濾器

  ISAPI過濾器是另外一種ISAPI,在IIS內部處理請求的過程中,將處理過程分為多個處理階段,在每個階段將會發出一個處理的消息供我們處理,ISAPI過濾器可以響應這些消息,在相應的消息發出后,過濾器將會被調用。在過濾器中,可以監視並修改處理過程中的數據,不管是客戶端發送到服務器的數據還是服務器准備返回到客戶端的數據。可以使用ISAPI過濾器提供增強的HTTP請求記錄、自定義加密、自定義壓縮或其他身份驗證方法。

  IIS中預定義的消息按照下面的順序依次發出:

  1. SF_NOTIFY_READ_RAW_DATA,當IIS要從用戶讀入數據時發生。過濾器可以在IIS處理他們之前檢查甚至修改用戶輸入的原始數據。
  2. SF_NOTIFY_PREPROC_HEADERS,IIS預處理HTTP請求包頭后發生。過濾器可以檢查修改增加包頭。
  3. SF_NOTIFY_URL_MAP,IIS試圖將URL解釋為物理文件時發生。過濾器可以將請求重定向到其他的文件。
  4. SF_NOTIFY_AUTHENTICATION,IIS試圖驗證用戶身份時發生。過濾器可以實現自己的驗證方案。
  5. SF_NOTIFY_AUTH_COMPLETE,當身份驗證完成時發生。
  6. SF_NOTIFY_AUTH_RESPONSE,在IIS處理請求之后,但是任何Header發送回客戶端之前發生。
  7. SF_NOTIFY_SEND_RAW_DATA,當其他程序處理完,IIS准備將數據發回給用戶時發生。可能多次發出。
  8. SF_NOTIFY_END_OF_REQUEST,當一個HTTP請求結束時發生。
  9. SF_NOTIFY_LOG,當IIS寫記錄到LOG文件時發生。過濾器可以搜集更多的信息寫入記錄文件中。
  10. SF_NOTIFY_END_OF_NET_SESSION,連接結束時發生。注意如果瀏覽器支持keep-alive,一次連接可能包含幾個HTTP請求。過濾器可以用它來釋放一些用戶的資源。

  對於ISAPI過濾器來說,ISAPI向IIS提供了三個方法的接口:

BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer);
DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc,DWORD notificationType,LPVOID pvNotification);
BOOL WINAPI TerminateFilter(DWORD dwFlags);

  GetFilterVersion方法是IIS調用過濾器的第一個方法,在這個方法中,需要注冊過濾器需要需要監聽的事件。如果過濾器正常工作的話,必須返回真,否則,IIS不會向過濾器發送任何消息。

  對於事件的處理在HttpFilterProc中進行,對於不同的事件,HttpFilterProc的第三個參數將會得到不同類型的數據。處理的結果為以下之一。

  • SF_STATUS_REQ_FINISHED,過濾器處理了請求,服務器應該斷開會話。
  • SF_STATUS_REQ_FINISHED_KEEP_CONN,過濾器不支持。
  • SF_STATUS_REQ_NEXT_NOTIFICATION,應該調用下一個過濾器。
  • SF_STATUS_REQ_HANDLED_NOTIFICATION,過濾器處理了請求,不需要在調用其他的過濾器了。
  • SF_STATUS_REQ_ERROR,告訴IIS處理過程中出現了錯誤。
  • SF_STATUS_REQ_READ_NEXT,僅用於原始數據讀取通知。

  可以看到,ISAPI非常類似於HttpModule,不過ISAPI是使用C語言或者C++完成的,雖然效率很高,但是實現起來難度較大。

  3、CLR是一個COM組件

  通過ISAPI可以處理HTTP請求,但是,使用C語言來創建一個網站顯然是代價高昂的。然而,我們可以通過.Net來更加容易地開發網站應用程序,然后,通過COM技術,我們可以將需要處理的參數傳遞給.Net應用程序,最后,在非托管程序中取回托管程序處理的結果。

  4、ASP.NET中的ISAPI擴展和過濾器

  在Asp.net中,同樣使用ISAPI來擴展IIS,在位於%windir%\Microsoft.NET\Framework\v4.0.30319的ASP.NET的系統文件夾中,包含兩個特殊的文件,分別用於ISAPI擴展和ISAPI過濾器。

  • aspnet_isapi.dll
  • aspnet_filter.dll

  過濾器用於支持無Cookie的狀態管理,將遷入在URL路徑中的票據去除,使得請求路徑轉化為正常的請求地址,將票據信息轉化為請求頭參數,以便於在ASP.NET中進行處理。

  對於嵌入在URL中的標識信息,不同的前綴表示這是不同的標識。

  1. S-Cookieless ticket for session state
  2. A-Cookieless ticket for anonymous identification
  3. F-Cookieless ticket for forms authentication

  在經過ISAPI處理之后,嵌入在URL中的標識信息稱為了請求頭中參數的一部分。例如,在Cookieless狀態下,嵌入在地址中的SessionID被轉化為了名為AspFilterSessionId的請求頭,而即使是通過HttpRequest對象的RawUrl也只能取得轉換后的地址了。

過濾器的第二個作用是用來保護ASP.NET特殊的、受保護文件夾,例如App_Code,App_Data,App_Browsers等。

  ISAPI擴展器是ASP.NET的關鍵所在,它是接收和分派對各種ASP.NET資源請求的控制中心。該模塊存在於IIS進程中,在具有管理員權限的SYSTEM賬戶下運行。

  aspnet_isapi.dll是一個非托管的動態連接庫,它通過命令管道將請求轉發到ASP.NET所在的輔助進程,進程中的應用程序與將對請求進行最終的處理。ISAPI和進程的通訊是使用一組命名管道進行的。命名管道是一種Win32通訊機制,用於跨進程邊界傳輸數據。對於本地進程間通訊,管道是Windows中的最有效、最靈活的工具。為了確保獲得最優性能,aspnet_isapi使用異步命名管道來將請求轉發給輔助進程並獲得響應。另一方面,輔助進程在需要查詢有關IIS環境的信息(服務器變量)時又使用同步管道。aspnet_isapi模塊創建固定數量的命名管道,並使用重疊的操作以通過小的線程池處理同一時間進行的連接。當通過管道進行的數據交換操作結束后,將斷開客戶端,並重新使用管道實例為新的客戶端服務。線程池和重疊操作均可以保證使ASP.NET ISAPI的性能達到令人滿意的水平。



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM