Closed IgnacioGarcia-uala closed 1 year ago
So, there’s the possibility that the channel <- err
blocks, because the time out has happened. In this specific case, I recommend setting a buffer on the channel := make(chan error, 1)
in order that the goroutine can make that send without blocking indefinitely (and thus causing a goroutine leak).
I’m not sure what could be going on here. 🤔 The code doesn’t seem wrong at all. What happens if you try to write it without the timeout
?
The channel with the timeout is there to force the end of the process so it hangs, i tried with files less than 6kb and it was not resolved after 90s. If the code has nothing wrong, is it possible that there is a problem on the server side?
please provide a complate runnable reproducer where we have to change at most the file path and the credentials for the SFTP server instead of a code snippet. Thank you
Here is a sample with client creation, i let commented the "TODO"
package main
import (
"errors"
"fmt"
"os"
"time"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
)
func main() {
err := sendFiles()
fmt.Println(err)
}
func sendFiles() error {
key, err := ssh.ParseRawPrivateKeyWithPassphrase([]byte("TODO certificate"), []byte("TODO pass phrase"))
if err != nil {
return err
}
signer, err := ssh.NewSignerFromKey(key)
if err != nil {
return err
}
auth := []ssh.AuthMethod{ssh.PublicKeys(signer)}
cfg := ssh.ClientConfig{
User: "TODO user",
Auth: auth,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
addr := fmt.Sprintf("%s:%v", "TODO host", "TODO port")
conn, err := ssh.Dial("tcp", addr, &cfg)
if err != nil {
return err
}
client, err := sftp.NewClient(conn)
if err != nil {
return err
}
name := fmt.Sprintf("%s/%s", os.Getenv("VM_DEST_PATH"), "TODO file_name.txt")
destFile, err := client.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
if err != nil {
return err
}
defer destFile.Close()
channel := make(chan error)
go func() {
_, err = destFile.Write([]byte("TODO file content")) // hangs here
channel <- err
}()
select {
case <-time.After(5 * time.Second):
os.Exit(-1) // force close
return errors.New("time out")
case err := <-channel:
return err
}
}
Your example works for me with both OpenSSH and SFTPGo, try checking the server side logs. Is your server something we can easily test ourselves? (without downloading a proprietary sw, installing a trial license, etc.)
Im not the owner of the server and i not have access to logs or configuration, i will contact the owner to have more information
Im not the owner of the server and i not have access to logs or configuration, i will contact the owner to have more information
You could also try to set some client options, for example UseFstat could help with IBM sterling server. Disabling concurrent reads/writes should not make difference but you could try while waiting for the response from the server owner
The server logs show how the file is created and x bytes writted, but apparently that bytes stays in buffer. I have modify the writer to test this and it hang on writer.Flush()
writer := bufio.NewWriter(destFile)
b, err := writer.WriteString(string(content))
if err != nil {
channel <- err
}
log.Printf("bytes: %v", writer.Buffered())
err = writer.Flush() // hangs here
if err != nil {
channel <- err
}
channel <- nil
The client used is https://www.bitvise.com/ssh-server
strange, I installed bitwise server locally on a VM (v9.27) and I have no issues with it, also your example works fine. I have no idea sorry
Update: We had to reject this approach and carry out the solution in another way that does not involve the use of the server. The server owner could not find the fault.
Close Issue
Hi im having a issue while trying to create and write a new file, the file creation is successfully but when i'm trying to write it hangs and dont write anything, when proccess throw timeout error the file stay locked.
The code is:
The file is less than 1mb
Any idea? Thanks