mozilla是一個(gè)以瀏覽器為中心的軟件平臺,它在我們平臺中占有重要地位。我們用它來(lái)實(shí)現WEB瀏覽器、WAP瀏覽器、郵件系統、電子書(shū)和幫助閱讀器等應用程序。為此,我最近花了不少時(shí)間去閱讀mozilla的代碼和文檔,我將寫(xiě)一系列的BLOG作為筆記,供有需要的朋友參考。本文介紹一下傳輸協(xié)議。
Mozilla瀏覽器作為HTTP協(xié)議的客戶(hù)端,它與HTTP服務(wù)器(如Apache和IIS等)通信,進(jìn)行數據下載和上傳,自然要用到HTTP協(xié)議了。不過(guò)HTTP協(xié)議只是Mozilla所支持的眾多協(xié)議的一種,這些協(xié)議有的是網(wǎng)絡(luò )協(xié)議,比如HTTP,有的是本地協(xié)議,如file,還有的是虛擬協(xié)議,比如about。
我們說(shuō)過(guò),針對接口編程是Mozilla的重要特色之一,這里便是最好的例證:所有協(xié)議都要實(shí)現nsIProtocolHandler接口,使用者由nsIProtocolHandler請求所需要的服務(wù),而不關(guān)心具體的實(shí)現。通過(guò)URL中的Scheme自然的映射到具體協(xié)議的ContractID上,然后由組件管理器創(chuàng )建協(xié)議的實(shí)例。
nsIProtocolHandler的主要接口函數有:
1. GetScheme 得到協(xié)議的Scheme,這里的Scheme其實(shí)就是協(xié)議的名稱(chēng),比如http,https和ftp等等。
2. GetDefaultPort 得到協(xié)議的默認端口,比如http協(xié)議的默認端口是80,https協(xié)議的默認端口是443。
3. NewURI 創(chuàng )建一個(gè)nsIURI接口的實(shí)例。
4. NewChannel 根據提供的nsIURI創(chuàng )建一個(gè)Channel,Channel是客戶(hù)端與服務(wù)器端之間連接的抽象,但不能直接從Channel中獲取數據。獲取數據的方式有兩種:其一是調用Open得到nsIInputStream對象,再從nsIInputStream對象中讀取數據。其二是調用AsyncOpen注冊一個(gè)nsIStreamListener對象,當Channel中有數據可用時(shí),Channel會(huì )通知nsIStreamListener對象讀取數據。
在Mozilla中,實(shí)現的協(xié)議主要有:
1. nsHttpHandler 實(shí)現HTTP(S)協(xié)議,這是mozilla中最重要也是最復雜的協(xié)議,HTTP協(xié)議看似簡(jiǎn)單,不過(guò)要完整實(shí)現可不容易。比如處理ResCode 100,重定向,認證和Chunked數據等等,都是比較麻煩的。
2. nsFtpProtocolHandler 實(shí)現FTP協(xié)議,mozilla能夠像瀏覽網(wǎng)頁(yè)一樣,在瀏覽器中瀏覽FTP網(wǎng)站。FTP返回的結果是文本格式,不能直接在瀏覽器中瀏覽,要經(jīng)過(guò)nsFTPDirListingConv轉換之后才能顯示。
3. nsDataHandler 實(shí)現Data協(xié)議,它用來(lái)解碼URL中的BASE64編碼,感覺(jué)用處不大。
4. nsAboutProtocolHandler 實(shí)現About協(xié)議。用來(lái)顯示瀏覽器本身的一些信息,比如,about:plugins用來(lái)顯示已經(jīng)安裝的插件,about:config用來(lái)顯示和修改配置信息,about:buildconfig用來(lái)顯示編譯配置信息,about:cache用來(lái)顯示cache信息等等。
5. nsFileProtocolHandler 實(shí)現file協(xié)議,用來(lái)瀏覽本地文件,可以當簡(jiǎn)單的文件管理器使用。
6. nsKeywordProtocolHandler 實(shí)現Keyword協(xié)議,它只是對HTTP協(xié)議的包裝,它到指定的URL上去查詢(xún)某個(gè)關(guān)鍵字,估計可以當作搜索引擎使用。
7. nsViewSourceHandler 實(shí)現ViewSource協(xié)議,它是對其它協(xié)議的包裝,用來(lái)顯示HTML源代碼。
8. nsChromeProtocolHandler 實(shí)現Chrome協(xié)議,Chrome是mozilla自己的協(xié)議,它用來(lái)訪(fǎng)問(wèn)自己的資源文件,像locale、skin和XUL等等。它通過(guò)配置文件把chrome URI映射到物理文件上。
Mozilla還有其它一些協(xié)議的實(shí)現,而且它還可以通過(guò)GNomeVFS來(lái)支持更多協(xié)議,這里就不多說(shuō)了。
為了避免與框架的耦合,以上這些協(xié)議的實(shí)現都是通過(guò)Factory來(lái)創(chuàng )建的。在build/nsNetModule.cpp和build2/nsNetModule.cpp定義了這些協(xié)議實(shí)現的ComponentInfo,再通過(guò)一些宏和GenericFactory包裝生成自己的Factory。
所有這些協(xié)議都是作為服務(wù)提供的,也就是說(shuō)在整個(gè)系統中只有一份實(shí)例存在。在第一次使用該協(xié)議時(shí)創(chuàng )建其實(shí)例,使用完后并不銷(xiāo)毀,后來(lái)再使用時(shí),就取第一次創(chuàng )建的實(shí)例。
URL到協(xié)議實(shí)現的匹配過(guò)程是在nsIOService::GetProtocolHandler里完成的。因為協(xié)議實(shí)現的mContractID都是以"@mozilla.org/network/protocol;1?name="開(kāi)頭,后面再附加協(xié)議的Scheme,所以很容易從URL對應的協(xié)議實(shí)現上。
~~end~~
聯(lián)系客服