in src/Transport/TlsTransport.cs [77:134]
public override bool WriteAsync(TransportAsyncCallbackArgs args)
{
Fx.Assert(this.writeState.Args == null, "Cannot write when a write is still in progress");
ArraySegment<byte> buffer;
if (args.Buffer != null)
{
buffer = new ArraySegment<byte>(args.Buffer, args.Offset, args.Count);
this.writeState.Args = args;
}
else
{
Fx.Assert(args.ByteBufferList != null, "Buffer list should not be null when buffer is null");
if (args.ByteBufferList.Count == 1)
{
ByteBuffer byteBuffer = args.ByteBufferList[0];
buffer = new ArraySegment<byte>(byteBuffer.Buffer, byteBuffer.Offset, byteBuffer.Length);
this.writeState.Args = args;
}
else
{
// Copy all buffers into one big buffer to avoid SSL overhead
Fx.Assert(args.Count > 0, "args.Count should be set");
ByteBuffer temp = new ByteBuffer(args.Count, false, false);
for (int i = 0; i < args.ByteBufferList.Count; ++i)
{
ByteBuffer byteBuffer = args.ByteBufferList[i];
Buffer.BlockCopy(byteBuffer.Buffer, byteBuffer.Offset, temp.Buffer, temp.Length, byteBuffer.Length);
temp.Append(byteBuffer.Length);
}
buffer = new ArraySegment<byte>(temp.Buffer, 0, temp.Length);
this.writeState.Args = args;
this.writeState.Buffer = temp;
}
}
IAsyncResult result;
try
{
result = this.sslStream.BeginWrite(buffer.Array, buffer.Offset, buffer.Count, onWriteComplete, this);
}
catch (ObjectDisposedException ode)
{
throw new IOException($"Transport '{this}' is closed", ode);
}
catch (InvalidOperationException ioe)
{
throw new IOException($"Transport '{this}' is valid for write operations.", ioe);
}
bool completedSynchronously = result.CompletedSynchronously;
if (completedSynchronously)
{
this.HandleOperationComplete(result, true, true);
}
return !completedSynchronously;
}