OpenSSL.SSL.SslStreamBase.InternalReadCallback C# (CSharp) Метод

InternalReadCallback() приватный Метод

private InternalReadCallback ( IAsyncResult asyncResult ) : void
asyncResult IAsyncResult
Результат void
		private void InternalReadCallback(IAsyncResult asyncResult)
		{
			InternalAsyncResult internalAsyncResult = (InternalAsyncResult)asyncResult.AsyncState;
			bool haveDataToReturn = false;

			try
			{
				int bytesRead = 0;
				try
				{
					bytesRead = innerStream.EndRead(asyncResult);
				}
				catch (Exception ex)
				{
					// Set the exception into the internal async result
					internalAsyncResult.SetComplete(ex);
				}
				if (bytesRead <= 0)
				{
					// Zero byte read most likely indicates connection closed (if it's a network stream)
					internalAsyncResult.SetComplete(0);
					return;
				}
				else
				{
					// Copy encrypted data into the SSL read_bio
					read_bio.Write(read_buffer, bytesRead);
					if (handShakeState == HandshakeState.InProcess ||
						handShakeState == HandshakeState.RenegotiateInProcess)
					{
						// We are in the handshake, complete the async operation to fire the async
						// handshake callback for processing
						internalAsyncResult.SetComplete(bytesRead);
						return;
					}
					uint nBytesPending = read_bio.BytesPending;
					byte[] decrypted_buf = new byte[SSL3_RT_MAX_PACKET_SIZE];
					while (nBytesPending > 0)
					{
						int decryptedBytesRead = ssl.Read(decrypted_buf, decrypted_buf.Length);
						if (decryptedBytesRead <= 0)
						{
							SslError lastError = ssl.GetError(decryptedBytesRead);
							if (lastError == SslError.SSL_ERROR_WANT_READ)
							{
								// if we have bytes pending in the write bio.
								// the client has requested a renegotiation
								if (write_bio.BytesPending > 0)
								{
									// Start the renegotiation by writing the write_bio data, and use the RenegotiationWriteCallback
									// to handle the rest of the renegotiation
									ArraySegment<byte> buf = write_bio.ReadBytes((int)write_bio.BytesPending);
									innerStream.BeginWrite(buf.Array, 0, buf.Count, new AsyncCallback(RenegotiationWriteCallback), internalAsyncResult);
									return;
								}
								// no data in the out bio, we just need more data to complete the record
								//break;
							}
							else if (lastError == SslError.SSL_ERROR_WANT_WRITE)
							{
								// unexpected error!
								//!!TODO debug log
							}
							else if (lastError == SslError.SSL_ERROR_ZERO_RETURN)
							{
								// Shutdown alert
								SendShutdownAlert();
								break;
							}
							else
							{
								throw new OpenSslException();
							}
						}
						if (decryptedBytesRead > 0)
						{
							// Write decrypted data to memory stream
							long pos = decrypted_data_stream.Position;
							decrypted_data_stream.Seek(0, SeekOrigin.End);
							decrypted_data_stream.Write(decrypted_buf, 0, decryptedBytesRead);
							decrypted_data_stream.Seek(pos, SeekOrigin.Begin);
							haveDataToReturn = true;
						}

						// See if we have more data to process
						nBytesPending = read_bio.BytesPending;
					}
					// Check to see if we have data to return, if not, fire the async read again
					if (!haveDataToReturn)
					{
						innerStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(InternalReadCallback), internalAsyncResult);
					}
					else
					{
						int bytesReadIntoUserBuffer = 0;

						// Read the data into the buffer provided by the user (now hosted in the InternalAsyncResult)
						bytesReadIntoUserBuffer = decrypted_data_stream.Read(internalAsyncResult.Buffer, internalAsyncResult.Offset, internalAsyncResult.Count);

						internalAsyncResult.SetComplete(bytesReadIntoUserBuffer);
					}
				}
			}
			catch (Exception ex)
			{
				internalAsyncResult.SetComplete(ex);
			}
		}