diff --git a/Duplicati/Library/Backend/FTP/FTPBackend.cs b/Duplicati/Library/Backend/FTP/FTPBackend.cs index 6c891c040..60a40daaf 100644 --- a/Duplicati/Library/Backend/FTP/FTPBackend.cs +++ b/Duplicati/Library/Backend/FTP/FTPBackend.cs @@ -160,7 +160,7 @@ namespace Duplicati.Library.Backend List lst = new List(); using(System.Net.WebResponse resp = req.GetResponse()) using(System.IO.Stream rs = resp.GetResponseStream()) - using (System.IO.StreamReader sr = new System.IO.StreamReader(rs)) + using(System.IO.StreamReader sr = new System.IO.StreamReader(new StreamReadHelper(rs))) { string line; while ((line = sr.ReadLine()) != null) @@ -349,5 +349,50 @@ namespace Duplicati.Library.Backend } #endregion + + /// + /// Private helper class to fix a bug with the StreamReader + /// + private class StreamReadHelper : Core.OverrideableStream + { + /// + /// Once the stream has returned 0 as the read count it is disposed + /// in the FtpRequest, and subsequent read requests will throw an ObjectDisposedException + /// + private bool m_empty = false; + + /// + /// Basic initialization, just pass the stream to the super class + /// + /// + public StreamReadHelper(System.IO.Stream stream) + : base(stream) + { + } + + /// + /// Override the read function to make sure that we only return less than the requested amount of data if the stream is exhausted + /// + /// The buffer to place data in + /// The offset into the buffer to start at + /// The number of bytes to read + /// The number of bytes read + public override int Read(byte[] buffer, int offset, int count) + { + int readCount = 0; + int a; + + while(!m_empty && count > 0) + { + a = base.Read(buffer, offset, count); + readCount += a; + count -= a; + offset += a; + m_empty = a == 0; + } + + return readCount; + } + } } }