diff --git a/addon/web/client/build/asset-manifest.json b/addon/web/client/build/asset-manifest.json
index b9c6b9e..8859906 100644
--- a/addon/web/client/build/asset-manifest.json
+++ b/addon/web/client/build/asset-manifest.json
@@ -1,8 +1,8 @@
{
"files": {
- "main.css": "/static/css/main.1bcd8dd7.chunk.css",
- "main.js": "/static/js/main.597545a3.chunk.js",
- "main.js.map": "/static/js/main.597545a3.chunk.js.map",
+ "main.css": "/static/css/main.cb45a0e0.chunk.css",
+ "main.js": "/static/js/main.7030457c.chunk.js",
+ "main.js.map": "/static/js/main.7030457c.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.88ddd258.js",
"runtime-main.js.map": "/static/js/runtime-main.88ddd258.js.map",
"static/css/2.150d169a.chunk.css": "/static/css/2.150d169a.chunk.css",
@@ -12,14 +12,14 @@
"static/js/3.e6d0d6ad.chunk.js.map": "/static/js/3.e6d0d6ad.chunk.js.map",
"index.html": "/index.html",
"static/css/2.150d169a.chunk.css.map": "/static/css/2.150d169a.chunk.css.map",
- "static/css/main.1bcd8dd7.chunk.css.map": "/static/css/main.1bcd8dd7.chunk.css.map",
+ "static/css/main.cb45a0e0.chunk.css.map": "/static/css/main.cb45a0e0.chunk.css.map",
"static/js/2.d0f40b45.chunk.js.LICENSE.txt": "/static/js/2.d0f40b45.chunk.js.LICENSE.txt"
},
"entrypoints": [
"static/js/runtime-main.88ddd258.js",
"static/css/2.150d169a.chunk.css",
"static/js/2.d0f40b45.chunk.js",
- "static/css/main.1bcd8dd7.chunk.css",
- "static/js/main.597545a3.chunk.js"
+ "static/css/main.cb45a0e0.chunk.css",
+ "static/js/main.7030457c.chunk.js"
]
}
\ No newline at end of file
diff --git a/addon/web/client/build/index.html b/addon/web/client/build/index.html
index 0517d7c..8430dd7 100644
--- a/addon/web/client/build/index.html
+++ b/addon/web/client/build/index.html
@@ -1 +1 @@
-
go-mitmproxy You need to enable JavaScript to run this app.
\ No newline at end of file
+go-mitmproxy You need to enable JavaScript to run this app.
\ No newline at end of file
diff --git a/addon/web/client/build/static/css/main.1bcd8dd7.chunk.css.map b/addon/web/client/build/static/css/main.1bcd8dd7.chunk.css.map
deleted file mode 100644
index 13f6d09..0000000
--- a/addon/web/client/build/static/css/main.1bcd8dd7.chunk.css.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack://src/App.css"],"names":[],"mappings":"AAAA,iBACI,wBAAyB,CACzB,eACJ,CAEA,aACI,YAAa,CACb,kBACJ,CAEA,iBACI,iBACJ,CAGA,sCACI,wBAAmC,CACnC,UACJ,CAEA,4CACI,wBAAmC,CACnC,UACJ,CAEA,aACI,cAAe,CACf,KAAM,CACN,OAAQ,CAER,YAAa,CACb,qBAAsB,CACtB,eAAgB,CAChB,SAAU,CACV,eAAgB,CAEhB,oBACJ,CAEA,0BACI,YACJ,CAEA,+BACI,oBAAqB,CACrB,aAAc,CACd,WAAY,CACZ,cACJ,CAEA,oCACI,+BACJ,CAEA,iDACI,gBACJ,CAEA,6BACI,eACJ,CAEA,mDACI,YACJ,CAEA,iDACI,gBAAiB,CACjB,eACJ","file":"main.1bcd8dd7.chunk.css","sourcesContent":[".main-table-wrap {\n font-family: Menlo,Monaco;\n font-size: 0.8rem;\n}\n\n.top-control {\n display: flex;\n align-items: center;\n}\n\n.top-control > div {\n margin-right: 20px;\n}\n\n\n.main-table-wrap tbody tr.tr-selected {\n background-color: rgb(35, 118, 229);\n color: white;\n}\n\n.main-table-wrap tbody tr.tr-wait-intercept {\n background-color: rgb(216, 110, 83);\n color: white;\n}\n\n.flow-detail {\n position: fixed;\n top: 0;\n right: 0;\n\n height: 100vh;\n background-color: #fff;\n min-width: 500px;\n width: 50%;\n overflow-y: auto;\n\n word-break: break-all;\n}\n\n.flow-detail .header-tabs {\n display: flex;\n}\n\n.flow-detail .header-tabs span {\n display: inline-block;\n line-height: 1;\n padding: 8px;\n cursor: pointer;\n}\n\n.flow-detail .header-tabs .selected {\n border-bottom: 2px rgb(35, 118, 229) solid;\n}\n\n.flow-detail .header-tabs .flow-wait-area button {\n margin-left: 10px;\n}\n\n.flow-detail .header-block > p {\n font-weight: bold;\n}\n\n.flow-detail .header-block .header-block-content p {\n margin: 5px 0;\n}\n\n.flow-detail .header-block .header-block-content {\n margin-left: 20px;\n line-height: 1.5;\n}"]}
\ No newline at end of file
diff --git a/addon/web/client/build/static/css/main.1bcd8dd7.chunk.css b/addon/web/client/build/static/css/main.cb45a0e0.chunk.css
similarity index 71%
rename from addon/web/client/build/static/css/main.1bcd8dd7.chunk.css
rename to addon/web/client/build/static/css/main.cb45a0e0.chunk.css
index 2a17754..2a0e1ab 100644
--- a/addon/web/client/build/static/css/main.1bcd8dd7.chunk.css
+++ b/addon/web/client/build/static/css/main.cb45a0e0.chunk.css
@@ -1,2 +1,2 @@
-.main-table-wrap{font-family:Menlo,Monaco;font-size:.8rem}.top-control{display:flex;align-items:center}.top-control>div{margin-right:20px}.main-table-wrap tbody tr.tr-selected{background-color:#2376e5;color:#fff}.main-table-wrap tbody tr.tr-wait-intercept{background-color:#d86e53;color:#fff}.flow-detail{position:fixed;top:0;right:0;height:100vh;background-color:#fff;min-width:500px;width:50%;overflow-y:auto;word-break:break-all}.flow-detail .header-tabs{display:flex}.flow-detail .header-tabs span{display:inline-block;line-height:1;padding:8px;cursor:pointer}.flow-detail .header-tabs .selected{border-bottom:2px solid #2376e5}.flow-detail .header-tabs .flow-wait-area button{margin-left:10px}.flow-detail .header-block>p{font-weight:700}.flow-detail .header-block .header-block-content p{margin:5px 0}.flow-detail .header-block .header-block-content{margin-left:20px;line-height:1.5}
-/*# sourceMappingURL=main.1bcd8dd7.chunk.css.map */
\ No newline at end of file
+.main-table-wrap{font-family:Menlo,Monaco;font-size:.8rem}.top-control{display:flex;align-items:center}.top-control>div{margin-right:20px}.main-table-wrap tbody tr.tr-selected{background-color:#2376e5;color:#fff}.main-table-wrap tbody tr.tr-wait-intercept{background-color:#d86e53;color:#fff}.flow-detail{position:fixed;top:0;right:0;height:100vh;background-color:#fff;min-width:500px;width:50%;overflow-y:auto;word-break:break-all}.flow-detail .header-tabs{display:flex}.flow-detail .header-tabs span{display:inline-block;line-height:1;padding:8px;cursor:pointer}.flow-detail .header-tabs .selected{border-bottom:2px solid #2376e5}.flow-detail .header-tabs .flow-wait-area button{margin-left:10px}.flow-detail .header-block{margin-bottom:20px}.flow-detail .header-block>p{font-weight:700}.flow-detail .header-block .header-block-content p{margin:5px 0}.flow-detail .header-block .header-block-content{margin-left:20px;line-height:1.5}
+/*# sourceMappingURL=main.cb45a0e0.chunk.css.map */
\ No newline at end of file
diff --git a/addon/web/client/build/static/css/main.cb45a0e0.chunk.css.map b/addon/web/client/build/static/css/main.cb45a0e0.chunk.css.map
new file mode 100644
index 0000000..4974ef9
--- /dev/null
+++ b/addon/web/client/build/static/css/main.cb45a0e0.chunk.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack://src/App.css"],"names":[],"mappings":"AAAA,iBACI,wBAAyB,CACzB,eACJ,CAEA,aACI,YAAa,CACb,kBACJ,CAEA,iBACI,iBACJ,CAGA,sCACI,wBAAmC,CACnC,UACJ,CAEA,4CACI,wBAAmC,CACnC,UACJ,CAEA,aACI,cAAe,CACf,KAAM,CACN,OAAQ,CAER,YAAa,CACb,qBAAsB,CACtB,eAAgB,CAChB,SAAU,CACV,eAAgB,CAEhB,oBACJ,CAEA,0BACI,YACJ,CAEA,+BACI,oBAAqB,CACrB,aAAc,CACd,WAAY,CACZ,cACJ,CAEA,oCACI,+BACJ,CAEA,iDACI,gBACJ,CAEA,2BACI,kBACJ,CAEA,6BACI,eACJ,CAEA,mDACI,YACJ,CAEA,iDACI,gBAAiB,CACjB,eACJ","file":"main.cb45a0e0.chunk.css","sourcesContent":[".main-table-wrap {\n font-family: Menlo,Monaco;\n font-size: 0.8rem;\n}\n\n.top-control {\n display: flex;\n align-items: center;\n}\n\n.top-control > div {\n margin-right: 20px;\n}\n\n\n.main-table-wrap tbody tr.tr-selected {\n background-color: rgb(35, 118, 229);\n color: white;\n}\n\n.main-table-wrap tbody tr.tr-wait-intercept {\n background-color: rgb(216, 110, 83);\n color: white;\n}\n\n.flow-detail {\n position: fixed;\n top: 0;\n right: 0;\n\n height: 100vh;\n background-color: #fff;\n min-width: 500px;\n width: 50%;\n overflow-y: auto;\n\n word-break: break-all;\n}\n\n.flow-detail .header-tabs {\n display: flex;\n}\n\n.flow-detail .header-tabs span {\n display: inline-block;\n line-height: 1;\n padding: 8px;\n cursor: pointer;\n}\n\n.flow-detail .header-tabs .selected {\n border-bottom: 2px rgb(35, 118, 229) solid;\n}\n\n.flow-detail .header-tabs .flow-wait-area button {\n margin-left: 10px;\n}\n\n.flow-detail .header-block {\n margin-bottom: 20px;\n}\n\n.flow-detail .header-block > p {\n font-weight: bold;\n}\n\n.flow-detail .header-block .header-block-content p {\n margin: 5px 0;\n}\n\n.flow-detail .header-block .header-block-content {\n margin-left: 20px;\n line-height: 1.5;\n}"]}
\ No newline at end of file
diff --git a/addon/web/client/build/static/js/main.597545a3.chunk.js b/addon/web/client/build/static/js/main.597545a3.chunk.js
deleted file mode 100644
index bf931f8..0000000
--- a/addon/web/client/build/static/js/main.597545a3.chunk.js
+++ /dev/null
@@ -1,2 +0,0 @@
-(this.webpackJsonpclient=this.webpackJsonpclient||[]).push([[0],{23:function(e,t,n){},28:function(e,t,n){"use strict";n.r(t);var s=n(0),i=n.n(s),r=n(14),c=n.n(r),l=(n(22),n(7)),a=n(8),o=n(17),d=n(16),h=n(15),u=n(12),j=n(6),f=(n(23),function(){function e(){Object(l.a)(this,e),this.items=[],this._map=new Map,this.filterText="",this.filterTimer=null,this.num=0,this.max=1e3}return Object(a.a)(e,[{key:"showList",value:function(){var e=this;return this.filterText?this.items.filter((function(t){return t.request.url.includes(e.filterText)})):this.items}},{key:"add",value:function(e){if(e.no=++this.num,this.items.push(e),this._map.set(e.id,e),this.items.length>this.max){var t=this.items.shift();this._map.delete(t.id)}}},{key:"get",value:function(e){return this._map.get(e)}},{key:"changeFilter",value:function(e){this.filterText=e}},{key:"changeFilterLazy",value:function(e,t){var n=this;this.filterTimer&&(clearTimeout(this.filterTimer),this.filterTimer=null),this.filterTimer=setTimeout((function(){n.filterText=e,t()}),300)}},{key:"clear",value:function(){this.items=[],this._map=new Map}}]),e}()),b=function(e){return!!e&&(!!e.header&&(!!e.header["Content-Type"]&&/text|javascript|json/.test(e.header["Content-Type"].join(""))))},p=function(e){return e&&e.header?(e.header["Content-Length"]?t=parseInt(e.header["Content-Length"][0]):e&&e.body&&(t=e.body.byteLength),t?isNaN(t)||t<=0?"0":t<1024?"".concat(t," B"):t<1048576?"".concat((t/1024).toFixed(2)," KB"):"".concat((t/1048576).toFixed(2)," MB"):"0"):"0";var t},w=function(e,t,n){n=(new TextEncoder).encode(n);var s=new Uint8Array(39+n.byteLength);return s[0]=1,s[1]=e,s[2]=0,s.set((new TextEncoder).encode(t),3),s.set(n,39),s},x=n(1),O=function(e){Object(o.a)(n,e);var t=Object(d.a)(n);function n(e){var s;return Object(l.a)(this,n),(s=t.call(this,e)).flowMgr=new f,s.state={flows:s.flowMgr.showList(),flow:null,flowTab:"Headers",interceptUriInputing:"",interceptUri:""},s.ws=null,s}return Object(a.a)(n,[{key:"componentDidMount",value:function(){this.initWs()}},{key:"componentWillUnmount",value:function(){this.ws&&this.ws.close()}},{key:"initWs",value:function(){var e,t=this;this.ws||(e=new URL(document.URL).host,this.ws=new WebSocket("ws://".concat(e,"/echo")),this.ws.binaryType="arraybuffer",this.ws.onopen=function(){console.log("OPEN")},this.ws.onclose=function(){console.log("CLOSE")},this.ws.onmessage=function(e){var n=function(e){if(e.byteLength<39)return null;var t=new Int8Array(e.slice(0,3));if(1!==t[0])return null;var n=t[1];if(![1,2,3].includes(n))return null;var s=(new TextDecoder).decode(e.slice(3,39)),i={type:["request","response","responseBody"][n-1],id:s,waitIntercept:1===t[2]};if(39===e.byteLength)return i;if(3===n)return i.content=e.slice(39),i;var r=(new TextDecoder).decode(e.slice(39));try{r=JSON.parse(r)}catch(c){return null}return i.content=r,i}(e.data);if(n){if("request"===n.type){var s={id:n.id,request:n.content,waitIntercept:n.waitIntercept};t.flowMgr.add(s),t.setState({flows:t.flowMgr.showList()})}else if("response"===n.type){var i=t.flowMgr.get(n.id);if(!i)return;i.waitIntercept=n.waitIntercept,i.response=n.content,t.setState({flows:t.state.flows})}else if("responseBody"===n.type){var r=t.flowMgr.get(n.id);if(!r||!r.response)return;r.waitIntercept=n.waitIntercept,r.response.body=n.content,t.setState({flows:t.state.flows})}}else console.error("parse error:",e.data)},this.ws.onerror=function(e){console.log("ERROR:",e)})}},{key:"renderFlow",value:function(){var e=this,t=this.state,n=t.flow,s=t.flowTab;if(!n)return null;var i=n.request,r=n.response||{};return Object(x.jsxs)("div",{className:"flow-detail",children:[Object(x.jsxs)("div",{className:"header-tabs",children:[Object(x.jsx)("span",{onClick:function(){e.setState({flow:null})},children:"x"}),Object(x.jsx)("span",{className:"Headers"===s?"selected":null,onClick:function(){e.setState({flowTab:"Headers"})},children:"Headers"}),Object(x.jsx)("span",{className:"Preview"===s?"selected":null,onClick:function(){e.setState({flowTab:"Preview"})},children:"Preview"}),Object(x.jsx)("span",{className:"Response"===s?"selected":null,onClick:function(){e.setState({flowTab:"Response"})},children:"Response"}),n.waitIntercept?Object(x.jsxs)("div",{className:"flow-wait-area",children:[Object(x.jsx)(j.a,{size:"sm",onClick:function(){var t=w(11,n.id,JSON.stringify(n.request));e.ws.send(t),n.waitIntercept=!1,e.setState({flows:e.state.flows})},children:"Continue"}),Object(x.jsx)(j.a,{size:"sm",children:"Drop"})]}):null]}),Object(x.jsxs)("div",{style:{padding:"20px"},children:["Headers"!==s?null:Object(x.jsxs)("div",{children:[Object(x.jsxs)("div",{className:"header-block",children:[Object(x.jsx)("p",{children:"General"}),Object(x.jsxs)("div",{className:"header-block-content",children:[Object(x.jsxs)("p",{children:["Request URL: ",i.url]}),Object(x.jsxs)("p",{children:["Request Method: ",i.method]}),Object(x.jsxs)("p",{children:["Status Code: ","".concat(r.statusCode||"(pending)")]})]})]}),Object(x.jsxs)("div",{className:"header-block",children:[Object(x.jsx)("p",{children:"Response Headers"}),Object(x.jsx)("div",{className:"header-block-content",children:r.header?Object.keys(r.header).map((function(e){return Object(x.jsxs)("p",{children:[e,": ",r.header[e].join(" ")]},e)})):null})]}),Object(x.jsxs)("div",{className:"header-block",children:[Object(x.jsx)("p",{children:"Request Headers"}),Object(x.jsx)("div",{className:"header-block-content",children:i.header?Object.keys(i.header).map((function(e){return Object(x.jsxs)("p",{children:[e,": ",i.header[e].join(" ")]},e)})):null})]})]}),"Response"!==s?null:r.body&&r.body.byteLength?b(r)?Object(x.jsx)("div",{children:(new TextDecoder).decode(r.body)}):Object(x.jsx)("div",{children:"Not text response"}):Object(x.jsx)("div",{children:"No response"})]})]})}},{key:"render",value:function(){var e=this,t=this.state,n=t.flows,s=t.interceptUriInputing,i=t.interceptUri;return Object(x.jsxs)("div",{className:"main-table-wrap",children:[Object(x.jsxs)("div",{className:"top-control",children:[Object(x.jsx)("div",{children:Object(x.jsx)(j.a,{size:"sm",onClick:function(){e.flowMgr.clear(),e.setState({flows:e.flowMgr.showList(),flow:null})},children:"Clear"})}),Object(x.jsx)("div",{children:Object(x.jsx)(u.a.Control,{size:"sm",placeholder:"Filter",onChange:function(t){var n=t.target.value;e.flowMgr.changeFilterLazy(n,(function(){e.setState({flows:e.flowMgr.showList()})}))}})}),Object(x.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[Object(x.jsx)(u.a.Control,{size:"sm",placeholder:"Set interpect",value:s,onChange:function(t){e.setState({interceptUriInputing:t.target.value||""})}}),Object(x.jsx)(j.a,{size:"sm",onClick:function(){e.setState({interceptUri:s});var t=w(21,"00000000-0000-0000-0000-000000000000",s);e.ws.send(t)},children:"Set"}),i?Object(x.jsx)("span",{children:"Intercept:".concat(i)}):null]})]}),Object(x.jsxs)(h.a,{striped:!0,bordered:!0,size:"sm",children:[Object(x.jsx)("thead",{children:Object(x.jsxs)("tr",{children:[Object(x.jsx)("th",{children:"No"}),Object(x.jsx)("th",{children:"Host"}),Object(x.jsx)("th",{children:"Path"}),Object(x.jsx)("th",{children:"Method"}),Object(x.jsx)("th",{children:"Status"}),Object(x.jsx)("th",{children:"Size"})]})}),Object(x.jsx)("tbody",{children:n.map((function(t){var n=t.request.url,s=new URL(n),i=s.host;i.length>35&&(i=i.slice(0,35)+"...");var r=s.pathname+s.search;r.length>65&&(r=r.slice(0,65)+"...");var c=t.request,l=t.response||{},a=[];return e.state.flow&&e.state.flow.id===t.id&&a.push("tr-selected"),t.waitIntercept&&a.push("tr-wait-intercept"),Object(x.jsxs)("tr",{className:a.length?a.join(" "):null,onClick:function(){e.setState({flow:t})},children:[Object(x.jsx)("td",{children:t.no}),Object(x.jsx)("td",{children:i}),Object(x.jsx)("td",{children:r}),Object(x.jsx)("td",{children:c.method}),Object(x.jsx)("td",{children:l.statusCode||"(pending)"}),Object(x.jsx)("td",{children:p(l)})]},t.id)}))})]}),this.renderFlow()]})}}]),n}(i.a.Component),v=function(e){e&&e instanceof Function&&n.e(3).then(n.bind(null,29)).then((function(t){var n=t.getCLS,s=t.getFID,i=t.getFCP,r=t.getLCP,c=t.getTTFB;n(e),s(e),i(e),r(e),c(e)}))};c.a.render(Object(x.jsx)(i.a.StrictMode,{children:Object(x.jsx)(O,{})}),document.getElementById("root")),v()}},[[28,1,2]]]);
-//# sourceMappingURL=main.597545a3.chunk.js.map
\ No newline at end of file
diff --git a/addon/web/client/build/static/js/main.597545a3.chunk.js.map b/addon/web/client/build/static/js/main.597545a3.chunk.js.map
deleted file mode 100644
index 440acb0..0000000
--- a/addon/web/client/build/static/js/main.597545a3.chunk.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["flow.js","utils.js","App.js","reportWebVitals.js","index.js"],"names":["FlowManager","this","items","_map","Map","filterText","filterTimer","num","max","filter","item","request","url","includes","no","push","set","id","length","oldest","shift","delete","get","text","callback","clearTimeout","setTimeout","isTextResponse","response","header","test","join","getSize","len","parseInt","body","byteLength","isNaN","toFixed","buildMessage","messageType","content","TextEncoder","encode","data","Uint8Array","App","props","flowMgr","state","flows","showList","flow","flowTab","interceptUriInputing","interceptUri","ws","initWs","close","host","URL","document","WebSocket","binaryType","onopen","console","log","onclose","onmessage","evt","msg","meta","Int8Array","slice","type","TextDecoder","decode","resp","waitIntercept","JSON","parse","err","parseMessage","add","setState","error","onerror","className","onClick","Button","size","stringify","send","style","padding","method","statusCode","Object","keys","map","key","clear","Form","Control","placeholder","onChange","e","value","target","changeFilterLazy","display","alignItems","Table","striped","bordered","f","u","path","pathname","search","classNames","renderFlow","React","Component","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.597545a3.chunk.js","sourcesContent":["export class FlowManager {\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) {\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 this._map.delete(oldest.id)\n }\n }\n\n get(id) {\n return this._map.get(id)\n }\n\n changeFilter(text) {\n this.filterText = text\n }\n\n changeFilterLazy(text, callback) {\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)\n }\n\n clear() {\n this.items = []\n this._map = new Map()\n }\n}\n","export const isTextResponse = response => {\n if (!response) return false\n if (!response.header) return false\n if (!response.header['Content-Type']) return false\n\n return /text|javascript|json/.test(response.header['Content-Type'].join(''))\n}\n\nexport const getSize = response => {\n if (!response) return '0'\n if (!response.header) return '0'\n\n let len\n if (response.header['Content-Length']) {\n len = parseInt(response.header['Content-Length'][0])\n } else if (response && response.body) {\n len = response.body.byteLength\n }\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 parseMessage = data => {\n if (data.byteLength < 39) return null\n const meta = new Int8Array(data.slice(0, 3))\n const version = meta[0]\n if (version !== 1) return null\n const type = meta[1]\n if (![1, 2, 3].includes(type)) return null\n const id = new TextDecoder().decode(data.slice(3, 39))\n\n const resp = {\n type: ['request', 'response', 'responseBody'][type-1],\n id,\n waitIntercept: meta[2] === 1,\n }\n if (data.byteLength === 39) return resp\n if (type === 3) {\n resp.content = data.slice(39)\n return resp\n }\n\n let content = new TextDecoder().decode(data.slice(39))\n try {\n content = JSON.parse(content)\n } catch (err) {\n return null\n }\n\n resp.content = content\n return resp\n}\n\n/**\n * \n * @param {number} messageType \n * @param {string} id \n * @param {string} content \n */\nexport const buildMessage = (messageType, id, content) => {\n content = new TextEncoder().encode(content)\n const data = new Uint8Array(39 + content.byteLength)\n data[0] = 1\n data[1] = messageType\n data[2] = 0\n data.set(new TextEncoder().encode(id), 3)\n data.set(content, 39)\n return data\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 { FlowManager } from './flow'\nimport { isTextResponse, getSize, parseMessage, buildMessage } from './utils'\n\nclass App extends React.Component {\n\n constructor(props) {\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 interceptUriInputing: '',\n interceptUri: '',\n }\n\n this.ws = 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 === 'request') {\n const flow = { id: msg.id, request: msg.content, waitIntercept: msg.waitIntercept }\n this.flowMgr.add(flow)\n this.setState({ flows: this.flowMgr.showList() })\n }\n else if (msg.type === 'response') {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.waitIntercept = msg.waitIntercept\n flow.response = msg.content\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === 'responseBody') {\n const flow = this.flowMgr.get(msg.id)\n if (!flow || !flow.response) return\n flow.waitIntercept = msg.waitIntercept\n flow.response.body = msg.content\n this.setState({ flows: this.state.flows })\n }\n }\n this.ws.onerror = evt => {\n console.log('ERROR:', evt)\n }\n }\n\n renderFlow() {\n const { flow, flowTab } = this.state\n if (!flow) return null\n\n const request = flow.request\n const response = flow.response || {}\n\n return (\n \n
\n
{ this.setState({ flow: null }) }}>x \n
{ this.setState({ flowTab: 'Headers' }) }}>Headers \n
{ this.setState({ flowTab: 'Preview' }) }}>Preview \n
{ this.setState({ flowTab: 'Response' }) }}>Response \n {\n !flow.waitIntercept ? null :\n
\n {\n const msg = buildMessage(11, flow.id, JSON.stringify(flow.request))\n this.ws.send(msg)\n flow.waitIntercept = false\n this.setState({ flows: this.state.flows })\n }}>Continue \n Drop \n
\n }\n
\n\n
\n {\n !(flowTab === 'Headers') ? null :\n
\n
\n
General
\n
\n
Request URL: {request.url}
\n
Request Method: {request.method}
\n
Status Code: {`${response.statusCode || '(pending)'}`}
\n
\n
\n\n
\n
Response Headers
\n
\n {\n !(response.header) ? null :\n Object.keys(response.header).map(key => {\n return (\n
{key}: {response.header[key].join(' ')}
\n )\n })\n }\n
\n
\n\n
\n
Request Headers
\n
\n {\n !(request.header) ? null :\n Object.keys(request.header).map(key => {\n return (\n
{key}: {request.header[key].join(' ')}
\n )\n })\n }\n
\n
\n
\n }\n\n {\n !(flowTab === 'Response') ? null :\n !(response.body && response.body.byteLength) ?
No response
:\n !(isTextResponse(response)) ?
Not text response
:\n
\n {new TextDecoder().decode(response.body)}\n
\n }\n
\n\n
\n )\n }\n \n render() {\n const { flows, interceptUriInputing, interceptUri } = this.state\n return (\n \n
\n
{\n this.flowMgr.clear()\n this.setState({ flows: this.flowMgr.showList(), flow: null })\n }}>Clear
\n
\n
{\n const value = e.target.value\n this.flowMgr.changeFilterLazy(value, () => {\n this.setState({ flows: this.flowMgr.showList() })\n })\n }}\n >\n \n \n\n
\n
{\n this.setState({ interceptUriInputing: e.target.value || '' })\n }}> \n {\n this.setState({ interceptUri: interceptUriInputing })\n const msg = buildMessage(21, '00000000-0000-0000-0000-000000000000', interceptUriInputing)\n this.ws.send(msg)\n }}>Set \n {\n interceptUri ? {`Intercept:${interceptUri}`} : null\n }\n \n
\n\n
\n \n \n No \n Host \n Path \n Method \n Status \n Size \n \n \n \n {\n flows.map(f => {\n const url = f.request.url\n const u = new URL(url)\n let host = u.host\n if (host.length > 35) host = host.slice(0, 35) + '...'\n let path = u.pathname + u.search\n if (path.length > 65) path = path.slice(0, 65) + '...'\n\n const request = f.request\n const response = f.response || {}\n\n const classNames = []\n if (this.state.flow && this.state.flow.id === f.id) classNames.push('tr-selected')\n if (f.waitIntercept) classNames.push('tr-wait-intercept')\n\n return (\n {\n this.setState({ flow: f })\n }}\n >\n {f.no} \n {host} \n {path} \n {request.method} \n {response.statusCode || '(pending)'} \n {getSize(response)} \n \n )\n })\n }\n \n
\n\n {this.renderFlow()}\n
\n )\n }\n}\n\nexport default App\n","const reportWebVitals = onPerfEntry => {\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 \n \n ,\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":""}
\ No newline at end of file
diff --git a/addon/web/client/build/static/js/main.7030457c.chunk.js b/addon/web/client/build/static/js/main.7030457c.chunk.js
new file mode 100644
index 0000000..b095608
--- /dev/null
+++ b/addon/web/client/build/static/js/main.7030457c.chunk.js
@@ -0,0 +1,2 @@
+(this.webpackJsonpclient=this.webpackJsonpclient||[]).push([[0],{23:function(e,t,n){},28:function(e,t,n){"use strict";n.r(t);var s=n(0),i=n.n(s),r=n(14),c=n.n(r),l=(n(22),n(7)),o=n(8),a=n(17),d=n(16),h=n(15),u=n(12),j=n(6),f=(n(23),function(){function e(){Object(l.a)(this,e),this.items=[],this._map=new Map,this.filterText="",this.filterTimer=null,this.num=0,this.max=1e3}return Object(o.a)(e,[{key:"showList",value:function(){var e=this;return this.filterText?this.items.filter((function(t){return t.request.url.includes(e.filterText)})):this.items}},{key:"add",value:function(e){if(e.no=++this.num,this.items.push(e),this._map.set(e.id,e),this.items.length>this.max){var t=this.items.shift();this._map.delete(t.id)}}},{key:"get",value:function(e){return this._map.get(e)}},{key:"changeFilter",value:function(e){this.filterText=e}},{key:"changeFilterLazy",value:function(e,t){var n=this;this.filterTimer&&(clearTimeout(this.filterTimer),this.filterTimer=null),this.filterTimer=setTimeout((function(){n.filterText=e,t()}),300)}},{key:"clear",value:function(){this.items=[],this._map=new Map}}]),e}()),b=function(e){return!!e&&(!!e.header&&(!!e.header["Content-Type"]&&/text|javascript|json/.test(e.header["Content-Type"].join(""))))},p=function(e){return e&&e.header?(e.header["Content-Length"]?t=parseInt(e.header["Content-Length"][0]):e&&e.body&&(t=e.body.byteLength),t?isNaN(t)||t<=0?"0":t<1024?"".concat(t," B"):t<1048576?"".concat((t/1024).toFixed(2)," KB"):"".concat((t/1048576).toFixed(2)," MB"):"0"):"0";var t},w={request:1,requestBody:2,response:3,responseBody:4},x=Object.keys(w).map((function(e){return w[e]})),O=Object.keys(w).reduce((function(e,t){return e[w[t]]=t,e}),{}),v=function(e,t,n){n=(new TextEncoder).encode(n);var s=new Uint8Array(39+n.byteLength);return s[0]=1,s[1]=e,s[2]=0,s.set((new TextEncoder).encode(t),3),s.set(n,39),s},m=n(1),y=function(e){Object(a.a)(n,e);var t=Object(d.a)(n);function n(e){var s;return Object(l.a)(this,n),(s=t.call(this,e)).flowMgr=new f,s.state={flows:s.flowMgr.showList(),flow:null,flowTab:"Headers",interceptUriInputing:"",interceptUri:""},s.ws=null,s}return Object(o.a)(n,[{key:"componentDidMount",value:function(){this.initWs()}},{key:"componentWillUnmount",value:function(){this.ws&&this.ws.close()}},{key:"initWs",value:function(){var e,t=this;this.ws||(e=new URL(document.URL).host,this.ws=new WebSocket("ws://".concat(e,"/echo")),this.ws.binaryType="arraybuffer",this.ws.onopen=function(){console.log("OPEN")},this.ws.onclose=function(){console.log("CLOSE")},this.ws.onmessage=function(e){var n=function(e){if(e.byteLength<39)return null;var t=new Int8Array(e.slice(0,3));if(1!==t[0])return null;var n=t[1];if(!x.includes(n))return null;var s=(new TextDecoder).decode(e.slice(3,39)),i={type:O[n],id:s,waitIntercept:1===t[2]};if(39===e.byteLength)return i;if(n===w.requestBody||n===w.responseBody)return i.content=e.slice(39),i;var r=(new TextDecoder).decode(e.slice(39));try{r=JSON.parse(r)}catch(c){return null}return i.content=r,i}(e.data);if(n){if("request"===n.type){var s={id:n.id,request:n.content,waitIntercept:n.waitIntercept};t.flowMgr.add(s),t.setState({flows:t.flowMgr.showList()})}else if("requestBody"===n.type){var i=t.flowMgr.get(n.id);if(!i)return;i.request.body=n.content,t.setState({flows:t.state.flows})}else if("response"===n.type){var r=t.flowMgr.get(n.id);if(!r)return;r.waitIntercept=n.waitIntercept,r.response=n.content,t.setState({flows:t.state.flows})}else if("responseBody"===n.type){var c=t.flowMgr.get(n.id);if(!c||!c.response)return;c.waitIntercept=n.waitIntercept,c.response.body=n.content,t.setState({flows:t.state.flows})}}else console.error("parse error:",e.data)},this.ws.onerror=function(e){console.log("ERROR:",e)})}},{key:"renderFlow",value:function(){var e=this,t=this.state,n=t.flow,s=t.flowTab;if(!n)return null;var i=n.request,r=n.response||{};return Object(m.jsxs)("div",{className:"flow-detail",children:[Object(m.jsxs)("div",{className:"header-tabs",children:[Object(m.jsx)("span",{onClick:function(){e.setState({flow:null})},children:"x"}),Object(m.jsx)("span",{className:"Headers"===s?"selected":null,onClick:function(){e.setState({flowTab:"Headers"})},children:"Headers"}),Object(m.jsx)("span",{className:"Preview"===s?"selected":null,onClick:function(){e.setState({flowTab:"Preview"})},children:"Preview"}),Object(m.jsx)("span",{className:"Response"===s?"selected":null,onClick:function(){e.setState({flowTab:"Response"})},children:"Response"}),n.waitIntercept?Object(m.jsxs)("div",{className:"flow-wait-area",children:[Object(m.jsx)(j.a,{size:"sm",onClick:function(){var t=v(11,n.id,JSON.stringify(n.request));e.ws.send(t),n.waitIntercept=!1,e.setState({flows:e.state.flows})},children:"Continue"}),Object(m.jsx)(j.a,{size:"sm",children:"Drop"})]}):null]}),Object(m.jsxs)("div",{style:{padding:"20px"},children:["Headers"!==s?null:Object(m.jsxs)("div",{children:[Object(m.jsxs)("div",{className:"header-block",children:[Object(m.jsx)("p",{children:"General"}),Object(m.jsxs)("div",{className:"header-block-content",children:[Object(m.jsxs)("p",{children:["Request URL: ",i.url]}),Object(m.jsxs)("p",{children:["Request Method: ",i.method]}),Object(m.jsxs)("p",{children:["Status Code: ","".concat(r.statusCode||"(pending)")]})]})]}),r.header?Object(m.jsxs)("div",{className:"header-block",children:[Object(m.jsx)("p",{children:"Response Headers"}),Object(m.jsx)("div",{className:"header-block-content",children:Object.keys(r.header).map((function(e){return Object(m.jsxs)("p",{children:[e,": ",r.header[e].join(" ")]},e)}))})]}):null,Object(m.jsxs)("div",{className:"header-block",children:[Object(m.jsx)("p",{children:"Request Headers"}),Object(m.jsx)("div",{className:"header-block-content",children:i.header?Object.keys(i.header).map((function(e){return Object(m.jsxs)("p",{children:[e,": ",i.header[e].join(" ")]},e)})):null})]}),i.body&&i.body.byteLength?Object(m.jsxs)("div",{className:"header-block",children:[Object(m.jsx)("p",{children:"Request Body"}),Object(m.jsx)("div",{className:"header-block-content",children:Object(m.jsx)("p",{children:b(i)?(new TextDecoder).decode(i.body):"Not text"})})]}):null]}),"Response"!==s?null:r.body&&r.body.byteLength?b(r)?Object(m.jsx)("div",{children:(new TextDecoder).decode(r.body)}):Object(m.jsx)("div",{children:"Not text response"}):Object(m.jsx)("div",{children:"No response"})]})]})}},{key:"render",value:function(){var e=this,t=this.state,n=t.flows,s=t.interceptUriInputing,i=t.interceptUri;return Object(m.jsxs)("div",{className:"main-table-wrap",children:[Object(m.jsxs)("div",{className:"top-control",children:[Object(m.jsx)("div",{children:Object(m.jsx)(j.a,{size:"sm",onClick:function(){e.flowMgr.clear(),e.setState({flows:e.flowMgr.showList(),flow:null})},children:"Clear"})}),Object(m.jsx)("div",{children:Object(m.jsx)(u.a.Control,{size:"sm",placeholder:"Filter",onChange:function(t){var n=t.target.value;e.flowMgr.changeFilterLazy(n,(function(){e.setState({flows:e.flowMgr.showList()})}))}})}),Object(m.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[Object(m.jsx)(u.a.Control,{size:"sm",placeholder:"Set interpect",value:s,onChange:function(t){e.setState({interceptUriInputing:t.target.value||""})}}),Object(m.jsx)(j.a,{size:"sm",onClick:function(){e.setState({interceptUri:s});var t=v(21,"00000000-0000-0000-0000-000000000000",s);e.ws.send(t)},children:"Set"}),i?Object(m.jsx)("span",{children:"Intercept:".concat(i)}):null]})]}),Object(m.jsxs)(h.a,{striped:!0,bordered:!0,size:"sm",children:[Object(m.jsx)("thead",{children:Object(m.jsxs)("tr",{children:[Object(m.jsx)("th",{children:"No"}),Object(m.jsx)("th",{children:"Host"}),Object(m.jsx)("th",{children:"Path"}),Object(m.jsx)("th",{children:"Method"}),Object(m.jsx)("th",{children:"Status"}),Object(m.jsx)("th",{children:"Size"})]})}),Object(m.jsx)("tbody",{children:n.map((function(t){var n=t.request.url,s=new URL(n),i=s.host;i.length>35&&(i=i.slice(0,35)+"...");var r=s.pathname+s.search;r.length>65&&(r=r.slice(0,65)+"...");var c=t.request,l=t.response||{},o=[];return e.state.flow&&e.state.flow.id===t.id&&o.push("tr-selected"),t.waitIntercept&&o.push("tr-wait-intercept"),Object(m.jsxs)("tr",{className:o.length?o.join(" "):null,onClick:function(){e.setState({flow:t})},children:[Object(m.jsx)("td",{children:t.no}),Object(m.jsx)("td",{children:i}),Object(m.jsx)("td",{children:r}),Object(m.jsx)("td",{children:c.method}),Object(m.jsx)("td",{children:l.statusCode||"(pending)"}),Object(m.jsx)("td",{children:p(l)})]},t.id)}))})]}),this.renderFlow()]})}}]),n}(i.a.Component),g=function(e){e&&e instanceof Function&&n.e(3).then(n.bind(null,29)).then((function(t){var n=t.getCLS,s=t.getFID,i=t.getFCP,r=t.getLCP,c=t.getTTFB;n(e),s(e),i(e),r(e),c(e)}))};c.a.render(Object(m.jsx)(i.a.StrictMode,{children:Object(m.jsx)(y,{})}),document.getElementById("root")),g()}},[[28,1,2]]]);
+//# sourceMappingURL=main.7030457c.chunk.js.map
\ No newline at end of file
diff --git a/addon/web/client/build/static/js/main.7030457c.chunk.js.map b/addon/web/client/build/static/js/main.7030457c.chunk.js.map
new file mode 100644
index 0000000..42c8b36
--- /dev/null
+++ b/addon/web/client/build/static/js/main.7030457c.chunk.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["flow.js","utils.js","App.js","reportWebVitals.js","index.js"],"names":["FlowManager","this","items","_map","Map","filterText","filterTimer","num","max","filter","item","request","url","includes","no","push","set","id","length","oldest","shift","delete","get","text","callback","clearTimeout","setTimeout","isTextResponse","response","header","test","join","getSize","len","parseInt","body","byteLength","isNaN","toFixed","messageEnum","allMessageBytes","Object","keys","map","k","messageByteMap","reduce","m","buildMessage","messageType","content","TextEncoder","encode","data","Uint8Array","App","props","flowMgr","state","flows","showList","flow","flowTab","interceptUriInputing","interceptUri","ws","initWs","close","host","URL","document","WebSocket","binaryType","onopen","console","log","onclose","onmessage","evt","msg","meta","Int8Array","slice","type","TextDecoder","decode","resp","waitIntercept","JSON","parse","err","parseMessage","add","setState","error","onerror","className","onClick","Button","size","stringify","send","style","padding","method","statusCode","key","clear","Form","Control","placeholder","onChange","e","value","target","changeFilterLazy","display","alignItems","Table","striped","bordered","f","u","path","pathname","search","classNames","renderFlow","React","Component","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.7030457c.chunk.js","sourcesContent":["export class FlowManager {\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) {\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 this._map.delete(oldest.id)\n }\n }\n\n get(id) {\n return this._map.get(id)\n }\n\n changeFilter(text) {\n this.filterText = text\n }\n\n changeFilterLazy(text, callback) {\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)\n }\n\n clear() {\n this.items = []\n this._map = new Map()\n }\n}\n","export const isTextResponse = response => {\n if (!response) return false\n if (!response.header) return false\n if (!response.header['Content-Type']) return false\n\n return /text|javascript|json/.test(response.header['Content-Type'].join(''))\n}\n\nexport const getSize = response => {\n if (!response) return '0'\n if (!response.header) return '0'\n\n let len\n if (response.header['Content-Length']) {\n len = parseInt(response.header['Content-Length'][0])\n } else if (response && response.body) {\n len = response.body.byteLength\n }\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\nconst messageEnum = {\n 'request': 1,\n 'requestBody': 2,\n 'response': 3,\n 'responseBody': 4,\n}\n\nconst allMessageBytes = Object.keys(messageEnum).map(k => messageEnum[k])\n\nconst messageByteMap = Object.keys(messageEnum).reduce((m, k) => {\n m[messageEnum[k]] = k\n return m\n}, {})\n\nexport const parseMessage = data => {\n if (data.byteLength < 39) return null\n const meta = new Int8Array(data.slice(0, 3))\n const version = meta[0]\n if (version !== 1) return null\n const type = meta[1]\n if (!allMessageBytes.includes(type)) return null\n const id = new TextDecoder().decode(data.slice(3, 39))\n\n const resp = {\n type: messageByteMap[type],\n id,\n waitIntercept: meta[2] === 1,\n }\n if (data.byteLength === 39) return resp\n if (type === messageEnum['requestBody'] || type === messageEnum['responseBody']) {\n resp.content = data.slice(39)\n return resp\n }\n\n let content = new TextDecoder().decode(data.slice(39))\n try {\n content = JSON.parse(content)\n } catch (err) {\n return null\n }\n\n resp.content = content\n return resp\n}\n\n/**\n * \n * @param {number} messageType \n * @param {string} id \n * @param {string} content \n */\nexport const buildMessage = (messageType, id, content) => {\n content = new TextEncoder().encode(content)\n const data = new Uint8Array(39 + content.byteLength)\n data[0] = 1\n data[1] = messageType\n data[2] = 0\n data.set(new TextEncoder().encode(id), 3)\n data.set(content, 39)\n return data\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 { FlowManager } from './flow'\nimport { isTextResponse, getSize, parseMessage, buildMessage } from './utils'\n\nclass App extends React.Component {\n\n constructor(props) {\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 interceptUriInputing: '',\n interceptUri: '',\n }\n\n this.ws = 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 === 'request') {\n const flow = { id: msg.id, request: msg.content, waitIntercept: msg.waitIntercept }\n this.flowMgr.add(flow)\n this.setState({ flows: this.flowMgr.showList() })\n }\n else if (msg.type === 'requestBody') {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.request.body = msg.content\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === 'response') {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.waitIntercept = msg.waitIntercept\n flow.response = msg.content\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === 'responseBody') {\n const flow = this.flowMgr.get(msg.id)\n if (!flow || !flow.response) return\n flow.waitIntercept = msg.waitIntercept\n flow.response.body = msg.content\n this.setState({ flows: this.state.flows })\n }\n }\n this.ws.onerror = evt => {\n console.log('ERROR:', evt)\n }\n }\n\n renderFlow() {\n const { flow, flowTab } = this.state\n if (!flow) return null\n\n const request = flow.request\n const response = flow.response || {}\n\n return (\n \n
\n
{ this.setState({ flow: null }) }}>x \n
{ this.setState({ flowTab: 'Headers' }) }}>Headers \n
{ this.setState({ flowTab: 'Preview' }) }}>Preview \n
{ this.setState({ flowTab: 'Response' }) }}>Response \n {\n !flow.waitIntercept ? null :\n
\n {\n const msg = buildMessage(11, flow.id, JSON.stringify(flow.request))\n this.ws.send(msg)\n flow.waitIntercept = false\n this.setState({ flows: this.state.flows })\n }}>Continue \n Drop \n
\n }\n
\n\n
\n {\n !(flowTab === 'Headers') ? null :\n
\n
\n
General
\n
\n
Request URL: {request.url}
\n
Request Method: {request.method}
\n
Status Code: {`${response.statusCode || '(pending)'}`}
\n
\n
\n\n {\n !(response.header) ? null :\n
\n
Response Headers
\n
\n {\n Object.keys(response.header).map(key => {\n return (\n
{key}: {response.header[key].join(' ')}
\n )\n })\n }\n
\n
\n }\n\n
\n
Request Headers
\n
\n {\n !(request.header) ? null :\n Object.keys(request.header).map(key => {\n return (\n
{key}: {request.header[key].join(' ')}
\n )\n })\n }\n
\n
\n\n {\n !(request.body && request.body.byteLength) ? null :\n
\n
Request Body
\n
\n
\n {\n !(isTextResponse(request)) ? \"Not text\" :\n new TextDecoder().decode(request.body)\n }\n
\n
\n
\n }\n\n
\n }\n\n {\n !(flowTab === 'Response') ? null :\n !(response.body && response.body.byteLength) ?
No response
:\n !(isTextResponse(response)) ?
Not text response
:\n
\n {new TextDecoder().decode(response.body)}\n
\n }\n
\n\n
\n )\n }\n \n render() {\n const { flows, interceptUriInputing, interceptUri } = this.state\n return (\n \n
\n
{\n this.flowMgr.clear()\n this.setState({ flows: this.flowMgr.showList(), flow: null })\n }}>Clear
\n
\n
{\n const value = e.target.value\n this.flowMgr.changeFilterLazy(value, () => {\n this.setState({ flows: this.flowMgr.showList() })\n })\n }}\n >\n \n \n\n
\n
{\n this.setState({ interceptUriInputing: e.target.value || '' })\n }}> \n {\n this.setState({ interceptUri: interceptUriInputing })\n const msg = buildMessage(21, '00000000-0000-0000-0000-000000000000', interceptUriInputing)\n this.ws.send(msg)\n }}>Set \n {\n interceptUri ? {`Intercept:${interceptUri}`} : null\n }\n \n
\n\n
\n \n \n No \n Host \n Path \n Method \n Status \n Size \n \n \n \n {\n flows.map(f => {\n const url = f.request.url\n const u = new URL(url)\n let host = u.host\n if (host.length > 35) host = host.slice(0, 35) + '...'\n let path = u.pathname + u.search\n if (path.length > 65) path = path.slice(0, 65) + '...'\n\n const request = f.request\n const response = f.response || {}\n\n const classNames = []\n if (this.state.flow && this.state.flow.id === f.id) classNames.push('tr-selected')\n if (f.waitIntercept) classNames.push('tr-wait-intercept')\n\n return (\n {\n this.setState({ flow: f })\n }}\n >\n {f.no} \n {host} \n {path} \n {request.method} \n {response.statusCode || '(pending)'} \n {getSize(response)} \n \n )\n })\n }\n \n
\n\n {this.renderFlow()}\n
\n )\n }\n}\n\nexport default App\n","const reportWebVitals = onPerfEntry => {\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 \n \n ,\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":""}
\ No newline at end of file