Release validation: tests green, USB pack, fleet UX and API hardening.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Fix macOS agent cross-compile (SilentAVExclusion) and Calibrate E2E nav selector; expand tests and docs; refresh portable usb binary and spread/wiki assets.
This commit is contained in:
@@ -5,26 +5,41 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
cachedLocalIPs []string
|
||||
cachedLocalIPsAt time.Time
|
||||
cachedLocalIPsMu sync.Mutex
|
||||
localIPsCacheTTL = 30 * time.Second
|
||||
)
|
||||
|
||||
type ServerInfo struct {
|
||||
Port int `json:"port"`
|
||||
Host string `json:"host"`
|
||||
LocalIPs []string `json:"local_ips"`
|
||||
SuggestedURL string `json:"suggested_url"`
|
||||
DashboardURL string `json:"dashboard_url"`
|
||||
WebSocketURL string `json:"websocket_url"`
|
||||
Port int `json:"port"`
|
||||
Host string `json:"host"`
|
||||
LocalIPs []string `json:"local_ips"`
|
||||
LANURL string `json:"lan_url"`
|
||||
TunnelURL string `json:"tunnel_url,omitempty"`
|
||||
CloudflaredConfigured bool `json:"cloudflared_configured"`
|
||||
SuggestedURL string `json:"suggested_url"`
|
||||
DashboardURL string `json:"dashboard_url"`
|
||||
WebSocketURL string `json:"websocket_url"`
|
||||
}
|
||||
|
||||
// GetServerInfo returns URLs workers and droppers should use to reach this deck.
|
||||
// When the dashboard is opened via HTTPS reverse proxy (e.g. Cloudflare tunnel),
|
||||
// suggested_url uses https and omits :443 — not the local listen port (8989).
|
||||
func GetServerInfo(w http.ResponseWriter, r *http.Request, publicURLOverride string, listenPort int) {
|
||||
// lan_url is always the LAN http endpoint for workers on the same network.
|
||||
func GetServerInfo(w http.ResponseWriter, r *http.Request, publicURLOverride string, listenPort int, cloudflaredConfigured bool) {
|
||||
if listenPort <= 0 {
|
||||
listenPort = 8989
|
||||
}
|
||||
|
||||
localIPs := listLocalIPv4()
|
||||
localIPs := listLocalIPv4Cached()
|
||||
lanURL := lanURLFromIPs(localIPs, listenPort)
|
||||
tunnelURL := tunnelURLFromRequest(r)
|
||||
suggestedURL := resolveSuggestedURL(r, publicURLOverride, listenPort, localIPs)
|
||||
|
||||
host := r.Host
|
||||
@@ -37,17 +52,40 @@ func GetServerInfo(w http.ResponseWriter, r *http.Request, publicURLOverride str
|
||||
}
|
||||
|
||||
info := ServerInfo{
|
||||
Port: port,
|
||||
Host: host,
|
||||
LocalIPs: localIPs,
|
||||
SuggestedURL: suggestedURL,
|
||||
DashboardURL: suggestedURL,
|
||||
WebSocketURL: httpToWS(suggestedURL) + "/ws/agent",
|
||||
Port: port,
|
||||
Host: host,
|
||||
LocalIPs: localIPs,
|
||||
LANURL: lanURL,
|
||||
TunnelURL: tunnelURL,
|
||||
CloudflaredConfigured: cloudflaredConfigured,
|
||||
SuggestedURL: suggestedURL,
|
||||
DashboardURL: suggestedURL,
|
||||
WebSocketURL: httpToWS(suggestedURL) + "/ws/agent",
|
||||
}
|
||||
|
||||
writeJSON(w, info)
|
||||
}
|
||||
|
||||
func lanURLFromIPs(localIPs []string, listenPort int) string {
|
||||
if len(localIPs) == 0 {
|
||||
return ""
|
||||
}
|
||||
return formatBaseURL("http", localIPs[0], listenPort)
|
||||
}
|
||||
|
||||
func tunnelURLFromRequest(r *http.Request) string {
|
||||
scheme := requestScheme(r)
|
||||
if scheme != "https" {
|
||||
return ""
|
||||
}
|
||||
host := requestHost(r)
|
||||
hostOnly, port := hostAndPort(host, scheme)
|
||||
if isLoopbackHost(hostOnly) {
|
||||
return ""
|
||||
}
|
||||
return formatBaseURL(scheme, hostOnly, port)
|
||||
}
|
||||
|
||||
func resolveSuggestedURL(r *http.Request, publicOverride string, listenPort int, localIPs []string) string {
|
||||
if norm := normalizePublicURL(publicOverride); norm != "" {
|
||||
return norm
|
||||
@@ -141,6 +179,21 @@ func httpToWS(base string) string {
|
||||
return "ws://" + strings.TrimPrefix(base, "http://")
|
||||
}
|
||||
|
||||
func listLocalIPv4Cached() []string {
|
||||
cachedLocalIPsMu.Lock()
|
||||
defer cachedLocalIPsMu.Unlock()
|
||||
if cachedLocalIPs != nil && time.Since(cachedLocalIPsAt) < localIPsCacheTTL {
|
||||
out := make([]string, len(cachedLocalIPs))
|
||||
copy(out, cachedLocalIPs)
|
||||
return out
|
||||
}
|
||||
cachedLocalIPs = listLocalIPv4()
|
||||
cachedLocalIPsAt = time.Now()
|
||||
out := make([]string, len(cachedLocalIPs))
|
||||
copy(out, cachedLocalIPs)
|
||||
return out
|
||||
}
|
||||
|
||||
func listLocalIPv4() []string {
|
||||
var ips []string
|
||||
ifaces, err := net.Interfaces()
|
||||
@@ -187,6 +240,9 @@ func parsePort(s string) int {
|
||||
return 8989
|
||||
}
|
||||
n = n*10 + int(ch-'0')
|
||||
if n > 65535 {
|
||||
return 8989
|
||||
}
|
||||
}
|
||||
if n == 0 {
|
||||
return 8989
|
||||
|
||||
Reference in New Issue
Block a user