From 18b571b016de36fcac979f52efd38364672cc46c Mon Sep 17 00:00:00 2001 From: lqqyt2423 <974923609@qq.com> Date: Sat, 11 Feb 2023 22:36:37 +0800 Subject: [PATCH] web addon optimization --- proxy/addon.go | 2 +- proxy/connection.go | 1 + proxy/proxy.go | 28 ++++++++++++++++ web/client/src/App.css | 4 +++ web/client/src/App.tsx | 11 ++++-- web/client/src/components/FlowPreview.tsx | 9 +++-- web/client/src/components/ViewFlow.tsx | 41 +++++++++++++++++------ web/client/src/lib/connection.ts | 2 ++ web/client/src/lib/flow.ts | 6 +++- web/client/src/lib/message.ts | 7 +++- web/message.go | 7 ++-- 11 files changed, 99 insertions(+), 19 deletions(-) diff --git a/proxy/addon.go b/proxy/addon.go index 84232a6..5fbb531 100644 --- a/proxy/addon.go +++ b/proxy/addon.go @@ -81,7 +81,7 @@ func (addon *LogAddon) ServerConnected(connCtx *ConnContext) { } func (addon *LogAddon) ServerDisconnected(connCtx *ConnContext) { - log.Infof("%v server disconnect %v (%v->%v)\n", connCtx.ClientConn.Conn.RemoteAddr(), connCtx.ServerConn.Address, connCtx.ServerConn.Conn.LocalAddr(), connCtx.ServerConn.Conn.RemoteAddr()) + log.Infof("%v server disconnect %v (%v->%v) - %v\n", connCtx.ClientConn.Conn.RemoteAddr(), connCtx.ServerConn.Address, connCtx.ServerConn.Conn.LocalAddr(), connCtx.ServerConn.Conn.RemoteAddr(), connCtx.FlowCount) } func (addon *LogAddon) Requestheaders(f *Flow) { diff --git a/proxy/connection.go b/proxy/connection.go index cc8255f..8262dd5 100644 --- a/proxy/connection.go +++ b/proxy/connection.go @@ -80,6 +80,7 @@ var connContextKey = new(struct{}) type ConnContext struct { ClientConn *ClientConn `json:"clientConn"` ServerConn *ServerConn `json:"serverConn"` + FlowCount uint32 `json:"-"` proxy *Proxy pipeConn *pipeConn diff --git a/proxy/proxy.go b/proxy/proxy.go index 4af7fe3..d4cfdf0 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -165,6 +165,8 @@ func (proxy *Proxy) ServeHTTP(res http.ResponseWriter, req *http.Request) { f.ConnContext = req.Context().Value(connContextKey).(*ConnContext) defer f.finish() + f.ConnContext.FlowCount = f.ConnContext.FlowCount + 1 + // trigger addon event Requestheaders for _, addon := range proxy.Addons { addon.Requestheaders(f) @@ -283,6 +285,16 @@ func (proxy *Proxy) handleConnect(res http.ResponseWriter, req *http.Request) { "host": req.Host, }) + f := newFlow() + f.Request = newRequest(req) + f.ConnContext = req.Context().Value(connContextKey).(*ConnContext) + defer f.finish() + + // trigger addon event Requestheaders + for _, addon := range proxy.Addons { + addon.Requestheaders(f) + } + var conn net.Conn var err error if proxy.shouldIntercept == nil || proxy.shouldIntercept(req.Host) { @@ -316,6 +328,22 @@ func (proxy *Proxy) handleConnect(res http.ResponseWriter, req *http.Request) { return } + f.Response = &Response{ + StatusCode: 200, + Header: make(http.Header), + } + + // trigger addon event Responseheaders + for _, addon := range proxy.Addons { + addon.Responseheaders(f) + } + defer func(f *Flow) { + // trigger addon event Response + for _, addon := range proxy.Addons { + addon.Response(f) + } + }(f) + transfer(log, conn, cconn) } diff --git a/web/client/src/App.css b/web/client/src/App.css index 42cc3c8..89bb933 100644 --- a/web/client/src/App.css +++ b/web/client/src/App.css @@ -56,6 +56,10 @@ color: white; } +.main-table-wrap tbody tr.tr-wait-warn { + background-color: rgb(255, 243, 205); +} + .flow-detail { position: fixed; top: 0; diff --git a/web/client/src/App.tsx b/web/client/src/App.tsx index 4feff07..19fce97 100644 --- a/web/client/src/App.tsx +++ b/web/client/src/App.tsx @@ -110,10 +110,17 @@ class App extends React.Component { // console.log('msg:', msg) if (msg.type === MessageType.CONN) { - this.connMgr.add(msg.id, msg.content as IConnection) + const conn = msg.content as IConnection + conn.opening = true + this.connMgr.add(msg.id, conn) this.setState({ flows: this.state.flows }) } else if (msg.type === MessageType.CONN_CLOSE) { + const conn = this.connMgr.get(msg.id) + if (!conn) return + conn.opening = false + conn.flowCount = msg.content as number + this.setState({ flows: this.state.flows }) this.connMgr.delete(msg.id) } else if (msg.type === MessageType.REQUEST) { @@ -197,7 +204,7 @@ class App extends React.Component { No Method - Host + Host Path Type Status diff --git a/web/client/src/components/FlowPreview.tsx b/web/client/src/components/FlowPreview.tsx index e486562..6b82b64 100644 --- a/web/client/src/components/FlowPreview.tsx +++ b/web/client/src/components/FlowPreview.tsx @@ -20,8 +20,13 @@ class FlowPreview extends React.Component { const fp = this.props.flow const classNames = [] - if (this.props.isSelected) classNames.push('tr-selected') - if (fp.waitIntercept) classNames.push('tr-wait-intercept') + if (this.props.isSelected) { + classNames.push('tr-selected') + } else if (fp.waitIntercept) { + classNames.push('tr-wait-intercept') + } else if (fp.warn) { + classNames.push('tr-wait-warn') + } return ( { if (!flow) return null const conn = flow.getConn() - if (!conn) return null return (
-

Server Connection

+

Flow Info

-

Address: {conn.serverConn.address}

-

Resolved Address: {conn.serverConn.peername}

-
-
-
-

Client Connection

-
-

Address: {conn.clientConn.address}

+

Id: {flow.id}

+ { + !conn ? null : + <> +
+

Server Connection

+
+

Address: {conn.serverConn.address}

+

Resolved Address: {conn.serverConn.peername}

+
+
+
+

Client Connection

+
+

Address: {conn.clientConn.address}

+
+
+
+

Connection Info

+
+

Id: {conn.clientConn.id}

+

Opening: {conn.opening ? 'true' : 'false'}

+ { + conn.flowCount == null ? null : +

Flow Count: {conn.flowCount}

+ } +
+
+ + }
) } diff --git a/web/client/src/lib/connection.ts b/web/client/src/lib/connection.ts index ee9b9dc..fac80b9 100644 --- a/web/client/src/lib/connection.ts +++ b/web/client/src/lib/connection.ts @@ -9,6 +9,8 @@ export interface IConnection { address: string peername: string } + opening: boolean + flowCount?: number } export class ConnectionManager { diff --git a/web/client/src/lib/flow.ts b/web/client/src/lib/flow.ts index df0f4d2..9060b0e 100644 --- a/web/client/src/lib/flow.ts +++ b/web/client/src/lib/flow.ts @@ -40,6 +40,7 @@ export interface IFlowPreview { size: string costTime: string contentType: string + warn: boolean } export class Flow { @@ -87,7 +88,9 @@ export class Flow { this.connId = flowRequestMsg.connId this.request = flowRequestMsg.request - this.url = new URL(this.request.url) + let rawUrl = this.request.url + if (rawUrl.startsWith('//')) rawUrl = 'http:' + rawUrl + this.url = new URL(rawUrl) this.path = this.url.pathname + this.url.search this._isTextRequest = null @@ -151,6 +154,7 @@ export class Flow { size: this.size, costTime: this.costTime, contentType: this.contentType, + warn: this.getConn()?.flowCount === 0, } } diff --git a/web/client/src/lib/message.ts b/web/client/src/lib/message.ts index 7036364..56ee32a 100644 --- a/web/client/src/lib/message.ts +++ b/web/client/src/lib/message.ts @@ -25,7 +25,7 @@ export interface IMessage { type: MessageType id: string waitIntercept: boolean - content?: ArrayBuffer | IFlowRequest | IResponse | IConnection + content?: ArrayBuffer | IFlowRequest | IResponse | IConnection | number } // type: 0/1/2/3/4 @@ -51,6 +51,11 @@ export const parseMessage = (data: ArrayBuffer): IMessage | null => { resp.content = data.slice(39) return resp } + if (type === MessageType.CONN_CLOSE) { + const view = new DataView(data.slice(39)) + resp.content = view.getUint32(0, false) + return resp + } const contentStr = new TextDecoder().decode(data.slice(39)) let content: any diff --git a/web/message.go b/web/message.go index 0300d6a..3cb87eb 100644 --- a/web/message.go +++ b/web/message.go @@ -117,9 +117,12 @@ func newMessageFlow(mType messageType, f *proxy.Flow) *messageFlow { } func newMessageConnClose(connCtx *proxy.ConnContext) *messageFlow { + var buf bytes.Buffer + binary.Write(&buf, binary.BigEndian, connCtx.FlowCount) return &messageFlow{ - mType: messageTypeConnClose, - id: connCtx.Id(), + mType: messageTypeConnClose, + id: connCtx.Id(), + content: buf.Bytes(), } }