#頭條創作挑戰賽#
gitweb是git自帶的一個網頁浏覽器,通過它可以在網頁上檢視代碼庫的各種資訊。
因為我想在它基礎上加個BUG跟蹤功能,是以這幾天研究了一下它的代碼。
它是用perl語言寫的一個CGI程式,具體怎麼部署在前一篇文章裡已經說過了,這裡再說一下它的代碼架構。
gitweb的主函數run()
1,gitweb的主函數是run()函數
如上圖,所有的網頁請求都在run()函數裡處理。
run()函數的結構非常簡單,先調用evaluate_argv()去處理輸入的各個參數,然後循環調用run_request()去處理網頁請求(直到處理完成)。
它的主要代碼,就在run_request()函數裡。
run_request()函數
2,run_request()函數
run_request()函數會首先運作一大堆的前置代碼,例如:解析網頁請求的uri,分析網頁請求的各個參數,确定要運作的CGI腳本的路徑,等等。
最後調用dispatch()函數,把這個網頁請求分發下去(繼續處理)。
dispatch在英語裡一般用來表示消息的分派,暗含着往下傳遞。
deliver一般用來表示消息的往上傳遞,例如資料包從IP層傳遞到TCP層,就叫diliver。
在網絡協定的分層裡,IP協定更接近硬體網卡,而TCP協定更接近應用程式。
這裡是從程式的主脈絡傳遞到具體的消息處理函數,是以叫dispatch()。
3,dispatch()函數
如下圖,dispatch()函數首先會進行一系列的檢測,以保證網頁通路的合法性。
它的大部分内容都是一些if else語句,最後是一個函數指針的調用。
dispatch()函數
這個函數指針是指針數組裡的某一項,它的索引就是網頁請求的參數。
當然指針數組是C語言的說法,perl語言裡叫哈希數組(散清單)。
哈希數組是由一個個的鍵值對構成的,“鍵”表示網頁請求的類型,“值"表示對應的處理函數。
是以,gitweb支援的所有網頁請求,就在這個actions哈希數組裡。
接下來,我們看看它的内容。
4,actions哈希數組
如下圖,前面的字元串是網頁請求的類型,後面的是對應的處理函數。
是以要是檢視某個代碼庫的日志,第3節的dispatch()函數實際調用的就是git_log()。
actions哈希數組
git_log()的實作如下圖,它隻是以"log"字元串為第一個參數,調用了通用的日志函數git_log_generic()。
git_log()函數
5,git_log_generic()函數
git_log_generic()的代碼比較長,但前面也是一些if else的檢查,它的關鍵代碼也隻有最後兩行。
git_log_generic(),第一張圖
如下圖,紅框裡的就是關鍵代碼,它調用了一個函數指針用來生成html的主體部分。
git_log_generic(),第二張圖
如果是生成簡短的日志,那麼這裡調用的函數就是git_shortlog_body()。
6,git_shortlog_body()函數
它的代碼如下,實際上就是生成了一個html的表格,用來顯示git日志。
其他請求的處理跟檢視日志的處理差不多,也是通過調用不同的函數指針實作的。
gitweb傳回的是一個html檔案,經過浏覽器的渲染之後,就是我們看到的網頁了。
git_shortlog_body()函數