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
64 KiB
Plaintext
1 line
64 KiB
Plaintext
{"version":3,"sources":["message.ts","components/BreakPoint.tsx","utils.ts","components/FlowPreview.tsx","components/EditFlow.tsx","components/ViewFlow.tsx","flow.ts","App.tsx","reportWebVitals.ts","index.tsx"],"names":["MessageType","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","toString","padStart","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","_hexviewResponseBody","curNo","content","URL","pathname","search","REQUEST_BODY","body","RESPONSE","split","includes","RESPONSE_BODY","isTextRequest","TextDecoder","decode","isTextResponse","startsWith","type","data","responseBody","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","style","color","pv","previewResponseBody","src","keyStyle","stringStyle","valueStyle","booleanStyle","hexviewResponseBody","searchItems","searchParams","forEach","onClose","onReRenderFlows","padding","disabled","curl","fetchToCurl","headers","reduce","obj","requestBody","copy","setTimeout","hexviewRequestBody","preview","hexview","FlowManager","items","_map","filterText","filterTimer","num","max","Map","text","trim","endsWith","reg","RegExp","filter","item","err","oldest","shift","delete","get","callback","clearTimeout","App","flowMgr","ws","pageBottom","autoScore","flows","showList","initWs","close","document","WebSocket","binaryType","onopen","console","log","onclose","onmessage","evt","meta","Int8Array","resp","contentStr","parse","parseMessage","add","scrollIntoView","behavior","addRequestBody","addResponse","addResponseBody","error","onerror","watcher","scrollMonitor","create","enterViewport","exitViewport","clear","placeholder","changeFilterLazy","CHANGE_BREAK_POINT_RULES","rulesBytes","buildMessageMeta","send","Table","striped","bordered","tableLayout","width","f","ref","el","initScrollMonitor","height","visibility","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.31668b10.chunk.js","sourcesContent":["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 IPreviewResponseBody {\n type: 'image' | 'json'\n data: string\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: IPreviewResponseBody | 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(): IPreviewResponseBody | 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 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 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 str += '00000000: '\n for (let i = 0; i < len; i++) {\n str += bytes[i].toString(16).padStart(2, '0') + ' '\n if ((i + 1) % 16 === 0) {\n str += `\\n${(i + 1).toString(16).padStart(8, '0')}: `\n } else if ((i + 1) % 8 === 0) {\n str += ' '\n }\n }\n return str\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 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}\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 }\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 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 {\n !(flow.isTextRequest()) ? <div>\n <p><span style={{ color: 'gray' }}>Hex:</span></p>\n <div><pre>{flow.hexviewRequestBody()}</pre></div>\n </div> :\n flow.requestBody()\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 {flow.responseBody()}\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 scrollMonitor from 'scrollmonitor'\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'\n\ninterface IState {\n flows: Flow[]\n flow: Flow | null\n flowTab: 'Headers' | 'Preview' | 'Response'\n}\n\nclass App extends React.Component<any, IState> {\n private flowMgr: FlowManager\n private ws: WebSocket | null\n\n private pageBottom: HTMLDivElement | null\n private autoScore = false\n\n constructor(props: any) {\n super(props)\n\n this.flowMgr = new FlowManager()\n\n this.state = {\n flows: this.flowMgr.showList(),\n flow: null,\n\n flowTab: 'Headers', // Headers, Preview, Response\n }\n\n this.ws = null\n this.pageBottom = null\n }\n\n componentDidMount() {\n this.initWs()\n }\n\n componentWillUnmount() {\n if (this.ws) {\n this.ws.close()\n }\n }\n\n initWs() {\n if (this.ws) return\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 this.ws.onopen = () => { console.log('OPEN') }\n this.ws.onclose = () => { console.log('CLOSE') }\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 this.setState({ flows: this.flowMgr.showList() }, () => {\n if (this.pageBottom && this.autoScore) this.pageBottom.scrollIntoView({ behavior: 'auto' })\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 this.ws.onerror = evt => {\n console.log('ERROR:', evt)\n }\n }\n\n initScrollMonitor() {\n if (!this.pageBottom) return\n\n const watcher = scrollMonitor.create(this.pageBottom)\n watcher.enterViewport(() => {\n this.autoScore = true\n })\n watcher.exitViewport(() => {\n this.autoScore = false\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 </div>\n\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: '600px' }}>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\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\n <div ref={el => {\n if (this.pageBottom) return\n this.pageBottom = el\n this.initScrollMonitor()\n }} style={{ height: '0px', visibility: 'hidden' }}>bottom</div>\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":""} |