Skip to content

Commit e4b4e57

Browse files
committed
fix
1 parent 537fa69 commit e4b4e57

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

models/repo/repo.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -602,25 +602,32 @@ func ComposeHTTPSCloneURL(owner, repo string) string {
602602

603603
func ComposeSSHCloneURL(ownerName, repoName string) string {
604604
sshUser := setting.SSH.User
605-
606-
// if we have a ipv6 literal we need to put brackets around it
607-
// for the git cloning to work.
608605
sshDomain := setting.SSH.Domain
609-
ip := net.ParseIP(setting.SSH.Domain)
610-
if ip != nil && ip.To4() == nil {
611-
sshDomain = "[" + setting.SSH.Domain + "]"
606+
sshPort := setting.SSH.Port
607+
608+
// if the domain already contains a port, just use it (many users already use it this way)
609+
if _, _, err := net.SplitHostPort(sshDomain); err == nil {
610+
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName))
612611
}
613612

614-
if setting.SSH.Port != 22 {
615-
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser,
616-
net.JoinHostPort(setting.SSH.Domain, strconv.Itoa(setting.SSH.Port)),
617-
url.PathEscape(ownerName),
618-
url.PathEscape(repoName))
613+
// non-standard port, it must use full URI
614+
if sshPort != 22 {
615+
if strings.HasPrefix(sshDomain, "[") && strings.HasSuffix(sshDomain, "]") {
616+
sshDomain = sshDomain[1 : len(sshDomain)-1]
617+
}
618+
sshHost := net.JoinHostPort(sshDomain, strconv.Itoa(sshPort))
619+
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName))
620+
}
621+
622+
// for standard port, it can use a shorter URI (without the port)
623+
sshHost := sshDomain
624+
if ip := net.ParseIP(sshHost); ip != nil && ip.To4() == nil && !strings.HasPrefix(sshHost, "[") {
625+
sshHost = "[" + sshHost + "]" // for IPv6 address, wrap it with brackets
619626
}
620627
if setting.Repository.UseCompatSSHURI {
621-
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName))
628+
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName))
622629
}
623-
return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName))
630+
return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName))
624631
}
625632

626633
func (repo *Repository) cloneLink(isUncyclo bool) *CloneLink {

models/repo/repo_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"code.gitea.io/gitea/models/unittest"
1313
user_model "code.gitea.io/gitea/models/user"
1414
"code.gitea.io/gitea/modules/markup"
15+
"code.gitea.io/gitea/modules/setting"
16+
"code.gitea.io/gitea/modules/test"
1517
"code.gitea.io/gitea/modules/util"
1618

1719
"github.com/stretchr/testify/assert"
@@ -186,3 +188,47 @@ func TestGetRepositoryByURL(t *testing.T) {
186188
test(t, "try.gitea.io:user2/repo2.git")
187189
})
188190
}
191+
192+
func TestComposeSSHCloneURL(t *testing.T) {
193+
defer test.MockVariableValue(&setting.SSH, setting.SSH)()
194+
defer test.MockVariableValue(&setting.Repository, setting.Repository)()
195+
196+
setting.SSH.User = "git"
197+
198+
// test SSH_DOMAIN with port
199+
setting.SSH.Domain = "domain:123"
200+
setting.SSH.Port = 22
201+
setting.Repository.UseCompatSSHURI = false
202+
assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
203+
setting.SSH.Domain = "[::1]:123"
204+
setting.SSH.Port = 456
205+
setting.Repository.UseCompatSSHURI = true
206+
assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
207+
208+
// test SSH_DOMAIN without port
209+
setting.SSH.Domain = "domain"
210+
setting.SSH.Port = 22
211+
setting.Repository.UseCompatSSHURI = false
212+
assert.Equal(t, "git@domain:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
213+
setting.Repository.UseCompatSSHURI = true
214+
assert.Equal(t, "ssh://git@domain/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
215+
// test SSH_DOMAIN without port and use non-standard SSH port
216+
setting.SSH.Port = 123
217+
setting.Repository.UseCompatSSHURI = false
218+
assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
219+
setting.Repository.UseCompatSSHURI = true
220+
assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
221+
222+
// test IPv6 SSH_DOMAIN without port
223+
setting.Repository.UseCompatSSHURI = false
224+
setting.SSH.Domain = "[::1]"
225+
setting.SSH.Port = 22
226+
assert.Equal(t, "git@[::1]:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
227+
setting.SSH.Port = 123
228+
assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
229+
setting.SSH.Domain = "::1"
230+
setting.SSH.Port = 22
231+
assert.Equal(t, "git@[::1]:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
232+
setting.SSH.Port = 123
233+
assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))
234+
}

0 commit comments

Comments
 (0)