whistle – 跨平臺(Win/Mac/Linux)的 Fiddler

avwu發表於2016-07-05

web除錯代理工具是web開發人員必備的工具,它在發起web請求的客戶端與伺服器之間充當中間人角色,可以用於檢視、修改或替換HTTP、HTTPS、Websocket請求(響應)資料,協助我們做本地開發除錯、構造資料、定位問題等等,業界已有一些比較優秀的web除錯代理工具,特別是Windows上的Fiddler,由於其出色的功能設計,儼然成為了web除錯代理工具的代名詞。但Fiddler只能在Windows系統上使用,當我們換上Mac或者開發環境限制必須使用Linux時,我們很難在這些平臺上找到類似Fiddler的工具,這個時候可能被提起最多的是Charles,Charles是用Java實現的跨平臺web除錯代理工具,理論上可以在安裝java虛擬機器的桌面系統上使用,用過Fiddler的人普遍覺得Charles難用,不管是效能、體驗、介面都無法跟Fiddler相提並論(事實上Fiddler本身也是很耗記憶體),更重要的是Charles不是免費的,價格也不菲,這也可能是因為在Mac、Linux平臺上可以選擇的web除錯代理工具也不多,下面我要給大家詳細介紹的是本文的主角,開源免費且持續在維護的whistle–全新的跨平臺web除錯代理工具。

Note: 想了解除錯代理工具的原理可以看這篇文章:HTTP 代理原理及實現

whistle

Github: https://github.com/avwo/whistle

whistle是用NodeJS實現的跨平臺web除錯代理工具,可以安裝部署在裝有NodeJS的作業系統上(包括Windows、Mac、Linux等桌面或命令列系統),並可以通過Chrome瀏覽器訪問本地或遠端whistle的管理配置介面:

  • 檢視、修改或替換HTTP、HTTPS、Websocket請求(響應)資料(包括url,host,方法,狀態碼,頭部及內容等)

  • 設定延遲請求(響應)

  • 限制請求(響應)速度

  • 在Composer裡面構造請求

  • 可以把請求代理到其它伺服器(支援socks和http代理)

  • 檢視請求列表的Timeline

  • 檢視頁面JS指令碼執行過程中丟擲的異常(可以用在除錯終端頁面或遠端除錯)

  • 檢視JS中的console[info, log, warn, error, fatal](這些方法在IE也可以使用)列印出來的資料物件(可以用在除錯終端頁面或遠端除錯)

  • 利用whistle整合的weinre檢視或修改頁面的DOM結構(可以用在除錯終端頁面或遠端除錯)

  • 使用通過外掛的形式擴充套件的功能(外掛可以用來擴充套件whistle的功能,特別是整合本地開發環境,方便開發人員使用),如:處理combo請求

whistle借鑑了Fiddler的一些優秀的設計,比如請求列表及其詳細內容的展示(即Network),但whistle不是Fiddler的複製品,除了請求列表的展示外,whistle在操作請求及功能擴充套件上有著自己獨特的方式,讓修改請求(響應)操作變得更簡單,並整合了終端(遠端)除錯工具。

Note:為了讓大家能對下面內容更好的理解及快速上手whistle,請先按步驟安裝好whistle:安裝node、安裝whistle、配置代理、啟動whistle

規則原理

