ipn/ipnlocal: add PeerAPI endpoint for doctor output

Useful when debugging issues (e.g. to see the full routing table), and
easier to refer to the output via a browser than trying to read it from
the logs generated by `bugreport --diagnose`.

Behind a canDebug() check, similar to the /magicsock and /interfaces
endpoints.

Updates #7184

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
pull/7241/head
Mihai Parparita 2 years ago committed by Brad Fitzpatrick
parent 9e4d99305b
commit 6799ef838f

@ -707,6 +707,9 @@ func (h *peerAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
case "/v0/interfaces": case "/v0/interfaces":
h.handleServeInterfaces(w, r) h.handleServeInterfaces(w, r)
return return
case "/v0/doctor":
h.handleServeDoctor(w, r)
return
case "/v0/ingress": case "/v0/ingress":
metricIngressCalls.Add(1) metricIngressCalls.Add(1)
h.handleServeIngress(w, r) h.handleServeIngress(w, r)
@ -818,6 +821,24 @@ func (h *peerAPIHandler) handleServeInterfaces(w http.ResponseWriter, r *http.Re
fmt.Fprintln(w, "</table>") fmt.Fprintln(w, "</table>")
} }
func (h *peerAPIHandler) handleServeDoctor(w http.ResponseWriter, r *http.Request) {
if !h.canDebug() {
http.Error(w, "denied; no debug access", http.StatusForbidden)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintln(w, "<h1>Doctor Output</h1>")
fmt.Fprintln(w, "<pre>")
h.ps.b.Doctor(r.Context(), func(format string, args ...any) {
line := fmt.Sprintf(format, args)
fmt.Fprintln(w, html.EscapeString(line))
})
fmt.Fprintln(w, "</pre>")
}
type incomingFile struct { type incomingFile struct {
name string // "foo.jpg" name string // "foo.jpg"
started time.Time started time.Time

Loading…
Cancel
Save