PutFile using stream does not upload whole file with S3 object stream

Advertisement

obrynda
Joined:
Posts:
1

PutFile using stream does not upload whole file with S3 object stream

Hey, I am trying to use WinSCP Nuget package version 6.5.3 to upload file to FTP server. I have a file stored in AWS S3 and I wanted to use stream variant of PutFile for upload. Problem is that only 17kB out of 10MB are uploaded. It works fine when I copy S3 stream to memory stream first, or if I use temporary file variant PutFiles. Is there a something I am doing wrong? I would expect S3 stream to be like any other stream - it has no problem writing it to file etc.
Thank you for checking.
Here's minimal example and I am also attaching logs for all variants I tested.
using Amazon.S3;
using Amazon.S3.Model;
using WinSCP;
using Protocol = WinSCP.Protocol;

namespace ConsoleApp1;

class Program
{
    private const string ServerUrl = "updateMe";
    private const string Username = "updateMe";
    private const string Password = "updateMe";
    private const string Destination = "updateMe";

    private const string S3Bucket = "updateMe";
    private const string S3File = "updateMe";

    private static readonly AmazonS3Client AmazonS3Client = new ();

    static void Main()
    {
        // doesn't upload whole file - only 17kb
        UploadUsingS3Stream().Wait();

        // uploads whole file
        UploadUsingMemoryStream().Wait();

        // uploads whole file
        UploadUsingFile().Wait();
    }

    static async Task UploadUsingS3Stream()
    {
        using var session = new Session();
        session.SessionLogPath = "UploadUsingS3Stream.log";

        session.Open(new SessionOptions
        {
            Protocol = Protocol.Ftp,
            HostName = ServerUrl,
            PortNumber = 21,
            FtpMode = FtpMode.Passive,
            UserName = Username,
            Password = Password
        });

        var s3Response = await AmazonS3Client.GetObjectAsync(new GetObjectRequest
        {
            Key = S3File,
            BucketName = S3Bucket
        });

        session.PutFile(
            s3Response.ResponseStream, // using S3 stream directly
            Destination + $"/{Guid.NewGuid()}.txt",
            new TransferOptions
            {
                TransferMode = TransferMode.Binary,
                PreserveTimestamp = false,
                OverwriteMode = OverwriteMode.Overwrite
            });
    }

    static async Task UploadUsingMemoryStream()
    {
        using var session = new Session();
        session.SessionLogPath = "UploadUsingMemoryStream.log";

        session.Open(new SessionOptions
        {
            Protocol = Protocol.Ftp,
            HostName = ServerUrl,
            PortNumber = 21,
            FtpMode = FtpMode.Passive,
            UserName = Username,
            Password = Password
        });

        var s3Response = await AmazonS3Client.GetObjectAsync(new GetObjectRequest
        {
            Key = S3File,
            BucketName = S3Bucket
        });

        // copy to memory stream
        var memoryStream = new MemoryStream();
        await s3Response.ResponseStream.CopyToAsync(memoryStream);
        memoryStream.Position = 0;

        session.PutFile(
            memoryStream, // using stream copied to memory stream
            Destination + $"/{Guid.NewGuid()}.txt",
            new TransferOptions
            {
                TransferMode = TransferMode.Binary,
                PreserveTimestamp = false,
                OverwriteMode = OverwriteMode.Overwrite
            });
    }

    static async Task UploadUsingFile()
    {
        using var session = new Session();
        session.SessionLogPath = "UploadUsingFile.log";

        session.Open(new SessionOptions
        {
            Protocol = Protocol.Ftp,
            HostName = ServerUrl,
            PortNumber = 21,
            FtpMode = FtpMode.Passive,
            UserName = Username,
            Password = Password
        });

        var s3Response = await AmazonS3Client.GetObjectAsync(new GetObjectRequest
        {
            Key = S3File,
            BucketName = S3Bucket
        });

        // copying to temporary file first
        var tempPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
        await using var fileStream = new FileStream(tempPath, FileMode.Create, FileAccess.Write);
        await s3Response.ResponseStream.CopyToAsync(fileStream);

        var result = session.PutFiles(
            tempPath, // using file path
            Destination + $"/{Guid.NewGuid()}.txt",
            false,
            new TransferOptions
            {
                TransferMode = TransferMode.Binary,
                PreserveTimestamp = false,
                OverwriteMode = OverwriteMode.Overwrite
            });

        result.Check();
    }
}
  • logs.zip (7.49 KB, Private file)

Reply with quote

Advertisement

You can post new topics in this forum