diff --git a/cli/internal/client/sshurl.go b/cli/internal/client/sshurl.go index 5ec933ef..d111134a 100644 --- a/cli/internal/client/sshurl.go +++ b/cli/internal/client/sshurl.go @@ -100,6 +100,9 @@ func (sp *SshParams) URL() *url.URL { if sp.CliPath != "" { q.Set("cliPath", sp.CliPath) } + if sp.ConfigPath != "" { + q.Set("configPath", sp.ConfigPath) + } for k, v := range sp.Options { q.Set(fmt.Sprintf("option[%s]", k), v) } diff --git a/cli/internal/client/sshurl_test.go b/cli/internal/client/sshurl_test.go index 20c8749b..58f7b29d 100644 --- a/cli/internal/client/sshurl_test.go +++ b/cli/internal/client/sshurl_test.go @@ -192,6 +192,13 @@ func TestSshParams_URL_WithCliPath(t *testing.T) { assert.Contains(t, u.RawQuery, "cliPath") } +func TestSshParams_URL_WithConfigPath(t *testing.T) { + sp := SshParams{Host: "myhost", ConfigPath: "/home/user/.ssh/config"} + u := sp.URL() + assert.Contains(t, u.RawQuery, "configPath") + assert.Equal(t, "/home/user/.ssh/config", u.Query().Get("configPath")) +} + func TestSshParams_URL_WithOptions(t *testing.T) { sp := SshParams{ Host: "myhost", @@ -202,7 +209,7 @@ func TestSshParams_URL_WithOptions(t *testing.T) { } func TestSshParams_String_RoundTrip(t *testing.T) { - original := "ssh://alice@myhost:2222/path/to/socket?cliPath=%2Fusr%2Fbin%2Ftyger&option%5BFoo%5D=bar" + original := "ssh://alice@myhost:2222/path/to/socket?cliPath=%2Fusr%2Fbin%2Ftyger&configPath=%2Fhome%2Fuser%2F.ssh%2Fconfig&option%5BFoo%5D=bar" u, err := url.Parse(original) require.NoError(t, err) @@ -220,6 +227,7 @@ func TestSshParams_String_RoundTrip(t *testing.T) { assert.Equal(t, u.Path, u2.Path) assert.Equal(t, u.User.Username(), u2.User.Username()) assert.Equal(t, u.Query().Get("cliPath"), u2.Query().Get("cliPath")) + assert.Equal(t, u.Query().Get("configPath"), u2.Query().Get("configPath")) assert.Equal(t, u.Query().Get("option[Foo]"), u2.Query().Get("option[Foo]")) } @@ -465,16 +473,6 @@ func TestFormatCmdLine_StructureOrder(t *testing.T) { assert.Equal(t, "arg2", remoteCmd[3]) } -func TestParseSshUrl_ConfigPathNotInURL(t *testing.T) { - // configPath is consumed during parsing and should not appear in URL output - sp := SshParams{ - Host: "myhost", - ConfigPath: "/home/user/.ssh/config", - } - u := sp.URL() - assert.NotContains(t, u.RawQuery, "configPath") -} - func TestSshParams_URL_NoQueryWhenEmpty(t *testing.T) { sp := SshParams{Host: "myhost", SocketPath: "/path"} u := sp.URL() diff --git a/cli/internal/tygerproxy/tygerproxy_test.go b/cli/internal/tygerproxy/tygerproxy_test.go index 7e535507..bfc0a8bb 100644 --- a/cli/internal/tygerproxy/tygerproxy_test.go +++ b/cli/internal/tygerproxy/tygerproxy_test.go @@ -20,6 +20,10 @@ func TestUrlsEquivalent(t *testing.T) { "ssh://user@myhost/opt/tyger/api.sock?option[StrictHostKeyChecking]=no&option[UserKnownHostsFile]=NUL", "ssh://user@myhost/opt/tyger/api.sock?option%5BStrictHostKeyChecking%5D=no&option%5BUserKnownHostsFile%5D=NUL", true}, + {"order of query parameters doesn't matter", + "ssh://user@myhost/opt/tyger/api.sock?option[StrictHostKeyChecking]=no&option[UserKnownHostsFile]=NUL", + "ssh://user@myhost/opt/tyger/api.sock?option[UserKnownHostsFile]=NUL&option[StrictHostKeyChecking]=no", + true}, {"escaped vs unescaped brackets reversed", "ssh://user@myhost/opt/tyger/api.sock?option%5BStrictHostKeyChecking%5D=no&option%5BUserKnownHostsFile%5D=NUL", "ssh://user@myhost/opt/tyger/api.sock?option[StrictHostKeyChecking]=no&option[UserKnownHostsFile]=NUL",