Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for resuming SFTP file upload/download #864

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from

Conversation

zybexXL
Copy link
Contributor

@zybexXL zybexXL commented Aug 27, 2021

This adds resume capability to SftpClient.UploadFile() , SftpClient.DownloadFile(), as well as to the BeginUploadFile() and BeginDownloadFile() variants.

The API remains unchanged. Resume is triggered simply by changing the current Position of the input/output stream which is given as an argument to these functions:

  • Setting a non-zero position on the input Stream for UploadFile() triggers an Append to the remote file. It's up to the caller to first check the current size of the remote file and set the local position accordingly!
  • Setting a non-zero position on the output Stream for DownloadFile() triggers a resume of the download at the given position.

This also does NOT check if the server supports Resume, though all servers I've tested so far do support it.

@zybexXL
Copy link
Contributor Author

zybexXL commented Nov 1, 2023

I've rebased this PR, please review and consider merging.

Copy link
Collaborator

@WojciechNagorski WojciechNagorski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked this PR and it looks great!

I just want you to provide two integration tests for upload and download.
You can use similar mechanism, like in

public void Common_LossOfNetworkConnectivityDisconnectAndConnect()

bool vmNetworkConnectionDisabled = false;
SshConnectionRestorer disruptor = null;
try
{
    using (var client = new SftpClient(_connectionInfoFactory.Create()))
    {
        client.Connect();
        
        // <-- Start upload/download file

        disruptor = _sshConnectionDisruptor.BreakConnections();
        vmNetworkConnectionDisabled = true;

        WaitForConnectionInterruption(client);
        // disconnect while network connectivity is lost
        client.Disconnect();

        Assert.IsFalse(client.IsConnected);
        
        disruptor.RestoreConnections();
        vmNetworkConnectionDisabled = false;

        // connect when network connectivity is restored
        client.Connect();

        // <-- Resume download/upload file

        client.Dispose();
    }
}
finally
{
    if (vmNetworkConnectionDisabled)
    {
        disruptor.RestoreConnections();
    }
    disruptor?.Dispose();
}

@zybexXL
Copy link
Contributor Author

zybexXL commented Nov 20, 2023

@WojciechNagorski
This type of Resume test won't work as the test file may well finish upload/download before the Disruptor kicks in, especially if the test server is in localhost.
Better to upload a small file, then reconnect and append some more data, then check if the filesize is as expected. The download resume test can download the file in 2 chunks and check if it's correct. OK ?

@WojciechNagorski
Copy link
Collaborator

WojciechNagorski commented Dec 20, 2023

Sorry for delay. It's correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants