diff --git a/control/controlhttp/client_js.go b/control/controlhttp/client_js.go index b59980d83..55cee81de 100644 --- a/control/controlhttp/client_js.go +++ b/control/controlhttp/client_js.go @@ -16,7 +16,7 @@ import ( "tailscale.com/types/key" ) -// Variant of Dial that tunnels the request over WebScokets, since we cannot do +// Variant of Dial that tunnels the request over WebSockets, since we cannot do // bi-directional communication over an HTTP connection when in JS. func Dial(ctx context.Context, addr string, machineKey key.MachinePrivate, controlKey key.MachinePublic, protocolVersion uint16, dialer dnscache.DialContextFunc) (*controlbase.Conn, error) { init, cont, err := controlbase.ClientDeferred(machineKey, controlKey, protocolVersion) @@ -24,13 +24,19 @@ func Dial(ctx context.Context, addr string, machineKey key.MachinePrivate, contr return nil, err } - host, addr, err := net.SplitHostPort(addr) + host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err } + wsScheme := "wss" + wsHost := host + if host == "localhost" { + wsScheme = "ws" + wsHost = addr + } wsURL := &url.URL{ - Scheme: "ws", - Host: net.JoinHostPort(host, addr), + Scheme: wsScheme, + Host: wsHost, Path: serverUpgradePath, // Can't set HTTP headers on the websocket request, so we have to to send // the handshake via an HTTP header.