Fiddler修改請求(響應)的資料時,需要對每個請求設定斷點後–>手動修改–>手動放開請求,如果是同時修改多個請求或者多次修改某個請求時,體驗不是很好;而whistle把對請求(響應)的操作分類,每一類對應一種協議(如:替換本地檔案 file://),每個具體操作要用到的引數值放到協議後(如:file:///User/xxx/test.html中的/User/xxx/test.html),這樣whistle把每個操作抽象成一個uri

問題來了,如果引數值有空格或需要多個引數(比如修改頭部的一些欄位),這個whistle是怎麼處理的?

上述問題包含兩個問題:

  1. 如何引數值有空格的問題?
    在單引數情形下,如果是檔案路徑或者是下面第二個問題要提到的請求引數型別(如:file://filepathresAppend://filepathreqHeaders://test=a%20b&referer=test等),可以用%20來代替,其它情形,可以用{key}的形式把引數值存到whistle的Values系統,如:ua://{chrome-ua},whistle會自動到Values裡面找chrome-ua對應的值。

  2. 如何處理多個引數的情形?
    為方便使用者使用,whistle儘可能把一些常用的操作精簡到只有一個引數的情形(如請求頭部欄位,可以用協議req這種多引數的形式來新增或修改,對裡面常用的欄位,如refererua等也可以用獨立的協議(refererua)來設定),但不可能把把所有操作都抽象成單個引數的情形。對於多引數情形,有如下3種方式:

    • 直接用請求引數的方式轉成單引數的情形: reqHeaders://test=a%20b&referer=test,如果裡面有空格要用%20替換

    • 按問題1的方式,用key代替,把value寫到whistle的Values裡面(reqHeaders://{test-reqHeaders}),而Values裡面reqHeaders的值也可以有兩種方式具體參考:JSON格式

    • 直接把值寫到本地檔案(reqHeaders:///User/xxxx/test.json),檔案/User/xxxx/test.json裡面reqHeaders的值也可以有兩種方式具體參考:JSON格式

上面解決了把每個對web請求的操作用一個uri來表示的問題, 現在我們把對web請求的操作都可以抽象成一個operator-uri,如何用這些operator-uri來操作具體請求呢?

處理這個問題,whistle擴充套件了傳統hosts配置方式,採用匹配請求url到operator-uri的對映:

pattern  operator-uri

pattern可以以下三種方式:

  • 域名匹配:www.example.com operator-uri

  • 路徑匹配:www.example.com/... operator-uri

  • 正則匹配:/example/ operator-uri

為了相容hosts的配置方式:

# 單個匹配
127.0.0.1 www.example.com

# 多個匹配
127.0.0.1 www.example1.com www.example2.com www.exampleN.com

whistle預設匹配順序是從上到下,從左到右,多個匹配也可以寫成

# 多個匹配
pattern operator-uri1 operator-uri2 operator-uriN

如果whistle可以判斷operator-uri不可能為web請求的url,即不是如下uri形式:

# operator-uri協議為http, https, ws, wss之一
pattern http://xxxx

# operator-uri不包含協議,又不是ip
pattern xxxxx

或者pattern為正規表示式,滿足這兩種情況下,patternoperator-uri的順序是可以調換的:

# 單個匹配
operator-uri pattern
# 多個匹配的情況
operator-uri pattern1 pattern2 patternN

上面講了Rules的一些配置規則原理及Values的用途,包括:operator-uri設計原理,規則的匹配順序(從上到下,從左到右),匹配方式,什麼情況下可以對調等等。

一些例子

下面舉一些例子,讓大家快速上手whistle(規則中用#作為註釋符號,如果要檢視或修改HTTPS、Websocket的請求(響應)資料,要開啟HTTPS攔截功能:啟用HTTPS):

  1. host
    host的配置方式不僅完全相容系統自帶的配置方式,而且支援路徑、正則匹配:

    # 傳統的配置方式
    # 單個匹配
    127.0.0.1 www.ifeng.com
    # 多個匹配
    127.0.0.1 www.ifeng.com www.qq.com
        
    # 路徑(順序可以調換)
    # 單個匹配
    127.0.0.1 http://www.ifeng.com/xxx
    # 多個匹配
    127.0.0.1 http://www.ifeng.com www.qq.com/xxx
        
        
    #正則(順序可以調換)
    # 單個匹配
    127.0.0.1 /ifeng/
    # 多個匹配
    127.0.0.1 /ifeng/ /qq/
        
        
    # whistle也支援如下方式,在ip前面加個協議(順序可以調換)
    # 單個匹配
    host://127.0.0.1 www.ifeng.com
    # 多個匹配
    host://127.0.0.1 www.ifeng.com www.qq.com
  2. 埠對映(下面舉得例子都是用域名匹配的方式,其它方式同理)

    # 本地除錯
    www.example.com 127.0.0.1:8080
        
    # 對映到線上
    www.example.com www.qq.com
    www.example.com:8080  www.qq.com
  3. 本地替換

    # 下面用`|`來分隔目錄或檔案,從左到右依次找到存在的檔案為止
    www.example.com file:///User/xxx/test|/User/xxx/test/index.html

上述配置,如果我們訪問http://www.example.com/,則whistle會先找是否有/User/xxx/test這個檔案,如果沒有就會匹配/User/xxx/test/index.html;如果我們訪問http://www.example.com/test.html,則whistle會先在找檔案/User/xxx/test/test.html,再找/User/xxx/test/index.html/test.html,如果沒就返回404

這裡只是舉了幾個小例子,whistle還有非常多的功能,如:reqHeadersresHeaderslogdisablefilterweinre等等,而且還支援外掛擴充套件,更多功能請參考:Wiki功能列表

後續規劃

whistle是我業餘時間在維護且會長期維護的專案,一般來說新版本(如果有)的釋出放在週日晚上(修復影響功能的bug的版本不受時間限制,有新版本釋出介面中的About選單現會有紅點提醒或者大版本釋出則是直接彈框提醒,大家按提示更新就可以),下面是一些後面的規劃內容:

  1. 外掛whistle.websocket開發:用於檢視websocket的請求內容

  2. 外掛whistle.img開發:用於檢視抓包到的圖片內容

  3. 外掛whistle.settings開發:用於一鍵安裝系統代理及安裝根證照(如果根證照不能一鍵安裝,至少要做到點選能彈出根證照的安裝對話方塊),也為後面的客戶端版本做準備

  4. whistle的客戶端開發:有打算把一些自動化測試的功能整合進來,設想的互動功能也會比Node強很多,因為可以直接操作本地檔案

  5. 官網http://wproxy.org及文件建設:打算用Gitbook把文件重新整理,然後再i18n下及官網陸續建立起來

上面面規劃的功能都只是在業餘時間做,所以不能給出確切的完成時間,前面兩個外掛會盡快開發出來,想關注進度可以 Follow me:https://github.com/avwo

PS:為什麼不把websocket、img、settings這幾個外掛功能整合到whistle裡面,而要以外掛的形式單獨存在?主要是考慮到這幾部分功能用到的時候相對比較少,及減少安裝whistle過程中出現錯誤及執行過程中的記憶體問題,像處理websocket用到的中介軟體體積比較大且需要本地編譯,img功能有比較耗記憶體和硬碟,而且把這部分功能放在獨立的頁面可能體驗更好,綜上考慮沒有把這部分功能整合到whistle裡面,但後續的客戶端版本會直接整合進來。

說點什麼

  1. 如果什麼問題或建議可以給我提issue或加QQ群462558941

  2. 也歡迎大家直接PR

  3. 如果覺得whistle好用且對大家有幫助,幫忙分享給你所在的團隊及別忘了給whistle加個Star

相關文章