教你開發whistle插件

  • 2019 年 12 月 4 日
  • 筆記

whistle介紹

whistle是一款用Node實現的跨平台的Web調試代理工具,支援查看修改http(s)、Websocket連接的請求和響應內容。IMWEB團隊avenwu作品。github地址:https://github.com/avwo/whistle

whistle安裝啟動

1、安裝whistle

    npm install -g whistle

2、 啟動whistle

    w2 start  // 啟動whistle      w2 restart  // 重啟whsitle      w2 run  // 調試模式啟動whistle

3、 在瀏覽器中訪問

(1)域名訪問 http://local.whistlejs.com/ (2)通過ip+埠來訪問,例如: http://127.0.0.1:8899

whistle插件開發

現在想做一個基於whistle的查看請求參數的插件,並將參數以表格的形式展示在頁面上

插件命名規範

whistle插件本身就是一個普通的Node模組,只是名字要按照whistle.xxx的形式命名,其中xxx指插件的名稱且只能包含小寫字母、數字、_、-四種字元,如:whistle.tdw,而xxx就是擴展的協議,可以直接在Rules裡面配置使用

插件目錄結構

whistle.tdw      |__ package.json      |__ rules.txt      |__ index.js      |__ lib            |__ ui-server.js            |__ plugin-server.js

index.js提供whistle暴露給開發者的介面

// index.js  var initPluginServer = require('./lib/plugin-server');  var initUIServer = require('./lib/ui-server');    exports.statsServer = function(server, options) {      initPluginServer(server, options);  };    exports.uiServer = function(server, options) {      initUIServer(server, options);  };

statsServer : 處理請求的server,可以做請求合併等,返回的數據就是請求的響應數據, 如上: options 包含一些自定義的頭部欄位名稱及配置資訊

    {              name: // 插件的名稱,            RULE_VALUE_HEADER: // 存儲配置的規則值的請求頭欄位,            SSL_FLAG_HEADER: // 判斷是否為HTTPS請求的請求頭欄位,            FULL_URL_HEADER: // 存儲請求完整url的請求頭欄位,            REAL_URL_HEADER: // 存儲配置映射到url的請求頭欄位,            NEXT_RULE_HEADER: // 存儲配置的下個規則(第一規則為插件)的請求頭欄位,            REQ_ID_HEADER: // 請求的id,可以用於區分響應和請求是否同一個,            DATA_ID_HEADER: // 數據包對應的id,不一定存在,            STATUS_CODE_HEADER: // 配置的響應狀態碼,            LOCAL_HOST_HEADER: // 配置的hosts,            HOST_PORT_HEADER: // 配置的埠,            METHOD_HEADER: // 請求方法,            debugMode: // 是否是通過w2 run啟動的,            config: // 包括whistle的埠號port等一系列whistle的配置,            storage: //提供本地存儲的介面,用法參  考:https://github.com/avwo/whistle/blob/master/lib/rules/util.js        }

server是是whistle傳給插件的http.Server對象,開發者通過監聽server的相關事件處理whistle轉發過來的請求

uiServer: local.whistlejs.com/whistle.xxx下的請求都會直接訪問該server,可用於後台管理介面

插件調試

把本地node模組link到全局目錄:

npm link 開啟whistle的調試模式 $ w2 run 這樣whistle會自動載入改插件,如果插件有程式碼更新,需要觸發修改package.json這個文件,比如加個空格,或者直接加個欄位,每次修改下這個欄位,whistle會檢查package.json是否有更改,如果更改的話會自動重啟。

具體實現

//  lib/plugin-server.js    module.exports = function(server, options) {      FULL_URL_HEADER = options.FULL_URL_HEADER;      SSL_FLAG_HEADER = options.SSL_FLAG_HEADER;      server.on('request', app);      initHttpServer(app);  };    function initHttpServer(app) {      app.use(function(req, res, next) {          dataEvent.emit('data', {query: req.headers});          res.end('');      });  }

打開whistle,訪問https://ke.qq.com , 在network介面上能看到很多的請求

通過statsServer介面,我們能獲取這些請求。這裡通過事件將獲取到的請求傳遞到uiserver中

// ui-server.js    module.exports = function(server, options) {      FULL_URL_HEADER = options.FULL_URL_HEADER;      server.on('request', app);      var io = require('socket.io')(server);      initHttpServer(app);      initWSServer(io);  };    function initHttpServer(app) {      app.get('/', function(req, res) {          res.sendFile(path.join(htdocs, 'index.html'));      });        app.get('/js/*', function(req, res) {          res.sendFile(path.join(htdocs, 'js/index.js'));      });  }    function initWSServer(io) {      io.on('connection', function (socket) {          dataEvent.on('data', function(data) {              socket.emit('data', getUrl(data));          });      });  }

在瀏覽器中訪問http://local.whistlejs.com/whistle.tdw ,請求會直接訪問uiServer ,如上, uiServer處理請求,返回給瀏覽器相關的資源文件,展示介面。現在想實時的在頁面上展示請求的鏈接參數,選擇socket.io來實現 。 服務端與客戶端建立鏈接,將statsServer傳輸過來的數據,推給瀏覽器展示。

客戶端js:

// js/index.js  var io = require('socket.io-client');  var socket = io({    path: '/whistle.tdw/socket.io'  });    socket.on('data', function(data) {        var list = self.state.list;        list.unshift(decodeReport(data));        self.setState({            list: list        });    });

結果頁面展示

插件發布

同發布正常的node模組,模組編寫完畢, 通過 npm publish 發布