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>
This commit is contained in:
Mihai Parparita 2023-02-09 14:58:20 -08:00 committed by Brad Fitzpatrick
parent 9e4d99305b
commit 6799ef838f

View File

@ -707,6 +707,9 @@ func (h *peerAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
case "/v0/interfaces":
h.handleServeInterfaces(w, r)
return
case "/v0/doctor":
h.handleServeDoctor(w, r)
return
case "/v0/ingress":
metricIngressCalls.Add(1)
h.handleServeIngress(w, r)
@ -818,6 +821,24 @@ func (h *peerAPIHandler) handleServeInterfaces(w http.ResponseWriter, r *http.Re
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 {
name string // "foo.jpg"
started time.Time