SFTP在Go中的错误:用户没有适当的读取权限。

huangapple go评论70阅读模式
英文:

SFTP In Go Error: User does not have appropriate read permission

问题

我正在尝试将产品数据源上传到Google Merchant SFTP账户。我可以通过命令提示符手动上传文件,但是当我尝试通过Go语言上传时遇到以下错误。

错误: sftp: "用户没有适当的读取权限" (SSH_FX_PERMISSION_DENIED)

我正在使用github.com/pkg/sftp包,并按照https://godoc.org/github.com/pkg/sftp#Client.Open中的示例进行操作。我怀疑这里的Create/Write模式与命令行中的简单put操作不同。

代码

func (g *GoogleExporter) ExportToSFTP(file []byte) error {

// 创建SSH连接
sshConfig := &ssh.ClientConfig{
	User: g.Creds.AccessData.SFTPUser,
	Auth: []ssh.AuthMethod{
		ssh.Password(g.Creds.AccessData.SFTPPassword),
	},
}

hostPort := fmt.Sprintf("%s:%d", SFTPHostName, SFTPHostPort)
connection, err := ssh.Dial("tcp", hostPort, sshConfig)
if err != nil {
	return err
}

fmt.Println(">> SSH连接已创建!")

// 在SSH上创建SFTP连接
sftp, err := sftp.NewClient(connection)
if err != nil {
	return err
}
defer sftp.Close()

fmt.Println(">> SFTP客户端已创建!")

// 上传文件
remoteFileName := "products.xml" // TODO: 将此名称配置化
remoteFile, err := sftp.Create(remoteFileName)
if err != nil {
	return err
}
fmt.Println(">> SFTP文件已创建!")
if _, err := remoteFile.Write(file); err != nil {
	return err
}

fmt.Println("成功将产品数据源上传到SFTP,文件:%s 用户:%s", remoteFileName, g.Creds.AccessData.SFTPUser)
util.Log("成功将产品数据源上传到SFTP,文件:%s 用户:%s", remoteFileName, g.Creds.AccessData.SFTPUser)

// 确认文件是否存在
if _, err := sftp.Lstat(remoteFileName); err != nil {
	return err
}

return nil
}

错误是由以下代码引起的:

remoteFile, err := sftp.Create(remoteFileName)
英文:

I am trying to upload a product feed to a Google Merchant SFTP account. I am able to upload a file manually through the command prompt but encounter the following error when trying to do it through Go.

Error: sftp: "User does not have appropriate read permission." (SSH_FX_PERMISSION_DENIED)

I am using the github.com/pkg/sftp package, following the example in https://godoc.org/github.com/pkg/sftp#Client.Open. I suspect that the Create/Write pattern here ends up being different from a simple put from command line.

Code

func (g *GoogleExporter) ExportToSFTP(file []byte) error {

// Creating an SSH connection
sshConfig := &ssh.ClientConfig{
	User: g.Creds.AccessData.SFTPUser,
	Auth: []ssh.AuthMethod{
		ssh.Password(g.Creds.AccessData.SFTPPassword),
	},
}

hostPort := fmt.Sprintf("%s:%d", SFTPHostName, SFTPHostPort)
connection, err := ssh.Dial("tcp", hostPort, sshConfig)
if err != nil {
	return err
}

fmt.Println(">> SSH Connection Created!")

// Creating an SFPT connection over SSH
sftp, err := sftp.NewClient(connection)
if err != nil {
	return err
}
defer sftp.Close()

fmt.Println(">> SFTP Client Created!")

// Uploading the file
remoteFileName := "products.xml" // TODO: Make this name configurable
remoteFile, err := sftp.Create(remoteFileName)
if err != nil {
	return err
}
fmt.Println(">> SFTP File Created!")
if _, err := remoteFile.Write(file); err != nil {
	return err
}

fmt.Println("Successfully uploaded product feed to SFTP, file:%s user:%s", remoteFileName, g.Creds.AccessData.SFTPUser)
util.Log("Successfully uploaded product feed to SFTP, file:%s user:%s", remoteFileName, g.Creds.AccessData.SFTPUser)

// Confirming if the file is there
if _, err := sftp.Lstat(remoteFileName); err != nil {
	return err
}

return nil
}

The error is cause by this line:

remoteFile, err := sftp.Create(remoteFileName)

答案1

得分: 5

我正在回答自己的问题,以帮助其他遇到同样问题的人。我找到了一个解决方案。

Google Merchant SFTP 账户只提供写入权限。然而,根据文档,当使用 sftp.Create(..) 函数时,它会以 0666 的标志创建一个文件,这与您的用户设置的权限不符。

为了模拟具有只写权限的 sftp.Create(..) 的行为,您可以使用更通用的 sftp.OpenFile(..) 函数。

remoteFile, err := sftp.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)

标志 os.O_WRONLY|os.O_CREATE|os.O_TRUNC 将模拟 Create() 的行为,即如果文件不存在,则创建文件,并且如果文件存在,则截断文件。

英文:

I am answering my own question to help anyone else that is having this problem. I was able to find a solution.

The Google Merchant SFTP account only gives you write only access. However, according to the docs, when using the sftp.Create(..) function, it creates a file with the flags as 0666, which does not agree with the permissions set on your user.

To mimic the behavior of sftp.Create(..) with write only permissions, you can use the more general sftp.OpenFile(..) function.

remoteFile, err := sftp.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)

The flags os.O_WRONLY|os.O_CREATE|os.O_TRUNC will mimic the behavior of Create() i.e. create a file it doesn't exist and truncate the file if it does.

huangapple
  • 本文由 发表于 2016年12月10日 05:40:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/41069325.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定