From b7311df34f75353b342974b8714c48a18109a6cd Mon Sep 17 00:00:00 2001 From: Oliver Chen Date: Mon, 11 May 2026 13:46:37 +0800 Subject: [PATCH] fix: centralize ttdy host - ttyd binds to 127.0.0.1 but vhs.go was opening Chrome at http://localhost:. This fails when Chrome choose IPv6 first. - This fix centralizes the ttdy host in `ttyHost`, uses it for both the ttyd --interface and the browser URL, and adds `vhs_test.go` to ensure they stay aligned. --- tty.go | 4 +++- vhs.go | 6 +++++- vhs_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 vhs_test.go diff --git a/tty.go b/tty.go index c8af5dea..6a75263f 100644 --- a/tty.go +++ b/tty.go @@ -16,6 +16,8 @@ import ( "os/exec" ) +const ttyHost = "127.0.0.1" + // randomPort returns a random port number that is not in use. func randomPort() int { addr, _ := net.Listen("tcp", ":0") //nolint:gosec,noctx @@ -27,7 +29,7 @@ func randomPort() int { func buildTtyCmd(port int, shell Shell) *exec.Cmd { args := []string{ //nolint:prealloc fmt.Sprintf("--port=%d", port), - "--interface", "127.0.0.1", + "--interface", ttyHost, "-t", "rendererType=canvas", "-t", "disableResizeOverlay=true", "-t", "enableSixel=true", diff --git a/vhs.go b/vhs.go index 235e7b42..bb226b83 100644 --- a/vhs.go +++ b/vhs.go @@ -143,7 +143,7 @@ func (vhs *VHS) Start() error { return fmt.Errorf("could not launch browser: %w", err) } browser := rod.New().ControlURL(u).MustConnect() - page, err := browser.Page(proto.TargetCreateTarget{URL: fmt.Sprintf("http://localhost:%d", port)}) + page, err := browser.Page(proto.TargetCreateTarget{URL: ttyURL(port)}) if err != nil { return fmt.Errorf("could not open ttyd: %w", err) } @@ -155,6 +155,10 @@ func (vhs *VHS) Start() error { return nil } +func ttyURL(port int) string { + return fmt.Sprintf("http://%s:%d", ttyHost, port) +} + // Setup sets up the VHS instance and performs the necessary actions to reflect // the options that are default and set by the user. func (vhs *VHS) Setup() { diff --git a/vhs_test.go b/vhs_test.go new file mode 100644 index 00000000..6405415c --- /dev/null +++ b/vhs_test.go @@ -0,0 +1,25 @@ +package main + +import "testing" + +func TestTtyHostMatchesBrowserURL(t *testing.T) { + const port = 19760 + + cmd := buildTtyCmd(port, Shell{Command: []string{"sh"}}) + iface := "" + for i, arg := range cmd.Args { + if arg == "--interface" && i+1 < len(cmd.Args) { + iface = cmd.Args[i+1] + break + } + } + + if iface != ttyHost { + t.Fatalf("expected ttyd to bind to %q, got %q", ttyHost, iface) + } + + wantURL := "http://" + iface + ":19760" + if gotURL := ttyURL(port); gotURL != wantURL { + t.Fatalf("expected browser URL %q, got %q", wantURL, gotURL) + } +}