background

Often we want to see some pages issued by the request, often will use CHARLES as a packet capture tool for interface capture, but on the one hand, the market is a lot of packet capture tools are charged or can not be secondary development. At present, most of our team also use CHARLES. However, it is relatively high for beginners to simply grab a package or modify and return data from the interface to start CHARLES directly, regardless of the cost of configuration and learning. So it is necessary for us in accordance with their best state to roll a suitable for their own grasp bag tools.

The results of

Based on the above appeal, we redesigned and modified the interaction by ourselves, and developed a simple desktop package capture tool that meets our appeal. The plugin itself can be integrated into UTools, but due to a lot of internal functions, we can’t release it through UTools, so we made a toolbox that can use all the ecology of UTools, Rubick. The package grabber tool is also based on Rubick’s plug-in tool.

Location of trial play:

Rubick: https://github.com/clouDr-f2e…

Caught plug-in: https://github.com/clouDr-f2e…

Let’s skip the code this time and look directly at the effect of the package capture tool we implemented:

Support HTTP/HTTPS request fetching.

Support Interface Mock

To complete the mock on the data of the interface, right-click the interface that you want to mock. All subsequent interface requests will go to that mock scenario:

Support for proxy forwarding

How to use

First we need to clone Rubick toolbox, he is a similar to utools toolbox based on Electron, warehouse address: Rubick: https://github.com/clouDr-f2e… You can then run it locally:

npm i
npm run dev

Then we should see something like this:

If you’re familiar with uTools, you can skip the next step.

When you are ready, copy the plugin.json from rubick-network to the input box of rubick and select New Plugin to see the plugin information:

Then open the plug-in, you can search for use!

Rubick’s biggest advantage over UTools is open source!! The community is welcome to work together to improve Rubick.

The technical implementation

Later we will introduce how to achieve such a capture package agent tool. Before the implementation of the capture package agent tool, first of all we need to go to self-study about NodeJS implementation of some knowledge points of the agent, here recommend a few good articles:

Principle and Implementation of HTTP Proxy (Part I)

Principle and Implementation of HTTP Proxy (Part II)

In simple terms, it is to implement a middleman. Users set up the agent, and the network request will be sent to the official server through the agent.

This middleman can be implemented in two ways.

One is an ordinary HTTP proxy, which starts an HTTP service through Node.js, sets our browser or mobile phone to the IP and port where the service is located, and then the HTTP traffic will pass through the proxy, thus achieving data interception.

For non-HTTP requests, such as HTTPS, or other application layer requests. We can listen for CONNECT requests by starting a TCP service in Node.js. Since the application layer is also based on the transport layer, data will first pass through the transport layer before reaching the application layer, so we can implement the transport layer data listening.

However, for requests caught by Connect, HTTP related information, including header information, cannot be retrieved. This is not useful for general front-end analysis, so in order to really listen to HTTPS, you need to support certificate related authentication.

There are also a lot of tutorials on how to generate certificates online, here is not redundant, you can baidu. However, after reading the design of others, it is easy to implement an HTTP proxy service by ourselves. However, in order to realize the function more quickly, we choose AnyProxy as the basic service and develop on the shoulders of giants.

AnyProxy provides a WebSocket service after installation. We only need to monitor the WebSocket port to dynamically display the data coming from the proxy:

function initWs(wsPort = 8002, path = 'do-not-proxy') { if(! WebSocket){ throw (new Error('WebSocket is not supported on this browser')); } const wsClient = new WebSocket(`ws://localhost:${wsPort}/${path}`); wsClient.onerror = (error) => { console.error(error); }; wsClient.onopen = (e) => { console.info('websocket opened: ', e); }; wsClient.onclose = (e) => { console.info('websocket closed: ', e); }; return wsClient; } // Connecting WebSocket const connectWs = () => {const wsClient = ws.initws (); wsClient.addEventListener('message', (e) => { const data = JSON.parse(e.data); store.commit('addRecord', data.content); }); }

However, AnyProxy only provides node-side capabilities, so Electron can just use NodeJS capabilities, that is, we can use Electron to implement NodeJS capabilities. Here, since we are plug-in, we refer to the design of utools and implement it as follows:

// preload.js const AnyProxy = require('anyproxy'); const options = { port: 8001, webInterface: { enable: true, webPort: 8002 }, forceProxyHttps: true, wsIntercept: False, // do not enable webSocket proxy silent: true}; class Network { constructor() { this.mockList = []; this.proxyServer = null; } initNetwork(op, { beforeSendRequest, beforeSendResponse, success, onRecord, }) { if (op === 'start') { if (! this.proxyServer || ! this.proxyServer.recorder) { const _this = this; options.rule = { *beforeSendRequest(requestDetail) { if (beforeSendRequest) { return beforeSendRequest(requestDetail); } return requestDetail }, *beforeSendResponse (requestDetail, responseDetail) { if (beforeSendResponse) { return beforeSendResponse(requestDetail, responseDetail); } return responseDetail; }}; this.proxyServer = new AnyProxy.ProxyServer(options); This.proxyServer. once('ready', () => {console.log(' boot complete '); success && success(this.proxyServer); }); } this.proxyServer.start(); } else { AnyProxy.utils.systemProxyMgr.disableGlobalProxy('http'); AnyProxy.utils.systemProxyMgr.disableGlobalProxy('https'); this.proxyServer.close(); success && success(); } } getIPAddress() { const interfaces = require('os').networkInterfaces(); for (const devName in interfaces) { const iface = interfaces[devName]; for (let i = 0; i < iface.length; i++) { const alias = iface[i]; if (alias.family === 'IPv4' && alias.address ! = = '127.0.0.1 &&! alias.internal) { return alias.address; } } } } }

Just add the implementation of AnyProxy service to Preload.js, and we can complete our demands!

conclusion

What is therubick ?

The Electron-based toolbox, comparable to the open source plug-in of UTools, has realized most of the API capabilities of UTools, so it can be seamlessly adapted to the open source plug-in of UTools. On the one hand, the reason for making this toolbox is that UTools itself is not open source, but the internal tool library of the company cannot be released into UTools plug-ins. Therefore, in order to enjoy the UTools ecology and have customized requirements, we made Rubick by referring to the design of UTools.

Please send us your PR and issues to help Rubick improve

Rubick: https://github.com/clouDr-f2e…

Related references:

Principle and Implementation of HTTP Proxy (Part I)

Principle and Implementation of HTTP Proxy (Part II)

Electron + Vue implements a proxy client