3ee26845d9
Some people have very slow SSH round trips and the extra time to attempt a failed git-lfs-transfer operation is bothersome. Let's add an option to allow users to use either the pure SSH protocol or the older hybrid protocol based on the URL in question to let them choose the right value if they know what it should be.
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
package lfsapi
|
|
|
|
import (
|
|
"github.com/git-lfs/git-lfs/v3/config"
|
|
"github.com/git-lfs/git-lfs/v3/creds"
|
|
"github.com/git-lfs/git-lfs/v3/errors"
|
|
"github.com/git-lfs/git-lfs/v3/lfshttp"
|
|
"github.com/git-lfs/git-lfs/v3/ssh"
|
|
"github.com/git-lfs/git-lfs/v3/tr"
|
|
"github.com/rubyist/tracerx"
|
|
)
|
|
|
|
type Client struct {
|
|
Endpoints EndpointFinder
|
|
Credentials creds.CredentialHelper
|
|
|
|
credContext *creds.CredentialHelperContext
|
|
|
|
client *lfshttp.Client
|
|
context lfshttp.Context
|
|
access []creds.AccessMode
|
|
}
|
|
|
|
func NewClient(ctx lfshttp.Context) (*Client, error) {
|
|
if ctx == nil {
|
|
ctx = lfshttp.NewContext(nil, nil, nil)
|
|
}
|
|
|
|
gitEnv := ctx.GitEnv()
|
|
osEnv := ctx.OSEnv()
|
|
|
|
httpClient, err := lfshttp.NewClient(ctx)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, tr.Tr.Get("error creating HTTP client"))
|
|
}
|
|
|
|
c := &Client{
|
|
Endpoints: NewEndpointFinder(ctx),
|
|
client: httpClient,
|
|
context: ctx,
|
|
credContext: creds.NewCredentialHelperContext(gitEnv, osEnv),
|
|
access: creds.AllAccessModes(),
|
|
}
|
|
|
|
return c, nil
|
|
}
|
|
|
|
func (c *Client) Context() lfshttp.Context {
|
|
return c.context
|
|
}
|
|
|
|
// SSHTransfer returns either an suitable transfer object or nil if the
|
|
// server is not using an SSH remote or the git-lfs-transfer style of SSH
|
|
// remote.
|
|
func (c *Client) SSHTransfer(operation, remote string) *ssh.SSHTransfer {
|
|
if len(operation) == 0 {
|
|
return nil
|
|
}
|
|
endpoint := c.Endpoints.Endpoint(operation, remote)
|
|
if len(endpoint.SSHMetadata.UserAndHost) == 0 {
|
|
return nil
|
|
}
|
|
uc := config.NewURLConfig(c.context.GitEnv())
|
|
if val, ok := uc.Get("lfs", endpoint.OriginalUrl, "sshtransfer"); ok && val != "negotiate" && val != "always" {
|
|
tracerx.Printf("skipping pure SSH protocol connection by request")
|
|
return nil
|
|
}
|
|
ctx := c.Context()
|
|
tracerx.Printf("attempting pure SSH protocol connection")
|
|
sshTransfer, err := ssh.NewSSHTransfer(ctx.OSEnv(), ctx.GitEnv(), &endpoint.SSHMetadata, operation)
|
|
if err != nil {
|
|
tracerx.Printf("pure SSH protocol connection failed: %s", err)
|
|
return nil
|
|
}
|
|
return sshTransfer
|
|
}
|