// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // The tshello server demonstrates how to use Tailscale as a library. package main import ( "crypto/tls" "flag" "fmt" "html" "log" "net/http" "strings" "tailscale.com/tsnet" ) var ( addr = flag.String("addr", ":80", "address to listen on") ) func main() { flag.Parse() s := new(tsnet.Server) defer s.Close() ln, err := s.Listen("tcp", *addr) if err != nil { log.Fatal(err) } defer ln.Close() lc, err := s.LocalClient() if err != nil { log.Fatal(err) } if *addr == ":443" { ln = tls.NewListener(ln, &tls.Config{ GetCertificate: lc.GetCertificate, }) } log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { who, err := lc.WhoIs(r.Context(), r.RemoteAddr) if err != nil { http.Error(w, err.Error(), 500) return } fmt.Fprintf(w, "
You are %s from %s (%s)
", html.EscapeString(who.UserProfile.LoginName), html.EscapeString(firstLabel(who.Node.ComputedName)), r.RemoteAddr) }))) } func firstLabel(s string) string { s, _, _ = strings.Cut(s, ".") return s }