From 12449760f4a08ce54530afdabb9560cc54dff9ee Mon Sep 17 00:00:00 2001 From: liqiang <974923609@qq.com> Date: Tue, 23 Mar 2021 17:41:55 +0800 Subject: [PATCH] chore: websocket message protocol frontend --- addon/web/client/src/App.js | 14 +++-- addon/web/client/src/message.js | 105 ++++++++++++++++++++++++++++++++ addon/web/client/src/utils.js | 62 ------------------- 3 files changed, 115 insertions(+), 66 deletions(-) create mode 100644 addon/web/client/src/message.js diff --git a/addon/web/client/src/App.js b/addon/web/client/src/App.js index 825be28..7ab7d1a 100644 --- a/addon/web/client/src/App.js +++ b/addon/web/client/src/App.js @@ -5,7 +5,8 @@ import Button from 'react-bootstrap/Button' import './App.css' import { FlowManager } from './flow' -import { isTextResponse, getSize, parseMessage, buildMessage } from './utils' +import { isTextResponse, getSize } from './utils' +import { parseMessage, sendMessageEnum, buildMessageEdit, buildMessageMeta } from './message' class App extends React.Component { @@ -20,6 +21,7 @@ class App extends React.Component { flowTab: 'Headers', // Headers, Preview, Response + // TODO: change to rules interceptUriInputing: '', interceptUri: '', } @@ -40,7 +42,7 @@ class App extends React.Component { initWs() { if (this.ws) return - let host; + let host if (process.env.NODE_ENV === 'development') { host = 'localhost:9081' } else { @@ -107,7 +109,7 @@ class App extends React.Component { !flow.waitIntercept ? null :
{ diff --git a/addon/web/client/src/message.js b/addon/web/client/src/message.js new file mode 100644 index 0000000..10c2e2f --- /dev/null +++ b/addon/web/client/src/message.js @@ -0,0 +1,105 @@ +const messageEnum = { + 'request': 1, + 'requestBody': 2, + 'response': 3, + 'responseBody': 4, +} + +const allMessageBytes = Object.keys(messageEnum).map(k => messageEnum[k]) + +const messageByteMap = Object.keys(messageEnum).reduce((m, k) => { + m[messageEnum[k]] = k + return m +}, {}) + + +// type: 1/2/3/4 +// messageFlow +// version 1 byte + type 1 byte + id 36 byte + waitIntercept 1 byte + content left bytes +export const parseMessage = data => { + if (data.byteLength < 39) return null + const meta = new Int8Array(data.slice(0, 39)) + const version = meta[0] + if (version !== 1) return null + const type = meta[1] + if (!allMessageBytes.includes(type)) return null + const id = new TextDecoder().decode(data.slice(2, 38)) + const waitIntercept = meta[38] === 1 + + const resp = { + type: messageByteMap[type], + id, + waitIntercept, + } + if (data.byteLength === 39) return resp + if (type === messageEnum['requestBody'] || type === messageEnum['responseBody']) { + resp.content = data.slice(39) + return resp + } + + let content = new TextDecoder().decode(data.slice(39)) + try { + content = JSON.parse(content) + } catch (err) { + return null + } + + resp.content = content + return resp +} + + +export const sendMessageEnum = { + 'changeRequest': 11, + 'changeResponse': 12, + 'changeBreakPointRules': 21, +} + +// type: 11/12 +// messageEdit +// version 1 byte + type 1 byte + id 36 byte + header len 4 byte + header content bytes + body len 4 byte + [body content bytes] +export const buildMessageEdit = (messageType, flow) => { + let header, body + + if (messageType === sendMessageEnum.changeRequest) { + ({ body, ...header } = flow.request) + } else if (messageType === sendMessageEnum.changeResponse) { + ({ body, ...header } = flow.response) + } else { + throw new Error('invalid message type') + } + + const headerBytes = new TextEncoder().encode(JSON.stringify(header)) + const len = 2 + 36 + 4 + headerBytes.byteLength + 4 + body.byteLength + const data = new ArrayBuffer(len) + const view = new Uint8Array(data) + view[0] = 1 + view[1] = messageType + view.set(new TextEncoder().encode(flow.id), 3) + view.set(headerBytes, 2 + 36 + 4) + view.set(body, 2 + 36 + 4 + headerBytes.byteLength + 4) + + const view2 = new DataView(data) + view2.setUint32(2 + 36, headerBytes.byteLength) + view2.setUint32(2 + 36 + 4 + headerBytes.byteLength, body.byteLength) + + return view +} + + +// type: 21 +// messageMeta +// version 1 byte + type 1 byte + content left bytes +export const buildMessageMeta = (messageType, rules) => { + if (messageType !== sendMessageEnum.changeBreakPointRules) { + throw new Error('invalid message type') + } + + const rulesBytes = new TextEncoder().encode(JSON.stringify(rules)) + const view = new Uint8Array(2 + rulesBytes.byteLength) + view[0] = 1 + view[1] = messageType + view.set(rulesBytes, 2) + + return view +} diff --git a/addon/web/client/src/utils.js b/addon/web/client/src/utils.js index 6bb4b8b..73caa4b 100644 --- a/addon/web/client/src/utils.js +++ b/addon/web/client/src/utils.js @@ -24,65 +24,3 @@ export const getSize = response => { if (len < 1024*1024) return `${(len/1024).toFixed(2)} KB` return `${(len/(1024*1024)).toFixed(2)} MB` } - -const messageEnum = { - 'request': 1, - 'requestBody': 2, - 'response': 3, - 'responseBody': 4, -} - -const allMessageBytes = Object.keys(messageEnum).map(k => messageEnum[k]) - -const messageByteMap = Object.keys(messageEnum).reduce((m, k) => { - m[messageEnum[k]] = k - return m -}, {}) - -export const parseMessage = data => { - if (data.byteLength < 39) return null - const meta = new Int8Array(data.slice(0, 3)) - const version = meta[0] - if (version !== 1) return null - const type = meta[1] - if (!allMessageBytes.includes(type)) return null - const id = new TextDecoder().decode(data.slice(3, 39)) - - const resp = { - type: messageByteMap[type], - id, - waitIntercept: meta[2] === 1, - } - if (data.byteLength === 39) return resp - if (type === messageEnum['requestBody'] || type === messageEnum['responseBody']) { - resp.content = data.slice(39) - return resp - } - - let content = new TextDecoder().decode(data.slice(39)) - try { - content = JSON.parse(content) - } catch (err) { - return null - } - - resp.content = content - return resp -} - -/** - * - * @param {number} messageType - * @param {string} id - * @param {string} content - */ -export const buildMessage = (messageType, id, content) => { - content = new TextEncoder().encode(content) - const data = new Uint8Array(39 + content.byteLength) - data[0] = 1 - data[1] = messageType - data[2] = 0 - data.set(new TextEncoder().encode(id), 3) - data.set(content, 39) - return data -}