You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 line
71 KiB
Plaintext
1 line
71 KiB
Plaintext
{"version":3,"sources":["components/BreakPoint.tsx","utils.ts","message.ts","components/FlowPreview.tsx","components/EditFlow.tsx","components/ViewFlow.tsx","flow.ts","App.tsx","reportWebVitals.ts","index.tsx"],"names":["BreakPoint","props","state","show","rule","method","url","action","haveRules","handleClose","bind","handleShow","handleSave","this","setState","rules","push","onSave","length","variant","Button","size","onClick","Modal","onHide","Header","closeButton","Title","Body","Form","Group","as","Row","Label","column","sm","Col","Control","value","onChange","e","target","parseInt","Footer","React","Component","isTextBody","payload","header","test","join","getSize","len","isNaN","toFixed","arrayBufferToBase64","buf","binary","bytes","Uint8Array","byteLength","i","String","fromCharCode","btoa","bufHexView","str","viewStr","toString","padStart","MessageType","FlowPreview","nextProps","isSelected","objA","objB","keysA","Object","keys","keysB","key","undefined","shallowEqual","flow","fp","classNames","waitIntercept","className","onShowDetail","no","host","path","contentType","statusCode","costTime","Flow","msg","id","request","response","_size","headerContentLengthExist","startTime","Date","now","endTime","status","REQUEST","_isTextRequest","_isTextResponse","_requestBody","_hexviewRequestBody","_responseBody","_previewResponseBody","_previewRequestBody","_hexviewResponseBody","curNo","content","URL","pathname","search","REQUEST_BODY","body","RESPONSE","split","includes","RESPONSE_BODY","isTextRequest","TextDecoder","decode","isTextResponse","startsWith","type","data","responseBody","requestBody","hexviewRequestBody","SendMessageType","allMessageBytes","buildMessageEdit","messageType","DROP_REQUEST","DROP_RESPONSE","view","set","TextEncoder","encode","CHANGE_REQUEST","CHANGE_RESPONSE","Error","ArrayBuffer","bodyLen","headerBytes","JSON","stringify","view2","DataView","setUint32","EditFlow","alertMsg","firstLine","headerLines","map","valstr","bodyLines","stringifyRequest","stringifyResponse","when","firstIndex","indexOf","slice","secondIndex","vals","proto","parseRequest","showAlert","onChangeRequest","parseResponse","onChangeResponse","msgType","onMessage","rows","Alert","ViewFlow","flowTab","copied","requestBodyViewTab","responseBodyLineBreak","style","color","pv","previewResponseBody","src","keyStyle","stringStyle","valueStyle","booleanStyle","previewRequestBody","hexviewResponseBody","searchItems","searchParams","forEach","onClose","onReRenderFlows","padding","disabled","curl","fetchToCurl","headers","reduce","obj","copy","setTimeout","marginBottom","requestBodyPreview","FormCheck","inline","checked","label","whiteSpace","preview","hexview","FlowManager","items","_map","filterText","filterTimer","num","max","Map","text","trim","endsWith","reg","RegExp","filter","item","err","oldest","shift","delete","get","callback","clearTimeout","wsReconnIntervals","App","flowMgr","ws","wsUnmountClose","tableBottomRef","wsReconnCount","flows","showList","wsStatus","createRef","initWs","close","document","WebSocket","binaryType","onopen","onerror","evt","console","error","onclose","waitSeconds","info","onmessage","meta","Int8Array","resp","contentStr","parse","parseMessage","add","shouldScroll","current","element","viewWidth","window","innerWidth","documentElement","clientWidth","viewHeight","innerHeight","clientHeight","getBoundingClientRect","top","right","bottom","left","isInViewPort","scrollIntoView","behavior","addRequestBody","addResponse","addResponseBody","clear","placeholder","changeFilterLazy","CHANGE_BREAK_POINT_RULES","rulesBytes","buildMessageMeta","send","Table","striped","bordered","tableLayout","width","f","ref","height","visibility","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.dab9e469.chunk.js","sourcesContent":["import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport Modal from 'react-bootstrap/Modal'\nimport Form from 'react-bootstrap/Form'\nimport Row from 'react-bootstrap/Row'\nimport Col from 'react-bootstrap/Col'\n\ntype Method = 'ALL' | 'GET' | 'POST' | 'PUT' | 'DELETE' | ''\ntype Action = 1 | 2 | 3\ninterface IRule {\n method: Method\n url: string\n action: Action\n}\n\ninterface IState {\n show: boolean\n rule: IRule\n haveRules: boolean\n}\n\ninterface IProps {\n onSave: (rules: IRule[]) => void\n}\n\nclass BreakPoint extends React.Component<IProps, IState> {\n constructor(props: IProps) {\n super(props)\n\n this.state = {\n show: false,\n\n rule: {\n method: 'ALL',\n url: '',\n action: 1,\n },\n\n haveRules: false,\n }\n\n this.handleClose = this.handleClose.bind(this)\n this.handleShow = this.handleShow.bind(this)\n this.handleSave = this.handleSave.bind(this)\n }\n\n handleClose() {\n this.setState({ show: false })\n }\n\n handleShow() {\n this.setState({ show: true })\n }\n\n handleSave() {\n const { rule } = this.state\n const rules: IRule[] = []\n if (rule.url) {\n rules.push({\n method: rule.method === 'ALL' ? '' : rule.method,\n url: rule.url,\n action: rule.action,\n })\n }\n\n this.props.onSave(rules)\n this.handleClose()\n\n this.setState({ haveRules: rules.length ? true : false })\n }\n\n render() {\n const { rule, haveRules } = this.state\n const variant = haveRules ? 'success' : 'primary'\n\n return (\n <div>\n <Button variant={variant} size=\"sm\" onClick={this.handleShow}>BreakPoint</Button>\n\n <Modal show={this.state.show} onHide={this.handleClose}>\n <Modal.Header closeButton>\n <Modal.Title>Set BreakPoint</Modal.Title>\n </Modal.Header>\n\n <Modal.Body>\n <Form.Group as={Row}>\n <Form.Label column sm={2}>Method</Form.Label>\n <Col sm={10}>\n <Form.Control as=\"select\" value={rule.method} onChange={e => { this.setState({ rule: { ...rule, method: e.target.value as Method } }) }}>\n <option>ALL</option>\n <option>GET</option>\n <option>POST</option>\n <option>PUT</option>\n <option>DELETE</option>\n </Form.Control>\n </Col>\n </Form.Group>\n\n <Form.Group as={Row}>\n <Form.Label column sm={2}>URL</Form.Label>\n <Col sm={10}><Form.Control value={rule.url} onChange={e => { this.setState({ rule: { ...rule, url: e.target.value } }) }} /></Col>\n </Form.Group>\n\n <Form.Group as={Row}>\n <Form.Label column sm={2}>Action</Form.Label>\n <Col sm={10}>\n <Form.Control as=\"select\" value={rule.action} onChange={e => { this.setState({ rule: { ...rule, action: parseInt(e.target.value) as Action } }) }}>\n <option value=\"1\">Request</option>\n <option value=\"2\">Response</option>\n <option value=\"3\">Both</option>\n </Form.Control>\n </Col>\n </Form.Group>\n </Modal.Body>\n\n <Modal.Footer>\n <Button variant=\"secondary\" onClick={this.handleClose}>\n Close\n </Button>\n <Button variant=\"primary\" onClick={this.handleSave}>\n Save\n </Button>\n </Modal.Footer>\n </Modal>\n </div>\n )\n }\n}\n\nexport default BreakPoint\n","import { IRequest, IResponse } from './message'\n\nexport const isTextBody = (payload: IRequest | IResponse) => {\n if (!payload) return false\n if (!payload.header) return false\n if (!payload.header['Content-Type']) return false\n\n return /text|javascript|json|x-www-form-urlencoded|xml|form-data/.test(payload.header['Content-Type'].join(''))\n}\n\nexport const getSize = (len: number) => {\n if (!len) return '0'\n if (isNaN(len)) return '0'\n if (len <= 0) return '0'\n\n if (len < 1024) return `${len} B`\n if (len < 1024 * 1024) return `${(len / 1024).toFixed(2)} KB`\n return `${(len / (1024 * 1024)).toFixed(2)} MB`\n}\n\nexport const shallowEqual = (objA: any, objB: any) => {\n if (objA === objB) return true\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n if (keysA.length !== keysB.length) return false\n\n for (let i = 0; i < keysA.length; i++) {\n const key = keysA[i]\n if (objB[key] === undefined || objA[key] !== objB[key]) return false\n }\n return true\n}\n\nexport const arrayBufferToBase64 = (buf: ArrayBuffer) => {\n let binary = ''\n const bytes = new Uint8Array(buf)\n const len = bytes.byteLength\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i])\n }\n return btoa(binary)\n}\n\nexport const bufHexView = (buf: ArrayBuffer) => {\n let str = ''\n const bytes = new Uint8Array(buf)\n const len = bytes.byteLength\n\n let viewStr = ''\n\n str += '00000000: '\n for (let i = 0; i < len; i++) {\n str += bytes[i].toString(16).padStart(2, '0') + ' '\n\n if (bytes[i] >= 32 && bytes[i] <= 126) {\n viewStr += String.fromCharCode(bytes[i])\n } else {\n viewStr += '.'\n }\n\n if ((i + 1) % 16 === 0) {\n str += ' ' + viewStr\n viewStr = ''\n str += `\\n${(i + 1).toString(16).padStart(8, '0')}: `\n } else if ((i + 1) % 8 === 0) {\n str += ' '\n }\n }\n\n // 补充最后一行的空白\n if (viewStr.length > 0) {\n for (let i = viewStr.length; i < 16; i++) {\n str += ' ' + ' '\n if ((i + 1) % 8 === 0) str += ' '\n }\n str += ' ' + viewStr\n }\n\n return str\n}\n\n// https://github.com/febobo/web-interview/issues/84\nexport function isInViewPort(element: HTMLElement) {\n const viewWidth = window.innerWidth || document.documentElement.clientWidth\n const viewHeight = window.innerHeight || document.documentElement.clientHeight\n const {\n top,\n right,\n bottom,\n left,\n } = element.getBoundingClientRect()\n\n return (\n top >= 0 &&\n left >= 0 &&\n right <= viewWidth &&\n bottom <= viewHeight\n )\n}\n","import { arrayBufferToBase64, bufHexView, getSize, isTextBody } from './utils'\n\nexport enum MessageType {\n REQUEST = 1,\n REQUEST_BODY = 2,\n RESPONSE = 3,\n RESPONSE_BODY = 4,\n}\n\nexport type Header = Record<string, string[]>\n\nexport interface IRequest {\n method: string\n url: string\n proto: string\n header: Header\n body?: ArrayBuffer\n}\n\nexport interface IResponse {\n statusCode: number\n header: Header\n body?: ArrayBuffer\n}\n\nexport interface IMessage {\n type: MessageType\n id: string\n waitIntercept: boolean\n content?: ArrayBuffer | IRequest | IResponse\n}\n\nexport interface IFlowPreview {\n no: number\n id: string\n waitIntercept: boolean\n host: string\n path: string\n method: string\n statusCode: string\n size: string\n costTime: string\n contentType: string\n}\n\ninterface IPreviewBody {\n type: 'image' | 'json' | 'binary'\n data: string | null\n}\n\nexport class Flow {\n public no: number\n public id: string\n public waitIntercept: boolean\n public request: IRequest\n public response: IResponse | null = null\n\n public url: URL\n private path: string\n private _size = 0\n private size = '0'\n private headerContentLengthExist = false\n private contentType = ''\n\n private startTime = Date.now()\n private endTime = 0\n private costTime = '(pending)'\n\n public static curNo = 0\n\n private status: MessageType = MessageType.REQUEST\n\n private _isTextRequest: boolean | null\n private _isTextResponse: boolean | null\n private _requestBody: string | null\n private _hexviewRequestBody: string | null = null\n private _responseBody: string | null\n\n private _previewResponseBody: IPreviewBody | null = null\n private _previewRequestBody: IPreviewBody | null = null\n private _hexviewResponseBody: string | null = null\n\n constructor(msg: IMessage) {\n this.no = ++Flow.curNo\n this.id = msg.id\n this.waitIntercept = msg.waitIntercept\n this.request = msg.content as IRequest\n\n this.url = new URL(this.request.url)\n this.path = this.url.pathname + this.url.search\n\n this._isTextRequest = null\n this._isTextResponse = null\n this._requestBody = null\n this._responseBody = null\n }\n\n public addRequestBody(msg: IMessage): Flow {\n this.status = MessageType.REQUEST_BODY\n this.waitIntercept = msg.waitIntercept\n this.request.body = msg.content as ArrayBuffer\n return this\n }\n\n public addResponse(msg: IMessage): Flow {\n this.status = MessageType.RESPONSE\n this.waitIntercept = msg.waitIntercept\n this.response = msg.content as IResponse\n\n if (this.response && this.response.header) {\n if (this.response.header['Content-Type'] != null) {\n this.contentType = this.response.header['Content-Type'][0].split(';')[0]\n if (this.contentType.includes('javascript')) this.contentType = 'javascript'\n }\n if (this.response.header['Content-Length'] != null) {\n this.headerContentLengthExist = true\n this._size = parseInt(this.response.header['Content-Length'][0])\n this.size = getSize(this._size)\n }\n }\n\n return this\n }\n\n public addResponseBody(msg: IMessage): Flow {\n this.status = MessageType.RESPONSE_BODY\n this.waitIntercept = msg.waitIntercept\n if (this.response) this.response.body = msg.content as ArrayBuffer\n this.endTime = Date.now()\n this.costTime = String(this.endTime - this.startTime) + ' ms'\n\n if (!this.headerContentLengthExist && this.response && this.response.body) {\n this._size = this.response.body.byteLength\n this.size = getSize(this._size)\n }\n return this\n }\n\n public preview(): IFlowPreview {\n return {\n no: this.no,\n id: this.id,\n waitIntercept: this.waitIntercept,\n host: this.url.host,\n path: this.path,\n method: this.request.method,\n statusCode: this.response ? String(this.response.statusCode) : '(pending)',\n size: this.size,\n costTime: this.costTime,\n contentType: this.contentType,\n }\n }\n\n public isTextRequest(): boolean {\n if (this._isTextRequest !== null) return this._isTextRequest\n this._isTextRequest = isTextBody(this.request)\n return this._isTextRequest\n }\n\n public requestBody(): string {\n if (this._requestBody !== null) return this._requestBody\n if (!this.isTextRequest()) {\n this._requestBody = ''\n return this._requestBody\n }\n if (this.status < MessageType.REQUEST_BODY) return ''\n this._requestBody = new TextDecoder().decode(this.request.body)\n return this._requestBody\n }\n\n public hexviewRequestBody(): string | null {\n if (this._hexviewRequestBody !== null) return this._hexviewRequestBody\n if (this.status < MessageType.REQUEST_BODY) return null\n if (!(this.request?.body?.byteLength)) return null\n\n this._hexviewRequestBody = bufHexView(this.request.body)\n return this._hexviewRequestBody\n }\n\n public isTextResponse(): boolean | null {\n if (this.status < MessageType.RESPONSE) return null\n if (this._isTextResponse !== null) return this._isTextResponse\n this._isTextResponse = isTextBody(this.response as IResponse)\n return this._isTextResponse\n }\n\n public responseBody(): string {\n if (this._responseBody !== null) return this._responseBody\n if (this.status < MessageType.RESPONSE) return ''\n if (!this.isTextResponse()) {\n this._responseBody = ''\n return this._responseBody\n }\n if (this.status < MessageType.RESPONSE_BODY) return ''\n this._responseBody = new TextDecoder().decode(this.response?.body)\n return this._responseBody\n }\n\n public previewResponseBody(): IPreviewBody | null {\n if (this._previewResponseBody) return this._previewResponseBody\n\n if (this.status < MessageType.RESPONSE_BODY) return null\n if (!(this.response?.body?.byteLength)) return null\n\n let contentType: string | undefined\n if (this.response.header['Content-Type']) contentType = this.response.header['Content-Type'][0]\n if (!contentType) return null\n\n if (contentType.startsWith('image/')) {\n this._previewResponseBody = {\n type: 'image',\n data: arrayBufferToBase64(this.response.body),\n }\n }\n else if (contentType.includes('application/json')) {\n this._previewResponseBody = {\n type: 'json',\n data: this.responseBody(),\n }\n }\n\n return this._previewResponseBody\n }\n\n public previewRequestBody(): IPreviewBody | null {\n if (this._previewRequestBody) return this._previewRequestBody\n\n if (this.status < MessageType.REQUEST_BODY) return null\n if (!(this.request.body?.byteLength)) return null\n\n if (!this.isTextRequest()) {\n this._previewRequestBody = {\n type: 'binary',\n data: this.hexviewRequestBody(),\n }\n } else if (/json/.test(this.request.header['Content-Type'].join(''))) {\n this._previewRequestBody = {\n type: 'json',\n data: this.requestBody(),\n }\n }\n\n return this._previewRequestBody\n }\n\n public hexviewResponseBody(): string | null {\n if (this._hexviewResponseBody !== null) return this._hexviewResponseBody\n\n if (this.status < MessageType.RESPONSE_BODY) return null\n if (!(this.response?.body?.byteLength)) return null\n\n this._hexviewResponseBody = bufHexView(this.response.body)\n return this._hexviewResponseBody\n }\n}\n\nconst allMessageBytes = [\n MessageType.REQUEST,\n MessageType.REQUEST_BODY,\n MessageType.RESPONSE,\n MessageType.RESPONSE_BODY,\n]\n\n\n// type: 1/2/3/4\n// messageFlow\n// version 1 byte + type 1 byte + id 36 byte + waitIntercept 1 byte + content left bytes\nexport const parseMessage = (data: ArrayBuffer): IMessage | null => {\n if (data.byteLength < 39) return null\n const meta = new Int8Array(data.slice(0, 39))\n const version = meta[0]\n if (version !== 1) return null\n const type = meta[1] as MessageType\n if (!allMessageBytes.includes(type)) return null\n const id = new TextDecoder().decode(data.slice(2, 38))\n const waitIntercept = meta[38] === 1\n\n const resp: IMessage = {\n type,\n id,\n waitIntercept,\n }\n if (data.byteLength === 39) return resp\n if (type === MessageType.REQUEST_BODY || type === MessageType.RESPONSE_BODY) {\n resp.content = data.slice(39)\n return resp\n }\n\n const contentStr = new TextDecoder().decode(data.slice(39))\n let content: any\n try {\n content = JSON.parse(contentStr)\n } catch (err) {\n return null\n }\n\n resp.content = content\n return resp\n}\n\n\nexport enum SendMessageType {\n CHANGE_REQUEST = 11,\n CHANGE_RESPONSE = 12,\n DROP_REQUEST = 13,\n DROP_RESPONSE = 14,\n CHANGE_BREAK_POINT_RULES = 21,\n}\n\n// type: 11/12/13/14\n// messageEdit\n// version 1 byte + type 1 byte + id 36 byte + header len 4 byte + header content bytes + body len 4 byte + [body content bytes]\nexport const buildMessageEdit = (messageType: SendMessageType, flow: Flow) => {\n if (messageType === SendMessageType.DROP_REQUEST || messageType === SendMessageType.DROP_RESPONSE) {\n const view = new Uint8Array(38)\n view[0] = 1\n view[1] = messageType\n view.set(new TextEncoder().encode(flow.id), 2)\n return view\n }\n\n let header: Omit<IRequest, 'body'> | Omit<IResponse, 'body'>\n let body: ArrayBuffer | Uint8Array | undefined\n\n if (messageType === SendMessageType.CHANGE_REQUEST) {\n ({ body, ...header } = flow.request)\n } else if (messageType === SendMessageType.CHANGE_RESPONSE) {\n ({ body, ...header } = flow.response as IResponse)\n } else {\n throw new Error('invalid message type')\n }\n\n if (body instanceof ArrayBuffer) body = new Uint8Array(body)\n const bodyLen = (body && body.byteLength) ? body.byteLength : 0\n\n if ('Content-Encoding' in header.header) delete header.header['Content-Encoding']\n if ('Transfer-Encoding' in header.header) delete header.header['Transfer-Encoding']\n header.header['Content-Length'] = [String(bodyLen)]\n\n const headerBytes = new TextEncoder().encode(JSON.stringify(header))\n const len = 2 + 36 + 4 + headerBytes.byteLength + 4 + bodyLen\n const data = new ArrayBuffer(len)\n const view = new Uint8Array(data)\n view[0] = 1\n view[1] = messageType\n view.set(new TextEncoder().encode(flow.id), 2)\n view.set(headerBytes, 2 + 36 + 4)\n if (bodyLen) view.set(body as Uint8Array, 2 + 36 + 4 + headerBytes.byteLength + 4)\n\n const view2 = new DataView(data)\n view2.setUint32(2 + 36, headerBytes.byteLength)\n view2.setUint32(2 + 36 + 4 + headerBytes.byteLength, bodyLen)\n\n return view\n}\n\n\n// type: 21\n// messageMeta\n// version 1 byte + type 1 byte + content left bytes\nexport const buildMessageMeta = (messageType: SendMessageType, rules: any) => {\n if (messageType !== SendMessageType.CHANGE_BREAK_POINT_RULES) {\n throw new Error('invalid message type')\n }\n\n const rulesBytes = new TextEncoder().encode(JSON.stringify(rules))\n const view = new Uint8Array(2 + rulesBytes.byteLength)\n view[0] = 1\n view[1] = messageType\n view.set(rulesBytes, 2)\n\n return view\n}\n","import React from 'react'\nimport { IFlowPreview } from '../message'\nimport { shallowEqual } from '../utils'\n\ninterface IProps {\n flow: IFlowPreview\n isSelected: boolean\n onShowDetail: () => void\n}\n\nclass FlowPreview extends React.Component<IProps> {\n shouldComponentUpdate(nextProps: IProps) {\n if (nextProps.isSelected === this.props.isSelected && shallowEqual(nextProps.flow, this.props.flow)) {\n return false\n }\n return true\n }\n\n render() {\n const fp = this.props.flow\n\n const classNames = []\n if (this.props.isSelected) classNames.push('tr-selected')\n if (fp.waitIntercept) classNames.push('tr-wait-intercept')\n\n return (\n <tr className={classNames.length ? classNames.join(' ') : undefined}\n onClick={() => {\n this.props.onShowDetail()\n }}\n >\n <td>{fp.no}</td>\n <td>{fp.method}</td>\n <td>{fp.host}</td>\n <td>{fp.path}</td>\n <td>{fp.contentType}</td>\n <td>{fp.statusCode}</td>\n <td>{fp.size}</td>\n <td>{fp.costTime}</td>\n </tr>\n )\n }\n}\n\nexport default FlowPreview\n","import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport Modal from 'react-bootstrap/Modal'\nimport Form from 'react-bootstrap/Form'\nimport Alert from 'react-bootstrap/Alert'\n\nimport { SendMessageType, buildMessageEdit, IRequest, IResponse, Header, Flow } from '../message'\nimport { isTextBody } from '../utils'\n\n\nconst stringifyRequest = (request: IRequest) => {\n const firstLine = `${request.method} ${request.url}`\n const headerLines = Object.keys(request.header).map(key => {\n const valstr = request.header[key].join(' \\t ') // for parse convenience\n return `${key}: ${valstr}`\n }).join('\\n')\n\n let bodyLines = ''\n if (request.body && isTextBody(request)) bodyLines = new TextDecoder().decode(request.body)\n\n return `${firstLine}\\n\\n${headerLines}\\n\\n${bodyLines}`\n}\n\nconst parseRequest = (content: string): IRequest | undefined => {\n const firstIndex = content.indexOf('\\n\\n')\n if (firstIndex <= 0) return\n\n const firstLine = content.slice(0, firstIndex)\n const [method, url] = firstLine.split(' ')\n if (!method || !url) return\n\n const secondIndex = content.indexOf('\\n\\n', firstIndex + 2)\n if (secondIndex <= 0) return\n const headerLines = content.slice(firstIndex + 2, secondIndex)\n const header: Header = {}\n for (const line of headerLines.split('\\n')) {\n const [key, vals] = line.split(': ')\n if (!key || !vals) return\n header[key] = vals.split(' \\t ')\n }\n\n const bodyLines = content.slice(secondIndex + 2)\n let body: ArrayBuffer | undefined\n if (bodyLines) body = new TextEncoder().encode(bodyLines)\n\n return {\n method,\n url,\n proto: '',\n header,\n body,\n }\n}\n\nconst stringifyResponse = (response: IResponse) => {\n const firstLine = `${response.statusCode}`\n const headerLines = Object.keys(response.header).map(key => {\n const valstr = response.header[key].join(' \\t ') // for parse convenience\n return `${key}: ${valstr}`\n }).join('\\n')\n\n let bodyLines = ''\n if (response.body && isTextBody(response)) bodyLines = new TextDecoder().decode(response.body)\n\n return `${firstLine}\\n\\n${headerLines}\\n\\n${bodyLines}`\n}\n\nconst parseResponse = (content: string): IResponse | undefined => {\n const firstIndex = content.indexOf('\\n\\n')\n if (firstIndex <= 0) return\n\n const firstLine = content.slice(0, firstIndex)\n const statusCode = parseInt(firstLine)\n if (isNaN(statusCode)) return\n\n const secondIndex = content.indexOf('\\n\\n', firstIndex + 2)\n if (secondIndex <= 0) return\n const headerLines = content.slice(firstIndex + 2, secondIndex)\n const header: Header = {}\n for (const line of headerLines.split('\\n')) {\n const [key, vals] = line.split(': ')\n if (!key || !vals) return\n header[key] = vals.split(' \\t ')\n }\n\n const bodyLines = content.slice(secondIndex + 2)\n let body: ArrayBuffer | undefined\n if (bodyLines) body = new TextEncoder().encode(bodyLines)\n\n return {\n statusCode,\n header,\n body,\n }\n}\n\n\ninterface IProps {\n flow: Flow\n onChangeRequest: (request: IRequest) => void\n onChangeResponse: (response: IResponse) => void\n onMessage: (msg: ArrayBufferLike) => void\n}\n\ninterface IState {\n show: boolean\n alertMsg: string\n content: string\n}\n\nclass EditFlow extends React.Component<IProps, IState> {\n constructor(props: IProps) {\n super(props)\n\n this.state = {\n show: false,\n alertMsg: '',\n content: '',\n }\n\n this.handleClose = this.handleClose.bind(this)\n this.handleShow = this.handleShow.bind(this)\n this.handleSave = this.handleSave.bind(this)\n }\n\n showAlert(msg: string) {\n this.setState({ alertMsg: msg })\n }\n\n handleClose() {\n this.setState({ show: false })\n }\n\n handleShow() {\n const { flow } = this.props\n const when = flow.response ? 'response' : 'request'\n\n let content = ''\n if (when === 'request') {\n content = stringifyRequest(flow.request)\n } else {\n content = stringifyResponse(flow.response as IResponse)\n }\n\n this.setState({ show: true, alertMsg: '', content })\n }\n\n handleSave() {\n const { flow } = this.props\n const when = flow.response ? 'response' : 'request'\n\n const { content } = this.state\n\n if (when === 'request') {\n const request = parseRequest(content)\n if (!request) {\n this.showAlert('parse error')\n return\n }\n\n this.props.onChangeRequest(request)\n this.handleClose()\n } else {\n const response = parseResponse(content)\n if (!response) {\n this.showAlert('parse error')\n return\n }\n\n this.props.onChangeResponse(response)\n this.handleClose()\n }\n }\n\n render() {\n const { flow } = this.props\n if (!flow.waitIntercept) return null\n\n const { alertMsg } = this.state\n\n const when = flow.response ? 'response' : 'request'\n\n return (\n <div className=\"flow-wait-area\">\n\n <Button size=\"sm\" onClick={this.handleShow}>Edit</Button>\n\n <Button size=\"sm\" onClick={() => {\n const msgType = when === 'response' ? SendMessageType.CHANGE_RESPONSE : SendMessageType.CHANGE_REQUEST\n const msg = buildMessageEdit(msgType, flow)\n this.props.onMessage(msg)\n }}>Continue</Button>\n\n <Button size=\"sm\" onClick={() => {\n const msgType = when === 'response' ? SendMessageType.DROP_RESPONSE : SendMessageType.DROP_REQUEST\n const msg = buildMessageEdit(msgType, flow)\n this.props.onMessage(msg)\n }}>Drop</Button>\n\n\n <Modal size=\"lg\" show={this.state.show} onHide={this.handleClose}>\n <Modal.Header closeButton>\n <Modal.Title>Edit {when === 'request' ? 'Request' : 'Response'}</Modal.Title>\n </Modal.Header>\n\n <Modal.Body>\n <Form.Group>\n <Form.Control as=\"textarea\" rows={10} value={this.state.content} onChange={e => { this.setState({ content: e.target.value }) }} />\n </Form.Group>\n {\n !alertMsg ? null : <Alert variant=\"danger\">{alertMsg}</Alert>\n }\n </Modal.Body>\n\n <Modal.Footer>\n <Button variant=\"secondary\" onClick={this.handleClose}>\n Close\n </Button>\n <Button variant=\"primary\" onClick={this.handleSave}>\n Save\n </Button>\n </Modal.Footer>\n </Modal>\n\n </div>\n )\n }\n}\n\nexport default EditFlow\n","import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport FormCheck from 'react-bootstrap/FormCheck'\nimport fetchToCurl from 'fetch-to-curl'\nimport copy from 'copy-to-clipboard'\nimport JSONPretty from 'react-json-pretty'\nimport { Flow, IResponse } from '../message'\nimport { isTextBody } from '../utils'\n\nimport EditFlow from './EditFlow'\n\ninterface Iprops {\n flow: Flow | null\n onClose: () => void\n onReRenderFlows: () => void\n onMessage: (msg: ArrayBufferLike) => void\n}\n\ninterface IState {\n flowTab: 'Headers' | 'Preview' | 'Response' | 'Hexview'\n copied: boolean\n requestBodyViewTab: 'Raw' | 'Preview'\n responseBodyLineBreak: boolean\n}\n\nclass ViewFlow extends React.Component<Iprops, IState> {\n constructor(props: Iprops) {\n super(props)\n\n this.state = {\n flowTab: 'Headers',\n copied: false,\n requestBodyViewTab: 'Raw',\n responseBodyLineBreak: false,\n }\n }\n\n preview() {\n const { flow } = this.props\n if (!flow) return null\n const response = flow.response\n if (!response) return null\n\n if (!(response.body && response.body.byteLength)) {\n return <div style={{ color: 'gray' }}>No response</div>\n }\n\n const pv = flow.previewResponseBody()\n if (!pv) return <div style={{ color: 'gray' }}>Not support preview</div>\n\n if (pv.type === 'image') {\n return <img src={`data:image/png;base64,${pv.data}`} />\n }\n else if (pv.type === 'json') {\n return <div><JSONPretty data={pv.data} keyStyle={'color: rgb(130,40,144);'} stringStyle={'color: rgb(153,68,60);'} valueStyle={'color: rgb(25,1,199);'} booleanStyle={'color: rgb(94,105,192);'} /></div>\n }\n\n return <div style={{ color: 'gray' }}>Not support preview</div>\n }\n\n requestBodyPreview() {\n const { flow } = this.props\n if (!flow) return null\n\n const pv = flow.previewRequestBody()\n if (!pv) return <div style={{ color: 'gray' }}>Not support preview</div>\n\n if (pv.type === 'json') {\n return <div><JSONPretty data={pv.data} keyStyle={'color: rgb(130,40,144);'} stringStyle={'color: rgb(153,68,60);'} valueStyle={'color: rgb(25,1,199);'} booleanStyle={'color: rgb(94,105,192);'} /></div>\n }\n else if (pv.type === 'binary') {\n return <div><pre>{pv.data}</pre></div>\n }\n\n return <div style={{ color: 'gray' }}>Not support preview</div>\n }\n\n hexview() {\n const { flow } = this.props\n if (!flow) return null\n const response = flow.response\n if (!response) return null\n\n if (!(response.body && response.body.byteLength)) {\n return <div style={{ color: 'gray' }}>No response</div>\n }\n\n return <pre>{flow.hexviewResponseBody()}</pre>\n }\n\n render() {\n if (!this.props.flow) return null\n\n const flow = this.props.flow\n const flowTab = this.state.flowTab\n\n const request = flow.request\n const response: IResponse = (flow.response || {}) as any\n\n // Query String Parameters\n const searchItems: Array<{ key: string; value: string }> = []\n if (flow.url && flow.url.search) {\n flow.url.searchParams.forEach((value, key) => {\n searchItems.push({ key, value })\n })\n }\n\n return (\n <div className=\"flow-detail\">\n <div className=\"header-tabs\">\n <span onClick={() => { this.props.onClose() }}>x</span>\n <span className={flowTab === 'Headers' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Headers' }) }}>Headers</span>\n <span className={flowTab === 'Preview' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Preview' }) }}>Preview</span>\n <span className={flowTab === 'Response' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Response' }) }}>Response</span>\n <span className={flowTab === 'Hexview' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Hexview' }) }}>Hexview</span>\n\n <EditFlow\n flow={flow}\n onChangeRequest={request => {\n flow.request.method = request.method\n flow.request.url = request.url\n flow.request.header = request.header\n if (isTextBody(flow.request)) flow.request.body = request.body\n this.props.onReRenderFlows()\n }}\n onChangeResponse={response => {\n if (!flow.response) flow.response = {} as IResponse\n\n flow.response.statusCode = response.statusCode\n flow.response.header = response.header\n if (isTextBody(flow.response)) flow.response.body = response.body\n this.props.onReRenderFlows()\n }}\n onMessage={msg => {\n this.props.onMessage(msg)\n flow.waitIntercept = false\n this.props.onReRenderFlows()\n }}\n />\n\n </div>\n\n <div style={{ padding: '20px' }}>\n {\n !(flowTab === 'Headers') ? null :\n <div>\n <p><Button size=\"sm\" variant={this.state.copied ? 'success' : 'primary'} disabled={this.state.copied} onClick={() => {\n const curl = fetchToCurl({\n url: flow.request.url,\n method: flow.request.method,\n headers: Object.keys(flow.request.header).reduce((obj: any, key: string) => {\n obj[key] = flow.request.header[key][0]\n return obj\n }, {}),\n body: flow.requestBody(),\n })\n copy(curl)\n\n this.setState({ copied: true }, () => {\n setTimeout(() => {\n this.setState({ copied: false })\n }, 1000)\n })\n\n }}>{this.state.copied ? 'Copied' : 'Copy as cURL'}</Button></p>\n\n <div className=\"header-block\">\n <p>General</p>\n <div className=\"header-block-content\">\n <p>Request URL: {request.url}</p>\n <p>Request Method: {request.method}</p>\n <p>Status Code: {`${response.statusCode || '(pending)'}`}</p>\n </div>\n </div>\n\n {\n !(response.header) ? null :\n <div className=\"header-block\">\n <p>Response Headers</p>\n <div className=\"header-block-content\">\n {\n Object.keys(response.header).map(key => {\n return (\n <p key={key}>{key}: {response.header[key].join(' ')}</p>\n )\n })\n }\n </div>\n </div>\n }\n\n <div className=\"header-block\">\n <p>Request Headers</p>\n <div className=\"header-block-content\">\n {\n !(request.header) ? null :\n Object.keys(request.header).map(key => {\n return (\n <p key={key}>{key}: {request.header[key].join(' ')}</p>\n )\n })\n }\n </div>\n </div>\n\n {\n !(searchItems.length) ? null :\n <div className=\"header-block\">\n <p>Query String Parameters</p>\n <div className=\"header-block-content\">\n {\n searchItems.map(({ key, value }) => {\n return (\n <p key={key}>{key}: {value}</p>\n )\n })\n }\n </div>\n </div>\n }\n\n {\n !(request.body && request.body.byteLength) ? null :\n <div className=\"header-block\">\n <p>Request Body</p>\n <div className=\"header-block-content\">\n <div>\n <div className=\"request-body-detail\" style={{ marginBottom: '15px' }}>\n <span className={this.state.requestBodyViewTab === 'Raw' ? 'selected' : undefined} onClick={() => { this.setState({ requestBodyViewTab: 'Raw' }) }}>Raw</span>\n <span className={this.state.requestBodyViewTab === 'Preview' ? 'selected' : undefined} onClick={() => { this.setState({ requestBodyViewTab: 'Preview' }) }}>Preview</span>\n </div>\n\n {\n !(this.state.requestBodyViewTab === 'Raw') ? null :\n <div>\n {\n !(flow.isTextRequest()) ? <span style={{ color: 'gray' }}>Not text Request</span> : flow.requestBody()\n }\n </div>\n }\n\n {\n !(this.state.requestBodyViewTab === 'Preview') ? null :\n <div>{this.requestBodyPreview()}</div>\n }\n </div>\n </div>\n </div>\n }\n\n </div>\n }\n\n {\n !(flowTab === 'Response') ? null :\n !(response.body && response.body.byteLength) ? <div style={{ color: 'gray' }}>No response</div> :\n !(flow.isTextResponse()) ? <div style={{ color: 'gray' }}>Not text response</div> :\n <div>\n <div style={{ marginBottom: '20px' }}>\n <FormCheck\n inline\n type=\"checkbox\"\n checked={this.state.responseBodyLineBreak}\n onChange={e => {\n this.setState({ responseBodyLineBreak: e.target.checked })\n }}\n label=\"自动换行\"></FormCheck>\n </div>\n <div style={{ whiteSpace: this.state.responseBodyLineBreak ? 'pre-wrap' : 'pre' }}>\n {flow.responseBody()}\n </div>\n </div>\n }\n\n {\n !(flowTab === 'Preview') ? null :\n <div>{this.preview()}</div>\n }\n\n {\n !(flowTab === 'Hexview') ? null :\n <div>{this.hexview()}</div>\n }\n </div>\n\n </div>\n )\n }\n}\n\nexport default ViewFlow\n","import { Flow } from './message'\n\nexport class FlowManager {\n private items: Flow[]\n private _map: Map<string, Flow>\n private filterText: string\n private filterTimer: number | null\n private num: number\n private max: number\n\n constructor() {\n this.items = []\n this._map = new Map()\n this.filterText = ''\n this.filterTimer = null\n this.num = 0\n\n this.max = 1000\n }\n\n showList() {\n let text = this.filterText\n if (text) text = text.trim()\n if (!text) return this.items\n\n // regexp\n if (text.startsWith('/') && text.endsWith('/')) {\n text = text.slice(1, text.length - 1).trim()\n if (!text) return this.items\n try {\n const reg = new RegExp(text)\n return this.items.filter(item => {\n return reg.test(item.request.url)\n })\n } catch (err) {\n return this.items\n }\n }\n\n return this.items.filter(item => {\n return item.request.url.includes(text)\n })\n }\n\n add(item: Flow) {\n item.no = ++this.num\n this.items.push(item)\n this._map.set(item.id, item)\n\n if (this.items.length > this.max) {\n const oldest = this.items.shift()\n if (oldest) this._map.delete(oldest.id)\n }\n }\n\n get(id: string) {\n return this._map.get(id)\n }\n\n changeFilter(text: string) {\n this.filterText = text\n }\n\n changeFilterLazy(text: string, callback: () => void) {\n if (this.filterTimer) {\n clearTimeout(this.filterTimer)\n this.filterTimer = null\n }\n\n this.filterTimer = setTimeout(() => {\n this.filterText = text\n callback()\n }, 300) as any\n }\n\n clear() {\n this.items = []\n this._map = new Map()\n }\n}\n","import React from 'react'\nimport Table from 'react-bootstrap/Table'\nimport Form from 'react-bootstrap/Form'\nimport Button from 'react-bootstrap/Button'\nimport './App.css'\n\nimport BreakPoint from './components/BreakPoint'\nimport FlowPreview from './components/FlowPreview'\nimport ViewFlow from './components/ViewFlow'\n\nimport { FlowManager } from './flow'\nimport { parseMessage, SendMessageType, buildMessageMeta, Flow, MessageType } from './message'\nimport { isInViewPort } from './utils'\n\ninterface IState {\n flows: Flow[]\n flow: Flow | null\n flowTab: 'Headers' | 'Preview' | 'Response'\n wsStatus: 'open' | 'close' | 'connecting'\n}\n\nconst wsReconnIntervals = [1, 1, 2, 2, 4, 4, 8, 8, 16, 16, 32, 32]\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface IProps {}\n\nclass App extends React.Component<IProps, IState> {\n private flowMgr: FlowManager\n private ws: WebSocket | null\n private wsUnmountClose: boolean\n private tableBottomRef: React.RefObject<HTMLDivElement>\n\n private wsReconnCount = -1\n\n constructor(props: IProps) {\n super(props)\n\n this.flowMgr = new FlowManager()\n\n this.state = {\n flows: this.flowMgr.showList(),\n flow: null,\n flowTab: 'Headers', // Headers, Preview, Response\n wsStatus: 'close',\n }\n\n this.ws = null\n this.wsUnmountClose = false\n this.tableBottomRef = React.createRef<HTMLDivElement>()\n }\n\n componentDidMount() {\n this.initWs()\n }\n\n componentWillUnmount() {\n if (this.ws) {\n this.wsUnmountClose = true\n this.ws.close()\n this.ws = null\n }\n }\n\n initWs() {\n if (this.ws) return\n\n this.setState({ wsStatus: 'connecting' })\n\n let host\n if (process.env.NODE_ENV === 'development') {\n host = 'localhost:9081'\n } else {\n host = new URL(document.URL).host\n }\n this.ws = new WebSocket(`ws://${host}/echo`)\n this.ws.binaryType = 'arraybuffer'\n\n this.ws.onopen = () => {\n this.wsReconnCount = -1\n this.setState({ wsStatus: 'open' })\n }\n\n this.ws.onerror = evt => {\n console.error('ERROR:', evt)\n this.ws?.close()\n }\n\n this.ws.onclose = () => {\n this.setState({ wsStatus: 'close' })\n if (this.wsUnmountClose) return\n\n this.wsReconnCount++\n this.ws = null\n const waitSeconds = wsReconnIntervals[this.wsReconnCount] || wsReconnIntervals[wsReconnIntervals.length - 1]\n console.info(`will reconnect after ${waitSeconds} seconds`)\n setTimeout(() => {\n this.initWs()\n }, waitSeconds * 1000)\n }\n\n this.ws.onmessage = evt => {\n const msg = parseMessage(evt.data)\n if (!msg) {\n console.error('parse error:', evt.data)\n return\n }\n // console.log('msg:', msg)\n\n if (msg.type === MessageType.REQUEST) {\n const flow = new Flow(msg)\n this.flowMgr.add(flow)\n\n let shouldScroll = false\n if (this.tableBottomRef?.current && isInViewPort(this.tableBottomRef.current)) {\n shouldScroll = true\n }\n this.setState({ flows: this.flowMgr.showList() }, () => {\n if (shouldScroll) {\n this.tableBottomRef?.current?.scrollIntoView({ behavior: 'auto' })\n }\n })\n }\n else if (msg.type === MessageType.REQUEST_BODY) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.addRequestBody(msg)\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === MessageType.RESPONSE) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.addResponse(msg)\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === MessageType.RESPONSE_BODY) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow || !flow.response) return\n flow.addResponseBody(msg)\n this.setState({ flows: this.state.flows })\n }\n }\n }\n\n render() {\n const { flows } = this.state\n return (\n <div className=\"main-table-wrap\">\n <div className=\"top-control\">\n <div><Button size=\"sm\" onClick={() => {\n this.flowMgr.clear()\n this.setState({ flows: this.flowMgr.showList(), flow: null })\n }}>Clear</Button></div>\n <div>\n <Form.Control\n size=\"sm\" placeholder=\"Filter\"\n onChange={(e) => {\n const value = e.target.value\n this.flowMgr.changeFilterLazy(value, () => {\n this.setState({ flows: this.flowMgr.showList() })\n })\n }}\n >\n </Form.Control>\n </div>\n\n <BreakPoint onSave={rules => {\n const msg = buildMessageMeta(SendMessageType.CHANGE_BREAK_POINT_RULES, rules)\n if (this.ws) this.ws.send(msg)\n }} />\n\n <span>status: {this.state.wsStatus}</span>\n </div>\n\n <div className=\"table-wrap-div\">\n <Table striped bordered size=\"sm\" style={{ tableLayout: 'fixed' }}>\n <thead>\n <tr>\n <th style={{ width: '50px' }}>No</th>\n <th style={{ width: '80px' }}>Method</th>\n <th style={{ width: '200px' }}>Host</th>\n <th style={{ width: 'auto' }}>Path</th>\n <th style={{ width: '150px' }}>Type</th>\n <th style={{ width: '80px' }}>Status</th>\n <th style={{ width: '90px' }}>Size</th>\n <th style={{ width: '90px' }}>Time</th>\n </tr>\n </thead>\n <tbody>\n {\n flows.map(f => {\n const fp = f.preview()\n\n return (\n <FlowPreview\n key={fp.id}\n flow={fp}\n isSelected={(this.state.flow && this.state.flow.id === fp.id) ? true : false}\n onShowDetail={() => {\n this.setState({ flow: f })\n }}\n />\n )\n })\n }\n </tbody>\n </Table>\n <div ref={this.tableBottomRef} id=\"hidden-bottom\" style={{ height: '0px', visibility: 'hidden', marginBottom: '1px' }}></div>\n </div>\n\n <ViewFlow\n flow={this.state.flow}\n onClose={() => { this.setState({ flow: null }) }}\n onReRenderFlows={() => { this.setState({ flows: this.state.flows }) }}\n onMessage={msg => { if (this.ws) this.ws.send(msg) }}\n />\n </div>\n )\n }\n}\n\nexport default App\n","import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry)\n getFID(onPerfEntry)\n getFCP(onPerfEntry)\n getLCP(onPerfEntry)\n getTTFB(onPerfEntry)\n })\n }\n}\n\nexport default reportWebVitals\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport 'bootstrap/dist/css/bootstrap.min.css'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\n\nReactDOM.render(\n <React.StrictMode>\n <App />\n </React.StrictMode>,\n document.getElementById('root')\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals()\n"],"sourceRoot":""} |