Przeglądaj źródła

Revert "Attempt to run tests against .NET 3.5 and 4.0."

This reverts commit b6ee090ba5e52f1a65cda0fd94c1b1f6459ed99b, reversing
changes made to 0baac6aebde6b1727a183225f84f3c7f5f5a908b.
Gert Driesen 8 lat temu
rodzic
commit
b63a0ea524

+ 3 - 13
src/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,33 +12,29 @@
     <AssemblyName>Renci.SshNet</AssemblyName>
     <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_SOCKET_SELECT;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
     <DocumentationFile>bin\Debug\Renci.SshNet.xml</DocumentationFile>
-    <LangVersion>5</LangVersion>
-    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
     <Optimize>true</Optimize>
     <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_SOCKET_SELECT;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
+    <DefineConstants>TRACE;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
     <NoWarn>
     </NoWarn>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup>
     <SignAssembly>true</SignAssembly>
@@ -865,9 +861,6 @@
     <Compile Include="..\Renci.SshNet\Sftp\SftpFileAttributes.cs">
       <Link>Sftp\SftpFileAttributes.cs</Link>
     </Compile>
-    <Compile Include="..\Renci.SshNet\Sftp\SftpFileReader.cs">
-      <Link>Sftp\SftpFileReader.cs</Link>
-    </Compile>
     <Compile Include="..\Renci.SshNet\Sftp\SftpFileStream.cs">
       <Link>Sftp\SftpFileStream.cs</Link>
     </Compile>
@@ -883,9 +876,6 @@
     <Compile Include="..\Renci.SshNet\Sftp\SftpMessageTypes.cs">
       <Link>Sftp\SftpMessageTypes.cs</Link>
     </Compile>
-    <Compile Include="..\Renci.SshNet\Sftp\SftpReadAsyncResult.cs">
-      <Link>Sftp\SftpReadAsyncResult.cs</Link>
-    </Compile>
     <Compile Include="..\Renci.SshNet\Sftp\SftpSession.cs">
       <Link>Sftp\SftpSession.cs</Link>
     </Compile>

+ 2 - 2
src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -42,8 +42,8 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
-    <Reference Include="Moq, Version=4.2.1409.1722, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\..\Users\Gert Driesen\Dropbox\Privé\Projects\SShNetTests\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
+    <Reference Include="Moq">
+      <HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core">

+ 3 - 27
src/Renci.SshNet/Common/AsyncResult.cs

@@ -29,12 +29,10 @@ namespace Renci.SshNet.Common
         private Exception _exception;
 
         /// <summary>
-        /// Gets or sets a value indicating whether <see cref="EndInvoke()"/> has been called on the current
-        /// <see cref="AsyncResult"/>.
+        /// Gets or sets a value indicating whether EndInvoke has been called on the current AsyncResult.
         /// </summary>
         /// <value>
-        /// <c>true</c> if <see cref="EndInvoke()"/> has been called on the current <see cref="AsyncResult"/>;
-        /// otherwise, <c>false</c>.
+        /// <c>true</c> if <see cref="EndInvoke()"/> has been called on the current <see cref="AsyncResult"/>; otherwise, <c>false</c>.
         /// </value>
         public bool EndInvokeCalled { get; private set; }
 
@@ -77,7 +75,7 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Waits until the asynchronous operation completes, and then returns. 
         /// </summary>
-        internal void EndInvoke()
+        public void EndInvoke()
         {
             // This method assumes that only 1 thread calls EndInvoke for this object
             if (!IsCompleted)
@@ -95,28 +93,6 @@ namespace Renci.SshNet.Common
                 throw _exception;
         }
 
-        /// <summary>
-        /// Waits until the asynchronous operation completes, and then returns. 
-        /// </summary>
-        internal void EndInvoke(TimeSpan timeout)
-        {
-            // This method assumes that only 1 thread calls EndInvoke for this object
-            if (!IsCompleted)
-            {
-                // If the operation isn't done, wait for it
-                var completed = AsyncWaitHandle.WaitOne(timeout);
-                _asyncWaitHandle = null;  // Allow early GC
-                AsyncWaitHandle.Dispose();
-
-            }
-
-            EndInvokeCalled = true;
-
-            // Operation is done: if an exception occurred, throw it
-            if (_exception != null)
-                throw _exception;
-        }
-
         #region Implementation of IAsyncResult
 
         /// <summary>

