-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdetect.go
More file actions
59 lines (51 loc) · 1.95 KB
/
detect.go
File metadata and controls
59 lines (51 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package main
import (
"context"
"fmt"
"net"
"os"
"runtime"
)
// BrowserAvailability holds the result of checking whether a browser can be opened.
type BrowserAvailability struct {
Available bool
Reason string // non-empty when Available is false, for logging/debugging
}
// checkBrowserAvailability determines whether a browser can be opened in the
// current environment. It uses a two-stage check:
//
// 1. Environment signals: SSH sessions without display forwarding, Linux
// hosts with no display server.
// 2. Callback port availability: the local redirect server must be bindable.
//
// This function never attempts to open a browser itself; it only inspects
// the environment. Callers that pass the check should still handle
// openBrowser() failures as a secondary fallback.
func checkBrowserAvailability(ctx context.Context, port int) BrowserAvailability {
// Stage 1a: SSH without X11/Wayland forwarding.
// SSH_TTY / SSH_CLIENT / SSH_CONNECTION indicate a remote shell.
// If a display is also present (X11 forwarding), the browser can still open.
inSSH := os.Getenv("SSH_TTY") != "" ||
os.Getenv("SSH_CLIENT") != "" ||
os.Getenv("SSH_CONNECTION") != ""
hasDisplay := os.Getenv("DISPLAY") != "" || os.Getenv("WAYLAND_DISPLAY") != ""
if inSSH && !hasDisplay {
return BrowserAvailability{false, "SSH session without display forwarding"}
}
// Stage 1b: Linux with no display server at all (headless / Docker / CI).
if runtime.GOOS == "linux" && !hasDisplay {
return BrowserAvailability{false, "no display server (DISPLAY/WAYLAND_DISPLAY not set)"}
}
// Stage 2: Verify the callback port can be bound.
// A busy port means the redirect server cannot start.
lc := &net.ListenConfig{}
ln, err := lc.Listen(ctx, "tcp", fmt.Sprintf("127.0.0.1:%d", port))
if err != nil {
return BrowserAvailability{
false,
fmt.Sprintf("callback port %d unavailable: %v", port, err),
}
}
ln.Close()
return BrowserAvailability{Available: true}
}