mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-13 08:41:03 +00:00
fix: Fix the panic when ssh remote lfs endpoint parsing failure (#38026)
Fix #38016
This commit is contained in:
+18
-2
@@ -5,9 +5,12 @@ package lfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"gitea.dev/modules/util"
|
||||
)
|
||||
|
||||
// DownloadCallback gets called for every requested LFS object to process its content
|
||||
@@ -23,10 +26,23 @@ type Client interface {
|
||||
Upload(ctx context.Context, objects []Pointer, callback UploadCallback) error
|
||||
}
|
||||
|
||||
// NewClient creates a LFS client
|
||||
func NewClient(endpoint *url.URL, httpTransport *http.Transport) Client {
|
||||
// newClient creates a LFS client
|
||||
func newClient(endpoint *url.URL, httpTransport *http.Transport) Client {
|
||||
if endpoint.Scheme == "file" {
|
||||
return newFilesystemClient(endpoint)
|
||||
}
|
||||
return newHTTPClient(endpoint, httpTransport)
|
||||
}
|
||||
|
||||
// NewClientFromEndpoint creates a LFS client after resolving its endpoint.
|
||||
func NewClientFromEndpoint(cloneurl, lfsurl string, httpTransport *http.Transport) (Client, error) {
|
||||
endpoint := DetermineEndpoint(cloneurl, lfsurl)
|
||||
if endpoint == nil {
|
||||
source := cloneurl
|
||||
if lfsurl != "" {
|
||||
source = lfsurl
|
||||
}
|
||||
return nil, fmt.Errorf("unable to determine LFS endpoint from %q", util.SanitizeCredentialURLs(source))
|
||||
}
|
||||
return newClient(endpoint, httpTransport), nil
|
||||
}
|
||||
|
||||
@@ -12,10 +12,21 @@ import (
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
u, _ := url.Parse("file:///test")
|
||||
c := NewClient(u, nil)
|
||||
c := newClient(u, nil)
|
||||
assert.IsType(t, &FilesystemClient{}, c)
|
||||
|
||||
u, _ = url.Parse("https://test.com/lfs")
|
||||
c = NewClient(u, nil)
|
||||
c = newClient(u, nil)
|
||||
assert.IsType(t, &HTTPClient{}, c)
|
||||
}
|
||||
|
||||
func TestNewClientFromEndpoint(t *testing.T) {
|
||||
client, err := NewClientFromEndpoint("ssh://git@example.com/owner/repo.git", "", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, client)
|
||||
|
||||
client, err = NewClientFromEndpoint("ftp://example.com/owner/repo.git", "", nil)
|
||||
assert.Nil(t, client)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "unable to determine LFS endpoint")
|
||||
}
|
||||
|
||||
+13
-1
@@ -10,6 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
giturl "gitea.dev/modules/git/url"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/modules/util"
|
||||
)
|
||||
@@ -44,15 +45,20 @@ func endpointFromCloneURL(rawurl string) *url.URL {
|
||||
}
|
||||
|
||||
func endpointFromURL(rawurl string) *url.URL {
|
||||
if rawurl == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if strings.HasPrefix(rawurl, "/") {
|
||||
return endpointFromLocalPath(rawurl)
|
||||
}
|
||||
|
||||
u, err := url.Parse(rawurl)
|
||||
gitURL, err := giturl.ParseGitURL(rawurl)
|
||||
if err != nil {
|
||||
log.Error("lfs.endpointFromUrl: %v", err)
|
||||
return nil
|
||||
}
|
||||
u := gitURL.URL
|
||||
|
||||
switch u.Scheme {
|
||||
case "http", "https":
|
||||
@@ -60,6 +66,12 @@ func endpointFromURL(rawurl string) *url.URL {
|
||||
case "git":
|
||||
u.Scheme = "https"
|
||||
return u
|
||||
case "ssh", "git+ssh":
|
||||
u.Scheme = "https" // is it possible http?
|
||||
u.Host = u.Hostname() // remove ssh port if any
|
||||
u.Path = "/" + strings.TrimPrefix(u.Path, "/")
|
||||
u.User = nil
|
||||
return u
|
||||
case "file":
|
||||
return u
|
||||
default:
|
||||
|
||||
@@ -64,6 +64,24 @@ func TestDetermineEndpoint(t *testing.T) {
|
||||
lfsurl: "git://gitlfs.com/repo",
|
||||
expected: str2url("https://gitlfs.com/repo"),
|
||||
},
|
||||
// case 7
|
||||
{
|
||||
cloneurl: "ssh://git@git.com/owner/repo.git",
|
||||
lfsurl: "",
|
||||
expected: str2url("https://git.com/owner/repo.git/info/lfs"),
|
||||
},
|
||||
// case 8
|
||||
{
|
||||
cloneurl: "git@git.com:owner/repo.git",
|
||||
lfsurl: "",
|
||||
expected: str2url("https://git.com/owner/repo.git/info/lfs"),
|
||||
},
|
||||
// case 9
|
||||
{
|
||||
cloneurl: "",
|
||||
lfsurl: "ssh://git@gitlfs.com/owner/repo.git/info/lfs",
|
||||
expected: str2url("https://gitlfs.com/owner/repo.git/info/lfs"),
|
||||
},
|
||||
}
|
||||
|
||||
for n, c := range cases {
|
||||
|
||||
Reference in New Issue
Block a user