+ 1 - 0
src/Renci.SshNet/Common/SemaphoreLight.cs

@@ -64,6 +64,7 @@ namespace Renci.SshNet.Common
         /// </summary>
         public void Wait()
         {
+
             lock (_lock)
             {
                 while (_currentCount < 1)

+ 2 - 5
src/Renci.SshNet/Renci.SshNet.csproj

@@ -18,7 +18,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <DocumentationFile>bin\Debug\Renci.SshNet.xml</DocumentationFile>
@@ -29,14 +29,13 @@
     <DebugType>none</DebugType>
     <Optimize>true</Optimize>
     <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
+    <DefineConstants>FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
     <NoWarn>
     </NoWarn>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <LangVersion>5</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
     <SignAssembly>true</SignAssembly>
@@ -417,7 +416,6 @@
     <Compile Include="Sftp\SftpDownloadAsyncResult.cs" />
     <Compile Include="Sftp\SftpFile.cs" />
     <Compile Include="Sftp\SftpFileAttributes.cs" />
-    <Compile Include="Sftp\SftpFileReader.cs" />
     <Compile Include="Sftp\SftpFileStream.cs" />
     <Compile Include="Sftp\SftpFileSystemInformation.cs">
       <SubType>Code</SubType>
@@ -427,7 +425,6 @@
     <Compile Include="Sftp\SftpMessageTypes.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="Sftp\SftpReadAsyncResult.cs" />
     <Compile Include="Sftp\SftpSession.cs">
       <SubType>Code</SubType>
     </Compile>

+ 6 - 22
src/Renci.SshNet/Session.cs

@@ -1815,16 +1815,14 @@ namespace Renci.SshNet
         /// </summary>
         private void MessageListener()
         {
-#if FEATURE_SOCKET_SELECT
-            var readSockets = new List<Socket> { _socket };
-#endif // FEATURE_SOCKET_SELECT
-
             try
             {
+                var readSockets = new List<Socket> {_socket};
+
                 // remain in message loop until socket is shut down or until we're disconnecting
                 while (_socket.IsConnected())
                 {
-#if FEATURE_SOCKET_SELECT
+#if FEATURE_SOCKET_POLL
                     // if the socket is already disposed when Select is invoked, then a SocketException
                     // stating "An operation was attempted on something that is not a socket" is thrown;
                     // we attempt to avoid this exception by having an IsConnected() that can break the
@@ -1837,8 +1835,7 @@ namespace Renci.SshNet
 
                     // perform a blocking select to determine whether there's is data available to be
                     // read; we do not use a blocking read to allow us to use Socket.Poll to determine
-                    // if the connection is still available (in IsSocketConnected)
-
+                    // if the connection is still available (in IsSocketConnected
                     Socket.Select(readSockets, null, null, -1);
 
                     // the Select invocation will be interrupted in one of the following conditions:
@@ -1858,19 +1855,7 @@ namespace Renci.SshNet
                         // break out of the message loop
                         break;
                     }
-#elif FEATURE_SOCKET_POLL
-                    // when Socket.Select(IList, IList, IList, Int32) is not available or is buggy, we use
-                    // Socket.Poll(Int, SelectMode) to block until either data is available or the socket
-                    // is closed
-
-                    var status = _socket.Poll(-1, SelectMode.SelectRead);
-                    if (!_socket.IsConnected())
-                    {
-                        // connection with SSH server was closed;
-                        // break out of the message loop
-                        break;
-                    }
-#endif // FEATURE_SOCKET_SELECT
+#endif // FEATURE_SOCKET_POLL
 
                     var message = ReceiveMessage();
                     if (message == null)
@@ -1884,7 +1869,7 @@ namespace Renci.SshNet
                     message.Process(this);
                 }
 
-                // connection with SSH server was closed or socket was disposed
+                // connection with SSH server was closed
                 RaiseError(CreateConnectionAbortedByServerException());
             }
             catch (SocketException ex)
@@ -2216,7 +2201,6 @@ namespace Renci.SshNet
                     return;
             }
 
-            // "save" exception and set exception wait handle to ensure any waits are interrupted
             _exception = exp;
             _exceptionWaitHandle.Set();
 

+ 0 - 13
src/Renci.SshNet/Sftp/ISftpSession.cs

@@ -2,20 +2,11 @@
 using System.Collections.Generic;
 using System.Threading;
 using Renci.SshNet.Sftp.Responses;
-using Renci.SshNet.Channels;
 
 namespace Renci.SshNet.Sftp
 {
     internal interface ISftpSession : ISubsystemSession
     {
-        /// <summary>
-        /// Gets the channel associated with this session.
-        /// </summary>
-        /// <value>
-        /// The channel associated with this session.
-        /// </value>
-        IChannelSession Channel { get; }
-
         /// <summary>
         /// Gets the SFTP protocol version.
         /// </summary>
@@ -104,10 +95,6 @@ namespace Renci.SshNet.Sftp
         /// <returns>data array; null if EOF</returns>
         byte[] RequestRead(byte[] handle, ulong offset, uint length);
 
-        SftpReadAsyncResult BeginRead(byte[] handle, ulong offset, uint length, AsyncCallback callback, object state);
-
-        byte[] EndRead(IAsyncResult asyncResult);
-
         /// <summary>
         /// Performs SSH_FXP_READDIR request
         /// </summary>

+ 0 - 229
src/Renci.SshNet/Sftp/SftpFileReader.cs

@@ -1,229 +0,0 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Common;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Renci.SshNet.Sftp
-{
-    internal class SftpFileReader
-    {
-        private const int MaxReadAhead = 10;
-
-        private readonly byte[] _handle;
-        private readonly ISftpSession _sftpSession;
-        private SemaphoreLight _semaphore;
-        private bool _isCompleted;
-        private uint _chunkLength;
-        private int _readAheadChunkIndex;
-        private int _nextChunkIndex;
-        private ulong _readAheadOffset;
-        private ulong _offset;
-        private ulong _fileSize;
-        private readonly IDictionary<int, BufferedRead> _queue;
-        private readonly object _readLock;
-
-        public SftpFileReader(byte[] handle, ISftpSession sftpSession)
-        {
-            _handle = handle;
-            _sftpSession = sftpSession;
-            _chunkLength = 16 * 1024; // TODO !
-            _semaphore = new SemaphoreLight(MaxReadAhead);
-            _queue = new Dictionary<int, BufferedRead>(MaxReadAhead);
-            _readLock = new object();
-
-            _fileSize = (ulong)_sftpSession.RequestFStat(_handle).Size;
-
-            ThreadAbstraction.ExecuteThread(() =>
-            {
-                while (!_isCompleted)
-                {
-                    if (_readAheadOffset >= _fileSize)
-                        break;
-
-                    // TODO implement cancellation!?
-                    _semaphore.Wait();
-
-                    // start reading next chunk
-                    _sftpSession.BeginRead(_handle, _readAheadOffset, _chunkLength, ReadCompleted,
-                                           new BufferedRead(_readAheadChunkIndex, _readAheadOffset));
-
-                    // advance read-ahead offset
-                    _readAheadOffset += _chunkLength;
-
-                    _readAheadChunkIndex++;
-                }
-            });
-        }
-
-        public byte[] Read()
-        {
-            lock (_readLock)
-            {
-                BufferedRead nextChunk;
-
-                while (!_queue.TryGetValue(_nextChunkIndex, out nextChunk) && !_isCompleted)
-                    Monitor.Wait(_readLock);
-
-                if (_isCompleted)
-                    return new byte[0];
-
-                if (nextChunk.Offset == _offset)
-                {
-                    var data = nextChunk.Data;
-                    _offset += (ulong) data.Length;
-
-                    // remove processed chunk
-                    _queue.Remove(_nextChunkIndex);
-                    // move to next chunk
-                    _nextChunkIndex++;
-                    // allow read ahead of a new chunk
-                    _semaphore.Release();
-                    return data;
-                }
-
-                // when the server returned less bytes than requested (for the previous chunk)
-                // we'll synchronously request the remaining data
-
-                var catchUp = new byte[nextChunk.Offset - _offset];
-                var bytesCaughtUp = 0L;
-
-                while (bytesCaughtUp < catchUp.Length)
-                {
-                    // TODO: break loop and interrupt blocking wait in case of exception
-                    var read = _sftpSession.RequestRead(_handle, _offset, (uint) catchUp.Length);
-                    if (read.Length == 0)
-                    {
-                        // break in loop in "read-ahead" thread (once a blocking wait is interrupted)
-                        _isCompleted = true;
-                        // interrupt blocking wait in "read-ahead" thread
-                        lock (_readLock)
-                            Monitor.PulseAll(_readLock);
-                        // signal failure
-                        throw new SshException("Unexpectedly reached end of file.");
-                    }
-
-                    bytesCaughtUp += read.Length;
-                    _offset += (ulong) bytesCaughtUp;
-                }
-
-                return catchUp;
-            }
-        }
-
-        private void ReadCompleted(IAsyncResult result)
-        {
-            var readAsyncResult = result as SftpReadAsyncResult;
-            if (readAsyncResult == null)
-                return;
-
-            var data = readAsyncResult.EndInvoke();
-            if (data.Length == 0)
-            {
-                _isCompleted = true;
-            }
-            else
-            {
-                var bufferedRead = (BufferedRead)readAsyncResult.AsyncState;
-                bufferedRead.Complete(data);
-                _queue.Add(bufferedRead.ChunkIndex, bufferedRead);
-            }
-
-            // signal that a chunk has been read or EOF has been reached;
-            // in both cases, we want to unblock the "read-ahead" thread
-            lock (_readLock)
-            {
-                Monitor.Pulse(_readLock);
-            }
-        }
-    }
-
-    //private class BufferedReadState
-    //{
-    //    private BlockingQueue<BufferedRead> _queue;
-    //    private long _offset;
-
-    //    public BufferedReadState(long offset, SemaphoreLight semaphore, BlockingQueue<BufferedRead> queue)
-    //    {
-    //        _queue = queue;
-    //        _offset = offset;
-    //        _semaphore = semaphore;
-    //    }
-
-    //    public long Offset
-    //    {
-    //        get { return _offset; }
-    //    }
-
-    //    public BlockingQueue<BufferedRead> Queue
-    //    {
-    //        get { return _queue; }
-    //    }
-
-    //    public SemaphoreLight Semaphore
-    //    {
-    //        get { return _semaphore; }
-    //    }
-    //}
-
-    //private class BlockingQueue<T>
-    //{
-    //    private readonly object _lock = new object();
-    //    private Queue<T> _queue;
-    //    private bool _isClosed;
-
-    //    public BlockingQueue(int capacity)
-    //    {
-    //        _queue = new Queue<T>(capacity);
-    //    }
-
-    //    public T Dequeue()
-    //    {
-    //        lock (_lock)
-    //        {
-    //            while (!_isClosed && _queue.Count == 0)
-    //                Monitor.Wait(_lock);
-
-    //            if (_queue.Count == 0)
-    //                return default(T);
-
-    //            return _queue.Dequeue();
-    //        }
-    //    }
-
-    //    public void Enqueue(T item)
-    //    {
-    //        lock (_lock)
-    //        {
-    //            _queue.Enqueue(item);
-    //            Monitor.PulseAll(_lock);
-    //        }
-    //    }
-
-    //    public void Close()
-    //    {
-    //        _isClosed = true;
-    //        Monitor.PulseAll(_lock);
-    //    }
-    //}
-
-    internal class BufferedRead
-    {
-        public int ChunkIndex { get; private set; }
-
-        public byte[] Data { get; private set; }
-
-        public ulong Offset { get; private set; }
-
-        public BufferedRead(int chunkIndex, ulong offset)
-        {
-            ChunkIndex = chunkIndex;
-            Offset = offset;
-        }
-
-        public void Complete(byte[] data)
-        {
-            Data = data;
-        }
-    }
-}

+ 0 - 12
src/Renci.SshNet/Sftp/SftpReadAsyncResult.cs

@@ -1,12 +0,0 @@
-using Renci.SshNet.Common;
-using System;
-
-namespace Renci.SshNet.Sftp
-{
-    internal class SftpReadAsyncResult : AsyncResult<byte[]>
-    {
-        public SftpReadAsyncResult(AsyncCallback asyncCallback, object state) : base(asyncCallback, state)
-        {
-        }
-    }
-}

+ 0 - 46
src/Renci.SshNet/Sftp/SftpSession.cs

@@ -169,8 +169,6 @@ namespace Renci.SshNet.Sftp
             var offset = 0;
             var count = data.Length;
 
-            //Console.WriteLine("Data received: " + count);
-
             // improve performance and reduce GC pressure by not buffering channel data if the received
             // chunk contains the complete packet data.
             //
@@ -186,8 +184,6 @@ namespace Renci.SshNet.Sftp
 
                     var packetTotalLength = packetDataLength + packetLengthByteCount;
 
-                    //Console.WriteLine("Current: " + data.Length + " | Total: " + packetTotalLength);
-
                     // check if complete packet data (or more) is available
                     if (count >= packetTotalLength)
                     {
@@ -245,8 +241,6 @@ namespace Renci.SshNet.Sftp
 
                 var packetTotalLength = packetDataLength + packetLengthByteCount;
 
-                //Console.WriteLine("Current: " + data.Length + " | Total: " + packetTotalLength);
-
                 // check if complete packet data is available
                 if (_data.Count < packetTotalLength)
                 {
@@ -403,46 +397,6 @@ namespace Renci.SshNet.Sftp
             }
         }
 
-        public SftpReadAsyncResult BeginRead(byte[] handle, ulong offset, uint length, AsyncCallback callback, object state)
-        {
-            var asyncResult = new SftpReadAsyncResult(callback, state);
-
-            var request = new SftpReadRequest(ProtocolVersion, NextRequestId, handle, offset, length,
-                response =>
-                {
-                    asyncResult.SetAsCompleted(response.Data, false);
-                },
-                response =>
-                {
-                    if (response.StatusCode != StatusCodes.Eof)
-                    {
-                        asyncResult.SetAsCompleted(GetSftpException(response), false);
-                    }
-                    else
-                    {
-                        asyncResult.SetAsCompleted(Array<byte>.Empty, false);
-                    }
-                });
-            SendRequest(request);
-
-            return asyncResult;
-        }
-
-        public byte[] EndRead(IAsyncResult asyncResult)
-        {
-            if (asyncResult == null)
-                throw new ArgumentNullException("asyncResult");
-
-            var sftpReadAsyncResult = asyncResult as SftpReadAsyncResult;
-            if (sftpReadAsyncResult == null)
-                throw new ArgumentException("IDIOT", "asyncResult");
-
-            if (sftpReadAsyncResult.EndInvokeCalled)
-                throw new InvalidOperationException("EndRead has already been called.");
-
-            return sftpReadAsyncResult.EndInvoke();
-        }
-
         /// <summary>
         /// Performs SSH_FXP_READ request.
         /// </summary>

+ 19 - 99
src/Renci.SshNet/SftpClient.cs

@@ -1996,120 +1996,40 @@ namespace Renci.SshNet
             var fullPath = _sftpSession.GetCanonicalPath(path);
 
             var handle = _sftpSession.RequestOpen(fullPath, Flags.Read);
-            var async = true;
-            if (async)
-            {
-                var fileReader = new SftpFileReader(handle, _sftpSession);
-                var totalBytesRead = 0UL;
-
-                while (true)
-                {
-                    var data = fileReader.Read();
-                    if (data.Length == 0)
-                        break;
 
-                    output.Write(data, 0, data.Length);
+            ulong offset = 0;
 
-                    totalBytesRead += (ulong) data.Length;
+            var optimalReadLength = _sftpSession.CalculateOptimalReadLength(_bufferSize);
 
-                    //Console.WriteLine(totalBytesRead);
+            var data = _sftpSession.RequestRead(handle, offset, optimalReadLength);
 
-                    if (downloadCallback != null)
-                        downloadCallback(totalBytesRead);
-                }
-            }
-            else
+            //  Read data while available
+            while (data.Length > 0)
             {
-                ulong offset = 0;
-
-                var optimalReadLength = _sftpSession.CalculateOptimalReadLength(_bufferSize);
-
-                var data = _sftpSession.RequestRead(handle, offset, optimalReadLength);
-
-                //  Read data while available
-                while (data.Length > 0)
-                {
-                    //  Cancel download
-                    if (asyncResult != null && asyncResult.IsDownloadCanceled)
-                        break;
-
-                    output.Write(data, 0, data.Length);
-
-                    output.Flush();
-
-                    offset += (ulong)data.Length;
-
-                    //Console.WriteLine("" + data.Length + " => " + offset);
+                //  Cancel download
+                if (asyncResult != null && asyncResult.IsDownloadCanceled)
+                    break;
 
-                    //  Call callback to report number of bytes read
-                    if (downloadCallback != null)
-                    {
-                        // copy offset to ensure it's not modified between now and execution of callback
-                        var downloadOffset = offset;
+                output.Write(data, 0, data.Length);
 
-                        //  Execute callback on different thread
-                        ThreadAbstraction.ExecuteThread(() => { downloadCallback(downloadOffset); });
-                    }
+                output.Flush();
 
-                    data = _sftpSession.RequestRead(handle, offset, optimalReadLength);
-                }
-            }
-
-            _sftpSession.RequestClose(handle);
-        }
+                offset += (ulong)data.Length;
 
-        private class BlockingQueue<T>
-        {
-            private readonly object _lock = new object();
-            private Queue<T> _queue;
-            private bool _isClosed;
-
-            public BlockingQueue(int capacity)
-            {
-                _queue = new Queue<T>(capacity);
-            }
-
-            public T Dequeue()
-            {
-                lock (_lock)
+                //  Call callback to report number of bytes read
+                if (downloadCallback != null)
                 {
-                    while (!_isClosed && _queue.Count == 0)
-                        Monitor.Wait(_lock);
+                    // copy offset to ensure it's not modified between now and execution of callback
+                    var downloadOffset = offset;
 
-                    if (_queue.Count == 0)
-                        return default(T);
-
-                    return _queue.Dequeue();
-                }
-            }
-
-            public void Enqueue(T item)
-            {
-                lock (_lock)
-                {
-                    _queue.Enqueue(item);
-                    Monitor.PulseAll(_lock);
+                    //  Execute callback on different thread
+                    ThreadAbstraction.ExecuteThread(() => { downloadCallback(downloadOffset); });
                 }
-            }
 
-            public void Close()
-            {
-                _isClosed = true;
-                Monitor.PulseAll(_lock);
+                data = _sftpSession.RequestRead(handle, offset, optimalReadLength);
             }
-        }
 
-        private class BufferedRead
-        {
-            public byte[] Data { get; private set; }
-
-            public ulong Offset { get; private set; }
-
-            public BufferedRead(ulong offset, byte[] data)
-            {
-                Offset = offset;
-                Data = data;
-            }
+            _sftpSession.RequestClose(handle);
         }
 
         /// <summary>

+ 1 - 1
src/Renci.SshNet/SubsystemSession.cs

@@ -42,7 +42,7 @@ namespace Renci.SshNet
         /// <value>
         /// The channel associated with this session.
         /// </value>
-        public IChannelSession Channel
+        internal IChannelSession Channel
         {
             get
             {