mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-22 08:51:41 +00:00
client/web: move api handler into web.go
Also uses `http.HandlerFunc` to pass the handler into `csrfProtect` so we can get rid of the extraneous `api` struct. Updates tailscale/corp#13775 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit is contained in:
parent
7b18ed293b
commit
4828e4c2db
@ -1,37 +0,0 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
package web
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gorilla/csrf"
|
|
||||||
"tailscale.com/util/httpm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type api struct {
|
|
||||||
s *Server
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServeHTTP 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.
|
|
||||||
func (a *api) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("X-CSRF-Token", csrf.Token(r))
|
|
||||||
path := strings.TrimPrefix(r.URL.Path, "/api")
|
|
||||||
switch path {
|
|
||||||
case "/data":
|
|
||||||
switch r.Method {
|
|
||||||
case httpm.GET:
|
|
||||||
a.s.serveGetNodeDataJSON(w, r)
|
|
||||||
case httpm.POST:
|
|
||||||
a.s.servePostNodeUpdate(w, r)
|
|
||||||
default:
|
|
||||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
http.Error(w, "invalid endpoint", http.StatusNotFound)
|
|
||||||
}
|
|
@ -30,6 +30,7 @@ import (
|
|||||||
"tailscale.com/licenses"
|
"tailscale.com/licenses"
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
|
"tailscale.com/util/httpm"
|
||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ func NewServer(ctx context.Context, opts ServerOpts) (s *Server, cleanup func())
|
|||||||
// The client is secured by limiting the interface it listens on,
|
// The client is secured by limiting the interface it listens on,
|
||||||
// or by authenticating requests before they reach the web client.
|
// or by authenticating requests before they reach the web client.
|
||||||
csrfProtect := csrf.Protect(s.csrfKey(), csrf.Secure(false))
|
csrfProtect := csrf.Protect(s.csrfKey(), csrf.Secure(false))
|
||||||
s.apiHandler = csrfProtect(&api{s: s})
|
s.apiHandler = csrfProtect(http.HandlerFunc(s.serveAPI))
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
@ -239,6 +240,27 @@ func (s *Server) serve(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func (s *Server) serveAPI(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("X-CSRF-Token", csrf.Token(r))
|
||||||
|
path := strings.TrimPrefix(r.URL.Path, "/api")
|
||||||
|
switch path {
|
||||||
|
case "/data":
|
||||||
|
switch r.Method {
|
||||||
|
case httpm.GET:
|
||||||
|
s.serveGetNodeDataJSON(w, r)
|
||||||
|
case httpm.POST:
|
||||||
|
s.servePostNodeUpdate(w, r)
|
||||||
|
default:
|
||||||
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Error(w, "invalid endpoint", http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
type nodeData struct {
|
type nodeData struct {
|
||||||
Profile tailcfg.UserProfile
|
Profile tailcfg.UserProfile
|
||||||
Status string
|
Status string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user