-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Fix some mirror bugs #18649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix some mirror bugs #18649
Changes from all commits
b76846c
3392a1b
c69de15
eb548af
00451ef
da038e4
52b6d13
bac353d
7bc026d
e871985
8e92e5d
d8a7456
ebd54a8
74dfb17
df5d00e
3422e91
64c9244
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright 2022 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package url | ||
|
||
import ( | ||
"fmt" | ||
stdurl "net/url" | ||
"strings" | ||
) | ||
|
||
// ErrWrongURLFormat represents an error with wrong url format | ||
type ErrWrongURLFormat struct { | ||
URL string | ||
} | ||
|
||
func (err ErrWrongURLFormat) Error() string { | ||
return fmt.Sprintf("git URL %s format is wrong", err.URL) | ||
} | ||
|
||
// GitURL represents a git URL | ||
type GitURL struct { | ||
*stdurl.URL | ||
extraMark int // 0 no extra 1 scp 2 file path with no prefix | ||
} | ||
|
||
// String returns the URL's string | ||
func (u *GitURL) String() string { | ||
switch u.extraMark { | ||
case 0: | ||
return u.URL.String() | ||
case 1: | ||
return fmt.Sprintf("%s@%s:%s", u.User.Username(), u.Host, u.Path) | ||
case 2: | ||
return u.Path | ||
default: | ||
return "" | ||
} | ||
} | ||
|
||
// Parse parse all kinds of git URL | ||
func Parse(remote string) (*GitURL, error) { | ||
if strings.Contains(remote, "://") { | ||
u, err := stdurl.Parse(remote) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &GitURL{URL: u}, nil | ||
} else if strings.Contains(remote, "@") && strings.Contains(remote, ":") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The SCP target path parsing is found here: https://github.com/openssh/openssh-portable/blob/16ea8b85838dd7a4dbeba4e51ac4f43fd68b1e5b/misc.c#L767-L834
|
||
url := stdurl.URL{ | ||
Scheme: "ssh", | ||
} | ||
squareBrackets := false | ||
lastIndex := -1 | ||
FOR: | ||
for i := 0; i < len(remote); i++ { | ||
switch remote[i] { | ||
case '@': | ||
url.User = stdurl.User(remote[:i]) | ||
lastIndex = i + 1 | ||
case ':': | ||
if !squareBrackets { | ||
url.Host = strings.ReplaceAll(remote[lastIndex:i], "%25", "%") | ||
if len(remote) <= i+1 { | ||
return nil, ErrWrongURLFormat{URL: remote} | ||
} | ||
url.Path = remote[i+1:] | ||
break FOR | ||
} | ||
case '[': | ||
squareBrackets = true | ||
case ']': | ||
squareBrackets = false | ||
} | ||
} | ||
return &GitURL{ | ||
URL: &url, | ||
extraMark: 1, | ||
}, nil | ||
} | ||
|
||
return &GitURL{ | ||
URL: &stdurl.URL{ | ||
Scheme: "file", | ||
Path: remote, | ||
}, | ||
extraMark: 2, | ||
}, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
// Copyright 2022 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package url | ||
|
||
import ( | ||
"net/url" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestParseGitURLs(t *testing.T) { | ||
kases := []struct { | ||
kase string | ||
expected *GitURL | ||
}{ | ||
{ | ||
kase: "[email protected]:go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "ssh", | ||
User: url.User("git"), | ||
Host: "127.0.0.1", | ||
Path: "go-gitea/gitea.git", | ||
}, | ||
extraMark: 1, | ||
}, | ||
}, | ||
{ | ||
kase: "git@[fe80:14fc:cec5:c174:d88%2510]:go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "ssh", | ||
User: url.User("git"), | ||
Host: "[fe80:14fc:cec5:c174:d88%10]", | ||
Path: "go-gitea/gitea.git", | ||
}, | ||
extraMark: 1, | ||
}, | ||
}, | ||
{ | ||
kase: "git@[::1]:go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "ssh", | ||
User: url.User("git"), | ||
Host: "[::1]", | ||
Path: "go-gitea/gitea.git", | ||
}, | ||
extraMark: 1, | ||
}, | ||
}, | ||
{ | ||
kase: "[email protected]:go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "ssh", | ||
User: url.User("git"), | ||
Host: "github.com", | ||
Path: "go-gitea/gitea.git", | ||
}, | ||
extraMark: 1, | ||
}, | ||
}, | ||
{ | ||
kase: "ssh://[email protected]/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "ssh", | ||
User: url.User("git"), | ||
Host: "github.com", | ||
Path: "/go-gitea/gitea.git", | ||
}, | ||
extraMark: 0, | ||
}, | ||
}, | ||
{ | ||
kase: "ssh://git@[::1]/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "ssh", | ||
User: url.User("git"), | ||
Host: "[::1]", | ||
Path: "/go-gitea/gitea.git", | ||
}, | ||
extraMark: 0, | ||
}, | ||
}, | ||
{ | ||
kase: "/repositories/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "file", | ||
Path: "/repositories/go-gitea/gitea.git", | ||
}, | ||
extraMark: 2, | ||
}, | ||
}, | ||
{ | ||
kase: "file:///repositories/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "file", | ||
Path: "/repositories/go-gitea/gitea.git", | ||
}, | ||
extraMark: 0, | ||
}, | ||
}, | ||
{ | ||
kase: "https://github.com/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "https", | ||
Host: "github.com", | ||
Path: "/go-gitea/gitea.git", | ||
}, | ||
extraMark: 0, | ||
}, | ||
}, | ||
{ | ||
kase: "https://git:[email protected]/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "https", | ||
Host: "github.com", | ||
User: url.UserPassword("git", "git"), | ||
Path: "/go-gitea/gitea.git", | ||
}, | ||
extraMark: 0, | ||
}, | ||
}, | ||
{ | ||
kase: "https://[fe80:14fc:cec5:c174:d88%2510]:20/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "https", | ||
Host: "[fe80:14fc:cec5:c174:d88%10]:20", | ||
Path: "/go-gitea/gitea.git", | ||
}, | ||
extraMark: 0, | ||
}, | ||
}, | ||
|
||
{ | ||
kase: "git://github.com/go-gitea/gitea.git", | ||
expected: &GitURL{ | ||
URL: &url.URL{ | ||
Scheme: "git", | ||
Host: "github.com", | ||
Path: "/go-gitea/gitea.git", | ||
}, | ||
extraMark: 0, | ||
}, | ||
}, | ||
} | ||
|
||
for _, kase := range kases { | ||
t.Run(kase.kase, func(t *testing.T) { | ||
u, err := Parse(kase.kase) | ||
assert.NoError(t, err) | ||
assert.EqualValues(t, kase.expected.extraMark, u.extraMark) | ||
assert.EqualValues(t, *kase.expected, *u) | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ import ( | |
"code.gitea.io/gitea/modules/base" | ||
"code.gitea.io/gitea/modules/emoji" | ||
"code.gitea.io/gitea/modules/git" | ||
giturl "code.gitea.io/gitea/modules/git/url" | ||
"code.gitea.io/gitea/modules/json" | ||
"code.gitea.io/gitea/modules/log" | ||
"code.gitea.io/gitea/modules/markup" | ||
|
@@ -971,20 +972,35 @@ type remoteAddress struct { | |
Password string | ||
} | ||
|
||
func mirrorRemoteAddress(ctx context.Context, m repo_model.RemoteMirrorer) remoteAddress { | ||
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress { | ||
a := remoteAddress{} | ||
if !m.IsMirror { | ||
return a | ||
} | ||
Comment on lines
+977
to
+979
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lunny I saw an issue here, the push mirrors URL are no longer displayed on the UI I think we should return empty remoteAddress when the repo is a mirror not the opposite if m.IsMirror {
return a
} |
||
|
||
remoteURL := m.OriginalURL | ||
if remoteURL == "" { | ||
var err error | ||
remoteURL, err = git.GetRemoteAddress(ctx, m.RepoPath(), remoteName) | ||
if err != nil { | ||
log.Error("GetRemoteURL %v", err) | ||
return a | ||
} | ||
} | ||
|
||
u, err := git.GetRemoteAddress(ctx, m.GetRepository().RepoPath(), m.GetRemoteName()) | ||
u, err := giturl.Parse(remoteURL) | ||
if err != nil { | ||
log.Error("GetRemoteAddress %v", err) | ||
log.Error("giturl.Parse %v", err) | ||
return a | ||
} | ||
|
||
if u.User != nil { | ||
a.Username = u.User.Username() | ||
a.Password, _ = u.User.Password() | ||
if u.Scheme != "ssh" && u.Scheme != "file" { | ||
if u.User != nil { | ||
a.Username = u.User.Username() | ||
a.Password, _ = u.User.Password() | ||
} | ||
u.User = nil | ||
} | ||
u.User = nil | ||
a.Address = u.String() | ||
|
||
return a | ||
|
Uh oh!
There was an error while loading. Please reload this page.