summaryrefslogtreecommitdiffstats
path: root/modules/git/submodule.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/git/submodule.go')
-rw-r--r--modules/git/submodule.go88
1 files changed, 62 insertions, 26 deletions
diff --git a/modules/git/submodule.go b/modules/git/submodule.go
index 294df3986a..6fc2e2444f 100644
--- a/modules/git/submodule.go
+++ b/modules/git/submodule.go
@@ -1,10 +1,19 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
// Copyright 2015 The Gogs 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 git
-import "strings"
+import (
+ "fmt"
+ "net"
+ "net/url"
+ "regexp"
+ "strings"
+)
+
+var scpSyntax = regexp.MustCompile(`^([a-zA-Z0-9_]+@)?([a-zA-Z0-9._-]+):(.*)$`)
// SubModule submodule is a reference on git repository
type SubModule struct {
@@ -34,46 +43,73 @@ func getRefURL(refURL, urlPrefix, parentPath string) string {
return ""
}
- url := strings.TrimSuffix(refURL, ".git")
-
- // git://xxx/user/repo
- if strings.HasPrefix(url, "git://") {
- return "http://" + strings.TrimPrefix(url, "git://")
- }
+ refURI := strings.TrimSuffix(refURL, ".git")
- // http[s]://xxx/user/repo
- if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
- return url
+ prefixURL, _ := url.Parse(urlPrefix)
+ urlPrefixHostname, _, err := net.SplitHostPort(prefixURL.Host)
+ if err != nil {
+ urlPrefixHostname = prefixURL.Host
}
// Relative url prefix check (according to git submodule documentation)
- if strings.HasPrefix(url, "./") || strings.HasPrefix(url, "../") {
+ if strings.HasPrefix(refURI, "./") || strings.HasPrefix(refURI, "../") {
// ...construct and return correct submodule url here...
idx := strings.Index(parentPath, "/src/")
if idx == -1 {
- return url
+ return refURI
}
- return strings.TrimSuffix(urlPrefix, "/") + parentPath[:idx] + "/" + url
+ return strings.TrimSuffix(urlPrefix, "/") + parentPath[:idx] + "/" + refURI
}
- // sysuser@xxx:user/repo
- i := strings.Index(url, "@")
- j := strings.LastIndex(url, ":")
+ if !strings.Contains(refURI, "://") {
+ // scp style syntax which contains *no* port number after the : (and is not parsed by net/url)
+ // ex: git@try.gitea.io:go-gitea/gitea
+ match := scpSyntax.FindAllStringSubmatch(refURI, -1)
+ if len(match) > 0 {
- // Only process when i < j because git+ssh://git@git.forwardbias.in/npploader.git
- if i > -1 && j > -1 && i < j {
- // fix problem with reverse proxy works only with local server
- if strings.Contains(urlPrefix, url[i+1:j]) {
- return urlPrefix + url[j+1:]
+ m := match[0]
+ refHostname := m[2]
+ path := m[3]
+
+ if !strings.HasPrefix(path, "/") {
+ path = "/" + path
+ }
+
+ if urlPrefixHostname == refHostname {
+ return prefixURL.Scheme + "://" + urlPrefixHostname + path
+ }
+ return "http://" + refHostname + path
}
- if strings.HasPrefix(url, "ssh://") || strings.HasPrefix(url, "git+ssh://") {
- k := strings.Index(url[j+1:], "/")
- return "http://" + url[i+1:j] + "/" + url[j+1:][k+1:]
+ }
+
+ ref, err := url.Parse(refURI)
+ if err != nil {
+ return ""
+ }
+
+ refHostname, _, err := net.SplitHostPort(ref.Host)
+ if err != nil {
+ refHostname = ref.Host
+ }
+
+ supportedSchemes := []string{"http", "https", "git", "ssh", "git+ssh"}
+
+ for _, scheme := range supportedSchemes {
+ if ref.Scheme == scheme {
+ if urlPrefixHostname == refHostname {
+ return prefixURL.Scheme + "://" + prefixURL.Host + ref.Path
+ } else if ref.Scheme == "http" || ref.Scheme == "https" {
+ if len(ref.User.Username()) > 0 {
+ return ref.Scheme + "://" + fmt.Sprintf("%v", ref.User) + "@" + ref.Host + ref.Path
+ }
+ return ref.Scheme + "://" + ref.Host + ref.Path
+ } else {
+ return "http://" + refHostname + ref.Path
+ }
}
- return "http://" + url[i+1:j] + "/" + url[j+1:]
}
- return url
+ return ""
}
// RefURL guesses and returns reference URL.