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
58 KiB
Plaintext
1 line
58 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","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","_responseBody","_previewResponseBody","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","style","color","pv","previewResponseBody","src","keyStyle","stringStyle","valueStyle","booleanStyle","onClose","onReRenderFlows","padding","curl","fetchToCurl","headers","reduce","obj","requestBody","copy","preview","FlowManager","items","_map","filterText","filterTimer","num","max","Map","filter","item","oldest","shift","delete","get","text","callback","clearTimeout","setTimeout","App","flowMgr","ws","pageBottom","autoScore","flows","showList","initWs","close","document","WebSocket","binaryType","onopen","console","log","onclose","onmessage","evt","meta","Int8Array","resp","contentStr","parse","err","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.0486ccb3.chunk.js","sourcesContent":["import { arrayBufferToBase64, 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 private 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 _responseBody: string | null\n\n private _previewResponseBody: IPreviewResponseBody | 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 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\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/.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","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'\n}\n\nclass ViewFlow extends React.Component<Iprops, IState> {\n constructor(props: Iprops) {\n super(props)\n\n this.state = {\n flowTab: 'Headers',\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 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 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\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\" 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 }}>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 !(request.body && request.body.byteLength) ? null :\n <div className=\"header-block\">\n <p>Request Body</p>\n <div className=\"header-block-content\">\n <p>\n {\n !(flow.isTextRequest()) ? <span style={{ color: 'gray' }}>Not text</span> :\n flow.requestBody()\n }\n </p>\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 </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 if (!this.filterText) return this.items\n return this.items.filter(item => {\n return item.request.url.includes(this.filterText)\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":""} |