bramvdbogaerde / go-scp

Simple Golang scp client
Mozilla Public License 2.0
422 stars 88 forks source link

error "ssh: StdoutPipe after process started" when doing multiple up- and downloads #75

Open svenczbg opened 9 months ago

svenczbg commented 9 months ago

I can successfully use scp.Client.CopyFile() and scp.Client.CopyFromRemote() once.

When I use these functions in a sequence, the 2nd call will return an error "ssh: StdoutPipe after process started".

I'm using the same scp.Client for all calls. This client is based on an existing ssh client:

uhc.SCPClient, err = scp.NewClientBySSH(uhc.SSHClient)

I can successfully open new ssh.sessions before and after the calls to scp.Client.CopyFile() and scp.Client.CopyFromRemote().

I can not see any difference in my code compared to

func TestMultipleUploadsAndDownloads(t *testing.T){}

What I do is:

Create scp Client:

uhc.SCPClient, err = scp.NewClientBySSH(uhc.SSHClient)
err = uhc.SCPClient.Connect()
func (uhc *UpdateHostConnection) Upload(filename string, remotefilename string, perm string) {
    // open local file
    f, err := os.Open(filename)
    insight.CheckErrorExplain(err, "unable to open file", false)
    defer f.Close()

    err = uhc.SCPClient.CopyFile(context.Background(), f, remotefilename, perm)
}
func (uhc *UpdateHostConnection) Download(remotefilename string, filename string) {
    // open local file
    f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0644)
    insight.CheckErrorExplain(err, fmt.Sprintf("unable to create local file %s", filename), false)
    defer f.Close()

    err = uhc.SCPClient.CopyFromRemote(context.Background(), f, remotefilename)
}

I have omitted error handling from the code.

Does anybody have an idea what I might do wrong?

Thanks! Sven

svenczbg commented 9 months ago

I've modified the code such that Upload() and Download() functions open a new scp client and close it when done. This way, it works. However, according to func TestMultipleUploadsAndDownloads(t *testing.T) it should be possible to do multiple Uploads and Downloads with the same scp.client and this would certainly be more efficient then close/reconnect for each file to be up-/downloaded.

I suppose there might be some issue with accessing Stdout of the underlying ssh session but can't find the location in the code that causes this issue.

I hope that somebody here can help.

bramvdbogaerde commented 9 months ago

Thanks for creating this issue. The testing code you are talking about comes from PR #70 which added support for multiple downloads and uploads over the same connection. If I recall correctly the PR proposed to create new SSH sessions (not be confused with connections, sessions are basically new remote scp processes) for each upload/download and will have their own Stdin and Stdout pipes.

I will have do some testing myself to see what is going on and I will try to get back to you soon.