From 773fdc8a8e1f67a52f63cb06a87e753c3e8036d2 Mon Sep 17 00:00:00 2001 From: lqqyt2423 <974923609@qq.com> Date: Sun, 21 Nov 2021 19:33:51 +0800 Subject: [PATCH] web addon: add response hex view --- addon/web/client/src/components/ViewFlow.tsx | 21 +++++++++++++++++++- addon/web/client/src/message.ts | 14 ++++++++++++- addon/web/client/src/utils.ts | 17 ++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/addon/web/client/src/components/ViewFlow.tsx b/addon/web/client/src/components/ViewFlow.tsx index 0f3717d..d2588d9 100644 --- a/addon/web/client/src/components/ViewFlow.tsx +++ b/addon/web/client/src/components/ViewFlow.tsx @@ -16,7 +16,7 @@ interface Iprops { } interface IState { - flowTab: 'Headers' | 'Preview' | 'Response' + flowTab: 'Headers' | 'Preview' | 'Response' | 'Hexview' copied: boolean } @@ -53,6 +53,19 @@ class ViewFlow extends React.Component { return
Not support preview
} + hexview() { + const { flow } = this.props + if (!flow) return null + const response = flow.response + if (!response) return null + + if (!(response.body && response.body.byteLength)) { + return
No response
+ } + + return
{flow.hexviewResponseBody()}
+ } + render() { if (!this.props.flow) return null @@ -77,6 +90,7 @@ class ViewFlow extends React.Component { { this.setState({ flowTab: 'Headers' }) }}>Headers { this.setState({ flowTab: 'Preview' }) }}>Preview { this.setState({ flowTab: 'Response' }) }}>Response + { this.setState({ flowTab: 'Hexview' }) }}>Hexview { !(flowTab === 'Preview') ? null :
{this.preview()}
} + + { + !(flowTab === 'Hexview') ? null : +
{this.hexview()}
+ } diff --git a/addon/web/client/src/message.ts b/addon/web/client/src/message.ts index 6a07cf4..a77b289 100644 --- a/addon/web/client/src/message.ts +++ b/addon/web/client/src/message.ts @@ -1,4 +1,4 @@ -import { arrayBufferToBase64, getSize, isTextBody } from './utils' +import { arrayBufferToBase64, bufHexView, getSize, isTextBody } from './utils' export enum MessageType { REQUEST = 1, @@ -76,6 +76,7 @@ export class Flow { private _responseBody: string | null private _previewResponseBody: IPreviewResponseBody | null = null + private _hexviewResponseBody: string | null = null constructor(msg: IMessage) { this.no = ++Flow.curNo @@ -209,6 +210,17 @@ export class Flow { return this._previewResponseBody } + + public hexviewResponseBody(): string | null { + if (this._hexviewResponseBody) return this._hexviewResponseBody + + if (this.status < MessageType.RESPONSE_BODY) return null + if (!(this.response?.body?.byteLength)) return null + + this._hexviewResponseBody = bufHexView(this.response.body) + + return this._hexviewResponseBody + } } const allMessageBytes = [ diff --git a/addon/web/client/src/utils.ts b/addon/web/client/src/utils.ts index a28183e..4ef46e3 100644 --- a/addon/web/client/src/utils.ts +++ b/addon/web/client/src/utils.ts @@ -41,3 +41,20 @@ export const arrayBufferToBase64 = (buf: ArrayBuffer) => { } return btoa(binary) } + +export const bufHexView = (buf: ArrayBuffer) => { + let str = '' + const bytes = new Uint8Array(buf) + const len = bytes.byteLength + + str += '00000000: ' + for (let i = 0; i < len; i++) { + str += bytes[i].toString(16).padStart(2, '0') + ' ' + if ((i + 1) % 16 === 0) { + str += `\n${(i + 1).toString(16).padStart(8, '0')}: ` + } else if ((i + 1) % 8 === 0) { + str += ' ' + } + } + return str +}