0 votes
by (160 points)

Hi,

I've created a C# .NET SFTP library that is essentially a wrapper for Rebex SFTP v.5.0.784 with some added functionality that I need.

I have a method called ConnectAndLogin() that essentially checks if the current instance of the SFTPClient is connected and authenticated, and if either is false, will connect and login, then return the status. This was meant as a "safe" way to keep trying to reconnect throughout a long process, without causing tons of new connections:

    public bool ConnectAndLogin() {
        if (!Client.IsConnected)
            Client.Connect(_hostName);
        if (!Client.IsAuthenticated)
            Client.Login(_userName, _password);

        return Client.IsAuthenticated && Client.IsConnected;
    }

I have an external app using my SFTP library, and in a specific section I'm passing in a list of objects that contain a source path and destination path. I'm looping through that list of objects to rename/archive each of the files if they exist (FileExists is just calling the built-in Rebex FileExists):

foreach (var info in archiveFileSetInfo) {
try {
    sftpClient.ConnectAndLogin();
    var fileExists = sftpClient.FileExists(info.SourcePath);
    filesExist.Add(fileExists);

    if (fileExists) {
        ArchiveFileWithRetries(info, sftpClient, batchID, ctx);
    }
}
catch (Exception e) {
    errors.Add(new ArchiveFileException(e.GetMessageAndInnerMessage()));
}}

Before getting to the foreach loop, the sftpClient may have been idle for some time, depending on the size of the files that were processed previously. The problem I'm having is that in the situations where the sftpClient was idle, it may have been disconnected by the server. In that scenario, on the first iteration, when I call ConnectAndLogin, both IsConnected and IsAuthenticated are true, so my code does not attempt to reconnect/reauth. Then, when i call FileExists(), an Exception is thrown because the client is disconnected. Something about that causes the connected/authenticated flags to update and now show as False, so on the next iteration, it connects as expected and everything works. So, if I pass a list of 5 paths to archive, the first one is always failing, and then the next 4 succeed.

Am I missing something about how those flags should work? Is there possibly a bug with their implementation? Or does anyone see anything wrong with what I'm doing?

Appreciate the help!

Applies to: Rebex SFTP

1 Answer

+1 vote
by (145k points)
selected by
 
Best answer

Hi,

The value returned by the IsConnected property indicates whether the session was connected at the time of the last operation, which makes it unsuitable for detecting whether the session is actually usable.

Possible solutions:
a) Don't actually leave idle SFTP sessions open indefinitely. If that happens, close the session, and only open it again when needed.
b) Before attempting further operations on a session that has been idle, try a dummy operation such as FileExists("anything") put into into a try/catch(SftpException) block. If the exception is raised, and its Status property is SftpExceptionStatus.ConnectionClosed or SftpExceptionStatus.Timeout , dispose the session and connect/login again.
c) Put your existing FileExists call into try/catch block and dispose/connect/login if ConnectionClosed or Timeout is detected.

...