0 votes
by (120 points)

I'm evaluating Rebex File Server to possibly act as a gateway to a bespoke digital asset management system.

It seems that whenever the SFTP client attempts to resume a download the only option from the ReadWriteFileSystemProvider implementation is stream the file again. This isn't ideal as the backend storage does support split downloads.

Is it possible to intercept the resume download request with the appropriate offset, etc?

Thanks

Applies to: Rebex SFTP, File Server

1 Answer

0 votes
by (5.3k points)
edited by

Hello martin-cod,
welcome to the Rebex forum and thanks for the question.
I don't know details about the capabilities of the backend storage, but I think that the following code should do the trick. You can return special stream (instance of your class derived from the .NET Stream, let's call it MyPartialDownloadStream)from the GetContent method. MyPartialDownloadStream will be responsible for the partial download.

protected override NodeContent GetContent(NodeBase node, NodeContentParameters contentParameters)
        {
            //Prepare all required data, use one of the Create*Content methods.

            NodeContent content = NodeContent.CreateReadOnlyContent(new MyPartialDownloadStream(...));
            return content;
        }

Skeleton of the MyPartialDownloadStream.

public class MyPartialDownloadStream : Stream
    {
        private Stream _innerStream;

        public MyPartialDownloadStream()
        {           
        }   

        public override long Seek(long offset, SeekOrigin origin
        {
            //Save position

            _innerStream = ...//or load required data from the underlying storage;
        }

        public override long Position
        {
            get => //calculate and return "real" position;
            set => //Save position / load required data from the underlying storage;
        };  


        public override int Read(byte[] buffer, int offset, int count)
        {
            //Check if we have data / load data from the underlying storage;            
            return _innerStream.Read(byte[] buffer, int offset, int count);
        }

        //Change other Stream methods as required by the solution.
        public override void SetLength(long value)
        {
             _innerStream.SetLength()
        }
        public override void SetLength(long value)
        {
             _innerStream.SetLength()
        }
        public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count);

        public override bool CanRead => _innerStream.CanRead;

        public override bool CanSeek => _innerStream.CanSeek;

        public override bool CanWrite => _innerStream.CanWrite;

        public override long Length => _innerStream.Length;


        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _innerStream?.Dispose();
            }
        }

Hope this helps.

...