From bac7ee79d875ec98484f873bb10717604e9d2845 Mon Sep 17 00:00:00 2001 From: Marwan Sulaiman Date: Fri, 2 Jun 2023 14:17:56 -0400 Subject: [PATCH] Provide information on service underlying a proxy (#2) Closes #5 Signed-off-by: Tyler Smalley Co-authored-by: Marwan Sulaiman --- src/types.ts | 3 ++ src/webviews/serve-panel/simple-view.tsx | 12 ++++++ tsrelay/main.go | 50 ++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/types.ts b/src/types.ts index e535ae6..0c3b2ff 100644 --- a/src/types.ts +++ b/src/types.ts @@ -22,6 +22,9 @@ export interface Handlers { export interface ServeStatus { ServeConfig?: ServeConfig; FunnelPorts?: number[]; + Services: { + [port: number]: string; + }; BackendState: string; Self: PeerStatus; Errors?: RelayError[]; diff --git a/src/webviews/serve-panel/simple-view.tsx b/src/webviews/serve-panel/simple-view.tsx index 7193a82..66704b8 100644 --- a/src/webviews/serve-panel/simple-view.tsx +++ b/src/webviews/serve-panel/simple-view.tsx @@ -164,6 +164,18 @@ export const SimpleView = () => { )} +
+ {data?.Services[port] ? ( +
+ Port {port} is currently started by "{data?.Services[port]}" +
+ ) : ( +
+ It seems there's no service currently utilizing port {port}. Please ensure you start a + local service that is bound to port {port}. +
+ )} +
); } diff --git a/tsrelay/main.go b/tsrelay/main.go index d477760..93942a2 100644 --- a/tsrelay/main.go +++ b/tsrelay/main.go @@ -122,6 +122,7 @@ type httpHandler struct { // to some helper fields for the typescript frontend type serveStatus struct { ServeConfig *ipn.ServeConfig + Services map[uint16]string BackendState string Self *peerStatus FunnelPorts []int @@ -201,6 +202,29 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } case http.MethodGet: + var wg sync.WaitGroup + wg.Add(1) + portMap := map[uint16]string{} + go func() { + defer wg.Done() + p := &portlist.Poller{ + Interval: 10 * time.Second, + IncludeLocalhost: true, + } + defer p.Close() + ctx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + ch, err := p.Run(ctx) + if err != nil { + h.l.Printf("error polling for serve: %v", err) + return + } + update := <-ch + for _, p := range update.List { + portMap[p.Port] = p.Process + } + }() + st, sc, err := h.getConfigs(ctx) if err != nil { var oe *net.OpError @@ -221,10 +245,36 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { s := serveStatus{ ServeConfig: sc, + Services: make(map[uint16]string), BackendState: st.BackendState, FunnelPorts: []int{}, } + wg.Wait() + if sc != nil { + for _, webCfg := range sc.Web { + for _, addr := range webCfg.Handlers { + if addr.Proxy == "" { + continue + } + u, err := url.Parse(addr.Proxy) + if err != nil { + h.l.Printf("error parsing address proxy %q: %v", addr.Proxy, err) + continue + } + portInt, err := strconv.Atoi(u.Port()) + if err != nil { + h.l.Printf("error parsing port %q of proxy %q: %v", u.Port(), addr.Proxy, err) + continue + } + port := uint16(portInt) + if process, ok := portMap[port]; ok { + s.Services[port] = process + } + } + } + } + if st.Self != nil { s.Self = &peerStatus{ DNSName: st.Self.DNSName,