Skip to content

Commit 2bc98ab

Browse files
committed
client/web: add web client Server struct
Updates tailscale/corp#13775 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
1 parent 7815fbe commit 2bc98ab

File tree

2 files changed

+36
-16
lines changed

2 files changed

+36
-16
lines changed

client/web/web.go

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,25 @@ var authenticationRedirectHTML string
4444

4545
var tmpl *template.Template
4646

47-
var localClient tailscale.LocalClient
47+
// Server is the backend server for a Tailscale web client.
48+
type Server struct {
49+
devMode bool
50+
lc *tailscale.LocalClient
51+
}
52+
53+
// NewServer constructs a new Tailscale web client server.
54+
//
55+
// lc is an optional parameter. When not filled, NewServer
56+
// initializes its own tailscale.LocalClient.
57+
func NewServer(devMode bool, lc *tailscale.LocalClient) *Server {
58+
if lc == nil {
59+
lc = &tailscale.LocalClient{}
60+
}
61+
return &Server{
62+
devMode: devMode,
63+
lc: lc,
64+
}
65+
}
4866

4967
func init() {
5068
tmpl = template.Must(template.New("web.html").Parse(webHTML))
@@ -264,8 +282,8 @@ req.send(null);
264282
</body></html>
265283
`
266284

267-
// Handle processes all requests for the Tailscale web client.
268-
func Handle(w http.ResponseWriter, r *http.Request) {
285+
// ServeHTTP processes all requests for the Tailscale web client.
286+
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
269287
ctx := r.Context()
270288
if authRedirect(w, r) {
271289
return
@@ -281,12 +299,12 @@ func Handle(w http.ResponseWriter, r *http.Request) {
281299
return
282300
}
283301

284-
st, err := localClient.StatusWithoutPeers(ctx)
302+
st, err := s.lc.StatusWithoutPeers(ctx)
285303
if err != nil {
286304
http.Error(w, err.Error(), http.StatusInternalServerError)
287305
return
288306
}
289-
prefs, err := localClient.GetPrefs(ctx)
307+
prefs, err := s.lc.GetPrefs(ctx)
290308
if err != nil {
291309
http.Error(w, err.Error(), http.StatusInternalServerError)
292310
return
@@ -316,7 +334,7 @@ func Handle(w http.ResponseWriter, r *http.Request) {
316334
mp.Prefs.AdvertiseRoutes = routes
317335
log.Printf("Doing edit: %v", mp.Pretty())
318336

319-
if _, err := localClient.EditPrefs(ctx, mp); err != nil {
337+
if _, err := s.lc.EditPrefs(ctx, mp); err != nil {
320338
w.WriteHeader(http.StatusInternalServerError)
321339
json.NewEncoder(w).Encode(mi{"error": err.Error()})
322340
return
@@ -331,7 +349,7 @@ func Handle(w http.ResponseWriter, r *http.Request) {
331349
logout = true
332350
}
333351
log.Printf("tailscaleUp(reauth=%v, logout=%v) ...", reauth, logout)
334-
url, err := tailscaleUp(r.Context(), st, postData)
352+
url, err := s.tailscaleUp(r.Context(), st, postData)
335353
log.Printf("tailscaleUp = (URL %v, %v)", url != "", err)
336354
if err != nil {
337355
w.WriteHeader(http.StatusInternalServerError)
@@ -386,9 +404,9 @@ func Handle(w http.ResponseWriter, r *http.Request) {
386404
w.Write(buf.Bytes())
387405
}
388406

389-
func tailscaleUp(ctx context.Context, st *ipnstate.Status, postData postedData) (authURL string, retErr error) {
407+
func (s *Server) tailscaleUp(ctx context.Context, st *ipnstate.Status, postData postedData) (authURL string, retErr error) {
390408
if postData.ForceLogout {
391-
if err := localClient.Logout(ctx); err != nil {
409+
if err := s.lc.Logout(ctx); err != nil {
392410
return "", fmt.Errorf("Logout error: %w", err)
393411
}
394412
return "", nil
@@ -415,18 +433,18 @@ func tailscaleUp(ctx context.Context, st *ipnstate.Status, postData postedData)
415433

416434
watchCtx, cancelWatch := context.WithCancel(ctx)
417435
defer cancelWatch()
418-
watcher, err := localClient.WatchIPNBus(watchCtx, 0)
436+
watcher, err := s.lc.WatchIPNBus(watchCtx, 0)
419437
if err != nil {
420438
return "", err
421439
}
422440
defer watcher.Close()
423441

424442
go func() {
425443
if !isRunning {
426-
localClient.Start(ctx, ipn.Options{})
444+
s.lc.Start(ctx, ipn.Options{})
427445
}
428446
if forceReauth {
429-
localClient.StartLoginInteractive(ctx)
447+
s.lc.StartLoginInteractive(ctx)
430448
}
431449
}()
432450

cmd/tailscale/cli/web.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Tailscale, as opposed to a CLI or a native app.
3838
webf := newFlagSet("web")
3939
webf.StringVar(&webArgs.listen, "listen", "localhost:8088", "listen address; use port 0 for automatic")
4040
webf.BoolVar(&webArgs.cgi, "cgi", false, "run as CGI script")
41+
webf.BoolVar(&webArgs.dev, "dev", false, "run web client in developer mode")
4142
return webf
4243
})(),
4344
Exec: runWeb,
@@ -46,6 +47,7 @@ Tailscale, as opposed to a CLI or a native app.
4647
var webArgs struct {
4748
listen string
4849
cgi bool
50+
dev bool
4951
}
5052

5153
func tlsConfigFromEnvironment() *tls.Config {
@@ -76,10 +78,10 @@ func runWeb(ctx context.Context, args []string) error {
7678
return fmt.Errorf("too many non-flag arguments: %q", args)
7779
}
7880

79-
webHandler := http.HandlerFunc(web.Handle)
81+
webServer := web.NewServer(webArgs.dev, nil)
8082

8183
if webArgs.cgi {
82-
if err := cgi.Serve(webHandler); err != nil {
84+
if err := cgi.Serve(webServer); err != nil {
8385
log.Printf("tailscale.cgi: %v", err)
8486
return err
8587
}
@@ -91,14 +93,14 @@ func runWeb(ctx context.Context, args []string) error {
9193
server := &http.Server{
9294
Addr: webArgs.listen,
9395
TLSConfig: tlsConfig,
94-
Handler: webHandler,
96+
Handler: webServer,
9597
}
9698

9799
log.Printf("web server running on: https://%s", server.Addr)
98100
return server.ListenAndServeTLS("", "")
99101
} else {
100102
log.Printf("web server running on: %s", urlOfListenAddr(webArgs.listen))
101-
return http.ListenAndServe(webArgs.listen, webHandler)
103+
return http.ListenAndServe(webArgs.listen, webServer)
102104
}
103105
}
104106

0 commit comments

Comments
 (0)