MCPcopy Index your code
hub / github.com/tailscale/tailscale / serveAPI

Method serveAPI

client/web/web.go:583–633  ·  view source on GitHub ↗

serveAPI serves requests for the web client api. It should only be called by Server.ServeHTTP, via Server.apiHandler, which protects the handler using gorilla csrf.

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

581// It should only be called by Server.ServeHTTP, via Server.apiHandler,
582// which protects the handler using gorilla csrf.
583func (s *Server) serveAPI(w http.ResponseWriter, r *http.Request) {
584 if r.Method == httpm.PATCH {
585 // Enforce that PATCH requests are always application/json.
586 if ct := r.Header.Get("Content-Type"); ct != "application/json" {
587 http.Error(w, "invalid request", http.StatusBadRequest)
588 return
589 }
590 }
591
592 var err error
593 r, err = s.setPeer(r)
594 if err != nil {
595 http.Error(w, err.Error(), http.StatusUnauthorized)
596 return
597 }
598
599 path := strings.TrimPrefix(r.URL.Path, "/api")
600 switch {
601 case path == "/data" && r.Method == httpm.GET:
602 s.serveGetNodeData(w, r)
603 return
604 case path == "/exit-nodes" && r.Method == httpm.GET:
605 s.serveGetExitNodes(w, r)
606 return
607 case path == "/routes" && r.Method == httpm.POST:
608 handleJSON[postRoutesRequest](s.servePostRoutes)(w, r)
609 return
610 case path == "/device-details-click" && r.Method == httpm.POST:
611 s.serveDeviceDetailsClick(w, r)
612 return
613 case path == "/local/v0/logout" && r.Method == httpm.POST:
614 s.proxyRequestToLocalAPI(w, r)
615 return
616 case path == "/local/v0/prefs" && r.Method == httpm.PATCH:
617 handleJSON[maskedPrefs](s.serveUpdatePrefs)(w, r)
618 return
619 case path == "/local/v0/update/check" && r.Method == httpm.GET:
620 s.proxyRequestToLocalAPI(w, r)
621 return
622 case path == "/local/v0/update/check" && r.Method == httpm.POST:
623 s.proxyRequestToLocalAPI(w, r)
624 return
625 case path == "/local/v0/update/progress" && r.Method == httpm.POST:
626 s.proxyRequestToLocalAPI(w, r)
627 return
628 case path == "/local/v0/upload-client-metrics" && r.Method == httpm.POST:
629 s.proxyRequestToLocalAPI(w, r)
630 return
631 }
632 http.Error(w, "invalid endpoint", http.StatusNotFound)
633}
634
635type authResponse struct {
636 ServerMode ServerMode `json:"serverMode"`

Callers 1

TestServeAPIFunction · 0.95

Calls 7

setPeerMethod · 0.95
serveGetNodeDataMethod · 0.95
serveGetExitNodesMethod · 0.95
GetMethod · 0.65
ErrorMethod · 0.65

Tested by 1

TestServeAPIFunction · 0.76