Преглед изворни кода

Failure when streamed data are detected earlier than <download> tag

(cherry picked from commit 6da51900239d62548ee22f72bab5ce8ba2da9bee)

Source commit: 6a3c30afe5140e9deba8aab9126b1ddf12a463ef
Martin Prikryl пре 5 година
родитељ
комит
4309595bb0
2 измењених фајлова са 25 додато и 24 уклоњено
  1. 21 16
      dotnet/Session.cs
  2. 4 8
      dotnet/internal/PipeStream.cs

+ 21 - 16
dotnet/Session.cs

@@ -1029,33 +1029,40 @@ namespace WinSCP
                 ParseRemotePath(remoteFilePath, out string remoteDirectory, out string filemask);
                 string remotePath = RemotePath.Combine(remoteDirectory, filemask);
 
-                StartGetCommand(remotePath, "-", false, options, additionalParams);
-
                 // only to collect failures
                 TransferOperationResult result = new TransferOperationResult();
 
-                ElementLogReader groupReader = _reader.WaitForGroupAndCreateLogReader();
-                IDisposable operationResultGuard = RegisterOperationResult(result);
-                IDisposable progressHandler = CreateProgressHandler();
+                ElementLogReader groupReader = null;
+                IDisposable operationResultGuard = null;
+                IDisposable progressHandler = null;
+
+                // should never happen
+                if (_process.StdOut != null)
+                {
+                    throw Logger.WriteException(new InvalidOperationException("Data stream already exist"));
+                }
+
+                PipeStream stream = new PipeStream();
+                _process.StdOut = stream;
 
                 void onGetEnd()
                 {
                     try
                     {
                         // This can throw
-                        progressHandler.Dispose();
+                        progressHandler?.Dispose();
                     }
                     finally
                     {
                         try
                         {
-                            groupReader.Dispose();
+                            groupReader?.Dispose();
                         }
                         finally
                         {
                             _process.StdOut = null;
                             // Only after disposing the group reader, so when called from onGetEndWithExit, the Check() has all failures.
-                            operationResultGuard.Dispose();
+                            operationResultGuard?.Dispose();
                         }
                     }
                 }
@@ -1073,17 +1080,14 @@ namespace WinSCP
                     }
                 }
 
-                // should never happen
-                if (_process.StdOut != null)
+                try
                 {
-                    throw Logger.WriteException(new InvalidOperationException("Data stream already exist"));
-                }
+                    StartGetCommand(remotePath, "-", false, options, additionalParams);
 
-                PipeStream stream = new PipeStream(onGetEndWithExit);
-                _process.StdOut = stream;
+                    groupReader = _reader.WaitForGroupAndCreateLogReader();
+                    operationResultGuard = RegisterOperationResult(result);
+                    progressHandler = CreateProgressHandler();
 
-                try
-                {
                     bool downloadFound;
                     try
                     {
@@ -1099,6 +1103,7 @@ namespace WinSCP
                     if (downloadFound)
                     {
                         callstackAndLock.DisarmLock();
+                        stream.OnDispose = onGetEndWithExit;
                         return stream;
                     }
                     else

+ 4 - 8
dotnet/internal/PipeStream.cs

@@ -54,12 +54,6 @@ namespace WinSCP
         private bool _isDisposed;
 
         private bool _closedWrite;
-        private Action _onDispose;
-
-        public PipeStream(Action onDispose)
-        {
-            _onDispose = onDispose;
-        }
 
         #endregion
 
@@ -71,6 +65,8 @@ namespace WinSCP
         /// <value>The length of the max buffer.</value>
         public long MaxBufferLength { get; set; } = 200 * 1024 * 1024;
 
+        public Action OnDispose { get; set; }
+
         #endregion
 
         #region Stream overide methods
@@ -349,8 +345,8 @@ namespace WinSCP
 
         private void Closed()
         {
-            Action onDispose = _onDispose;
-            _onDispose = null;
+            Action onDispose = OnDispose;
+            OnDispose = null;
             onDispose?.Invoke();
         }
     }