Skip to content

Commit aadd787

Browse files
authored
Merge pull request #6034 from thaJeztah/connhelper_cleanups_step2
cli/connhelper/ssh: add NewSpec utility to prevent parsing URL twice
2 parents 8638cef + f105e96 commit aadd787

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

cli/connhelper/connhelper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*ConnectionHelper
4141
return nil, err
4242
}
4343
if u.Scheme == "ssh" {
44-
sp, err := ssh.ParseURL(daemonURL)
44+
sp, err := ssh.NewSpec(u)
4545
if err != nil {
4646
return nil, fmt.Errorf("ssh host connection is not valid: %w", err)
4747
}

cli/connhelper/ssh/ssh.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,26 @@ func ParseURL(daemonURL string) (*Spec, error) {
1717
if errors.As(err, &urlErr) {
1818
err = urlErr.Unwrap()
1919
}
20-
return nil, fmt.Errorf("invalid ssh URL: %w", err)
20+
return nil, fmt.Errorf("invalid SSH URL: %w", err)
2121
}
22-
s, err := newSpec(u)
22+
return NewSpec(u)
23+
}
24+
25+
// NewSpec creates a [Spec] from the given ssh URL's properties. It returns
26+
// an error if the URL is using the wrong scheme, contains fragments,
27+
// query-parameters, or contains a password.
28+
func NewSpec(sshURL *url.URL) (*Spec, error) {
29+
s, err := newSpec(sshURL)
2330
if err != nil {
24-
return nil, fmt.Errorf("invalid ssh URL: %w", err)
31+
return nil, fmt.Errorf("invalid SSH URL: %w", err)
2532
}
2633
return s, nil
2734
}
2835

2936
func newSpec(u *url.URL) (*Spec, error) {
37+
if u == nil {
38+
return nil, errors.New("URL is nil")
39+
}
3040
if u.Scheme == "" {
3141
return nil, errors.New("no scheme provided")
3242
}

cli/connhelper/ssh/ssh_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,41 +87,41 @@ func TestParseURL(t *testing.T) {
8787
{
8888
doc: "malformed URL",
8989
url: "malformed %%url",
90-
expectedError: `invalid ssh URL: invalid URL escape "%%u"`,
90+
expectedError: `invalid SSH URL: invalid URL escape "%%u"`,
9191
},
9292
{
9393
doc: "URL missing scheme",
9494
url: "no-scheme.example.com",
95-
expectedError: "invalid ssh URL: no scheme provided",
95+
expectedError: "invalid SSH URL: no scheme provided",
9696
},
9797
{
9898
doc: "invalid URL with password",
9999
url: "ssh://me:[email protected]",
100-
expectedError: "invalid ssh URL: plain-text password is not supported",
100+
expectedError: "invalid SSH URL: plain-text password is not supported",
101101
},
102102
{
103103
doc: "invalid URL with query parameter",
104104
url: "ssh://example.com?foo=bar&bar=baz",
105-
expectedError: `invalid ssh URL: query parameters are not allowed: "foo=bar&bar=baz"`,
105+
expectedError: `invalid SSH URL: query parameters are not allowed: "foo=bar&bar=baz"`,
106106
},
107107
{
108108
doc: "invalid URL with fragment",
109109
url: "ssh://example.com#bar",
110-
expectedError: `invalid ssh URL: fragments are not allowed: "bar"`,
110+
expectedError: `invalid SSH URL: fragments are not allowed: "bar"`,
111111
},
112112
{
113113
doc: "invalid URL without hostname",
114114
url: "ssh://",
115-
expectedError: "invalid ssh URL: hostname is empty",
115+
expectedError: "invalid SSH URL: hostname is empty",
116116
},
117117
{
118118
url: "ssh:///no-hostname",
119-
expectedError: "invalid ssh URL: hostname is empty",
119+
expectedError: "invalid SSH URL: hostname is empty",
120120
},
121121
{
122122
doc: "invalid URL with unsupported scheme",
123123
url: "https://example.com",
124-
expectedError: `invalid ssh URL: incorrect scheme: https`,
124+
expectedError: `invalid SSH URL: incorrect scheme: https`,
125125
},
126126
}
127127
for _, tc := range testCases {

0 commit comments

Comments
 (0)