mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-06-10 06:10:46 +00:00
b62d46e50e
- Use errors.Is() instead of direct sentinel comparison (13 instances) - Convert if/else-if chains to switch/case for same-variable comparisons - Remove redundant bitwise OR with zero - Add post-implementation checklist to CLAUDE.md
83 lines
1.6 KiB
Go
83 lines
1.6 KiB
Go
//go:build tsnet
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
|
|
"tailscale.com/tsnet"
|
|
|
|
"github.com/nextlevelbuilder/goclaw/internal/config"
|
|
)
|
|
|
|
// initTailscale starts an additional Tailscale listener alongside the main gateway.
|
|
// Only compiled with -tags tsnet. The listener shares the same http.Handler (mux).
|
|
func initTailscale(ctx context.Context, cfg *config.Config, mux http.Handler) func() {
|
|
tc := cfg.Tailscale
|
|
if tc.Hostname == "" {
|
|
slog.Debug("Tailscale available but not configured (set GOCLAW_TSNET_HOSTNAME to enable)")
|
|
return nil
|
|
}
|
|
|
|
srv := &tsnet.Server{
|
|
Hostname: tc.Hostname,
|
|
AuthKey: tc.AuthKey,
|
|
Ephemeral: tc.Ephemeral,
|
|
}
|
|
if tc.StateDir != "" {
|
|
srv.Dir = tc.StateDir
|
|
}
|
|
|
|
var (
|
|
ln net.Listener
|
|
err error
|
|
)
|
|
|
|
if tc.EnableTLS {
|
|
ln, err = srv.ListenTLS("tcp", ":443")
|
|
} else {
|
|
ln, err = srv.Listen("tcp", ":80")
|
|
}
|
|
if err != nil {
|
|
slog.Warn("Tailscale listener failed to start", "error", err)
|
|
srv.Close()
|
|
return nil
|
|
}
|
|
|
|
port := ":80"
|
|
if tc.EnableTLS {
|
|
port = ":443 (TLS)"
|
|
}
|
|
slog.Info("Tailscale listener started",
|
|
"hostname", tc.Hostname,
|
|
"port", port,
|
|
)
|
|
|
|
httpSrv := &http.Server{Handler: mux}
|
|
go func() {
|
|
if err := httpSrv.Serve(ln); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
slog.Warn("Tailscale HTTP server error", "error", err)
|
|
}
|
|
}()
|
|
|
|
// Graceful shutdown on context cancellation
|
|
go func() {
|
|
<-ctx.Done()
|
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
httpSrv.Shutdown(shutdownCtx)
|
|
}()
|
|
|
|
return func() {
|
|
httpSrv.Close()
|
|
ln.Close()
|
|
srv.Close()
|
|
slog.Info("Tailscale listener stopped")
|
|
}
|
|
}
|