example_tshello_test.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package tsnet_test
  4. import (
  5. "flag"
  6. "fmt"
  7. "html"
  8. "log"
  9. "net/http"
  10. "strings"
  11. "tailscale.com/tsnet"
  12. )
  13. func firstLabel(s string) string {
  14. s, _, _ = strings.Cut(s, ".")
  15. return s
  16. }
  17. // Example_tshello is a full example on using tsnet. When you run this program it will print
  18. // an authentication link. Open it in your favorite web browser and add it to your tailnet
  19. // like any other machine. Open another terminal window and try to ping it:
  20. //
  21. // $ ping tshello -c 2
  22. // PING tshello (100.105.183.159) 56(84) bytes of data.
  23. // 64 bytes from tshello.your-tailnet.ts.net (100.105.183.159): icmp_seq=1 ttl=64 time=25.0 ms
  24. // 64 bytes from tshello.your-tailnet.ts.net (100.105.183.159): icmp_seq=2 ttl=64 time=1.12 ms
  25. //
  26. // Then connect to it using curl:
  27. //
  28. // $ curl http://tshello
  29. // <html><body><h1>Hello, world!</h1>
  30. // <p>You are <b>Xe</b> from <b>pneuma</b> (100.78.40.86:49214)</p>
  31. //
  32. // From here you can do anything you want with the Go standard library HTTP stack, or anything
  33. // that is compatible with it (Gin/Gonic, Gorilla/mux, etc.).
  34. func Example_tshello() {
  35. var (
  36. addr = flag.String("addr", ":80", "address to listen on")
  37. hostname = flag.String("hostname", "tshello", "hostname to use on the tailnet")
  38. )
  39. flag.Parse()
  40. s := new(tsnet.Server)
  41. s.Hostname = *hostname
  42. defer s.Close()
  43. ln, err := s.Listen("tcp", *addr)
  44. if err != nil {
  45. log.Fatal(err)
  46. }
  47. defer ln.Close()
  48. lc, err := s.LocalClient()
  49. if err != nil {
  50. log.Fatal(err)
  51. }
  52. log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  53. who, err := lc.WhoIs(r.Context(), r.RemoteAddr)
  54. if err != nil {
  55. http.Error(w, err.Error(), 500)
  56. return
  57. }
  58. fmt.Fprintf(w, "<html><body><h1>Hello, tailnet!</h1>\n")
  59. fmt.Fprintf(w, "<p>You are <b>%s</b> from <b>%s</b> (%s)</p>",
  60. html.EscapeString(who.UserProfile.LoginName),
  61. html.EscapeString(firstLabel(who.Node.ComputedName)),
  62. r.RemoteAddr)
  63. })))
  64. }