[release/3.0] SqlClient fix for managed encryption connection failure (#40825)
authorCheena Malhotra <v-chmalh@microsoft.com>
Thu, 5 Sep 2019 20:21:40 +0000 (13:21 -0700)
committerDan Moseley <danmose@microsoft.com>
Thu, 5 Sep 2019 20:21:40 +0000 (13:21 -0700)
src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SslOverTdsStream.cs

index 9a9bd82..74dc437 100644 (file)
@@ -89,71 +89,51 @@ namespace System.Data.SqlClient.SNI
         /// </summary>
         private async Task<int> ReadInternal(byte[] buffer, int offset, int count, CancellationToken token, bool async)
         {
+            int readBytes = 0;
+            byte[] packetData = null;
+            byte[] readTarget = buffer;
+            int readOffset = offset;
             if (_encapsulate)
             {
-                return await ReadInternalEncapsulate(buffer, offset, count, token, async);
-            }
-            else if (async)
-            {
-                return await ReadInternalAsync(buffer, offset, count, token);
-            }
-            else
-            {
-                return ReadInternalSync(buffer, offset, count);
-            }
-        }
+                packetData = ArrayPool<byte>.Shared.Rent(count < TdsEnums.HEADER_LEN ? TdsEnums.HEADER_LEN : count);
+                readTarget = packetData;
+                readOffset = 0;
+                if (_packetBytes == 0)
+                {
+                    // Account for split packets
+                    while (readBytes < TdsEnums.HEADER_LEN)
+                    {
+                        readBytes += async ?
+                            await _stream.ReadAsync(packetData, readBytes, TdsEnums.HEADER_LEN - readBytes, token).ConfigureAwait(false) :
+                            _stream.Read(packetData, readBytes, TdsEnums.HEADER_LEN - readBytes);
+                    }
 
-        private async Task<int> ReadInternalEncapsulate(byte[] buffer, int offset, int count, CancellationToken token, bool async)
-        {
-            int readBytes = 0;
-            byte[] packetData = ArrayPool<byte>.Shared.Rent(count < TdsEnums.HEADER_LEN ? TdsEnums.HEADER_LEN : count);
+                    _packetBytes = (packetData[TdsEnums.HEADER_LEN_FIELD_OFFSET] << 8) | packetData[TdsEnums.HEADER_LEN_FIELD_OFFSET + 1];
+                    _packetBytes -= TdsEnums.HEADER_LEN;
+                }
 
-            if (_packetBytes == 0)
-            {
-                // Account for split packets
-                while (readBytes < TdsEnums.HEADER_LEN)
+                if (count > _packetBytes)
                 {
-                    readBytes += (async ?
-                        await ReadInternalAsync(packetData, readBytes, TdsEnums.HEADER_LEN - readBytes, token) :
-                        ReadInternalSync(packetData, readBytes, TdsEnums.HEADER_LEN - readBytes)
-                   );
+                    count = _packetBytes;
                 }
-
-                _packetBytes = (packetData[TdsEnums.HEADER_LEN_FIELD_OFFSET] << 8) | packetData[TdsEnums.HEADER_LEN_FIELD_OFFSET + 1];
-                _packetBytes -= TdsEnums.HEADER_LEN;
             }
 
-            if (count > _packetBytes)
+            readBytes = async ?
+                await _stream.ReadAsync(readTarget, readOffset, count, token).ConfigureAwait(false) :
+                _stream.Read(readTarget, readOffset, count);
+
+            if (_encapsulate)
             {
-                count = _packetBytes;
+                _packetBytes -= readBytes;
+            }
+            if (packetData != null)
+            {
+                Buffer.BlockCopy(packetData, 0, buffer, offset, readBytes);
+                ArrayPool<byte>.Shared.Return(packetData, clearArray: true);
             }
-            
-            readBytes = (async ?
-                await ReadInternalAsync(packetData, 0, count, token) :
-                ReadInternalSync(packetData, 0, count)
-            );
-
-
-            _packetBytes -= readBytes;
-            
-            Buffer.BlockCopy(packetData, 0, buffer, offset, readBytes);
-
-            Array.Clear(packetData, 0, readBytes);
-            ArrayPool<byte>.Shared.Return(packetData, clearArray: false);
-
             return readBytes;
         }
 
-        private async Task<int> ReadInternalAsync(byte[] buffer, int offset, int count, CancellationToken token)
-        {
-            return await _stream.ReadAsync(buffer, 0, count, token).ConfigureAwait(false);
-        }
-
-        private int ReadInternalSync(byte[] buffer, int offset, int count)
-        {
-            return _stream.Read(buffer, 0, count);
-        }
-
         /// <summary>
         /// The internal write method calls Sync APIs when Async flag is false
         /// </summary>