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

Method serve

client/web/web.go:334–387  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

332}
333
334func (s *Server) serve(w http.ResponseWriter, r *http.Request) {
335 if s.mode == ManageServerMode {
336 // In manage mode, requests must be sent directly to the bare Tailscale IP address.
337 // If a request comes in on any other hostname, redirect.
338 if s.requireTailscaleIP(w, r) {
339 return // user was redirected
340 }
341
342 // serve HTTP 204 on /ok requests as connectivity check
343 if r.Method == httpm.GET && r.URL.Path == "/ok" {
344 w.WriteHeader(http.StatusNoContent)
345 return
346 }
347
348 if !s.devMode {
349 // This hash corresponds to the inline script in index.html that runs when the react app is unavailable.
350 // It was generated from https://csplite.com/csp/sha/.
351 // If the contents of the script are changed, this hash must be updated.
352 const indexScriptHash = "sha384-CW2AYVfS14P7QHZN27thEkMLKiCj3YNURPoLc1elwiEkMVHeuYTWkJOEki1F3nZc"
353
354 w.Header().Set("X-Frame-Options", "DENY")
355 w.Header().Set("Content-Security-Policy", "default-src 'self'; img-src * data:; script-src 'self' '"+indexScriptHash+"'")
356 w.Header().Set("Cross-Origin-Resource-Policy", "same-origin")
357 }
358 }
359
360 if r.URL.Path == "/metrics" {
361 r.URL.Path = "/api/local/v0/usermetrics"
362 s.proxyRequestToLocalAPI(w, r)
363 return
364 }
365
366 if strings.HasPrefix(r.URL.Path, "/api/") {
367 switch {
368 case r.URL.Path == "/api/auth" && r.Method == httpm.GET:
369 s.serveAPIAuth(w, r) // serve auth status
370 return
371 case r.URL.Path == "/api/auth/session/new" && r.Method == httpm.GET:
372 s.serveAPIAuthSessionNew(w, r) // create new session
373 return
374 case r.URL.Path == "/api/auth/session/wait" && r.Method == httpm.GET:
375 s.serveAPIAuthSessionWait(w, r) // wait for session to be authorized
376 return
377 }
378 if ok := s.authorizeRequest(w, r); !ok {
379 http.Error(w, "not authorized", http.StatusUnauthorized)
380 return
381 }
382 // Pass API requests through to the API handler.
383 s.apiHandler.ServeHTTP(w, r)
384 return
385 }
386 s.assetsHandler.ServeHTTP(w, r)
387}
388
389// requireTailscaleIP redirects an incoming request if the HTTP request was not made to a bare Tailscale IP address.
390// The request will be redirected to the Tailscale IP, port 5252, with the original request path.

Callers 1

TestServeAuthFunction · 0.95

Calls 11

requireTailscaleIPMethod · 0.95
serveAPIAuthMethod · 0.95
authorizeRequestMethod · 0.95
SetMethod · 0.65
ErrorMethod · 0.65
WriteHeaderMethod · 0.45
HeaderMethod · 0.45
ServeHTTPMethod · 0.45

Tested by 1

TestServeAuthFunction · 0.76