public Task WriteDataAsync(int streamId, ReadOnlySpan <byte> data, bool endStream, CancellationToken cancellationToken) { var tasks = new List <Task>(); lock (_writeLock) { _outgoingFrame.PrepareData(streamId); while (data.Length > _outgoingFrame.Length) { data.Slice(0, _outgoingFrame.Length).CopyTo(_outgoingFrame.Payload); data = data.Slice(_outgoingFrame.Length); tasks.Add(WriteAsync(_outgoingFrame.Raw, cancellationToken)); } _outgoingFrame.Length = data.Length; if (endStream) { _outgoingFrame.DataFlags = Http2DataFrameFlags.END_STREAM; } data.CopyTo(_outgoingFrame.Payload); tasks.Add(WriteAsync(_outgoingFrame.Raw, cancellationToken)); return(Task.WhenAll(tasks)); } }
private Task WriteDataUnsynchronizedAsync(int streamId, ReadOnlySequence <byte> data, bool endStream) { _outgoingFrame.PrepareData(streamId); var payload = _outgoingFrame.Payload; var unwrittenPayloadLength = 0; foreach (var buffer in data) { var current = buffer; while (current.Length > payload.Length) { current.Span.Slice(0, payload.Length).CopyTo(payload); current = current.Slice(payload.Length); _log.Http2FrameSending(_connectionId, _outgoingFrame); _outputWriter.Write(_outgoingFrame.Raw); payload = _outgoingFrame.Payload; unwrittenPayloadLength = 0; } if (current.Length > 0) { current.Span.CopyTo(payload); payload = payload.Slice(current.Length); unwrittenPayloadLength += current.Length; } } if (endStream) { _outgoingFrame.DataFlags = Http2DataFrameFlags.END_STREAM; } _outgoingFrame.PayloadLength = unwrittenPayloadLength; _log.Http2FrameSending(_connectionId, _outgoingFrame); _outputWriter.Write(_outgoingFrame.Raw); return(_flusher.FlushAsync()); }
/* Padding is not implemented +---------------+ |Pad Length? (8)| +---------------+-----------------------------------------------+ | Data (*) ... +---------------------------------------------------------------+ | Padding (*) ... +---------------------------------------------------------------+ */ private Task WriteDataUnsynchronizedAsync(int streamId, ReadOnlySequence <byte> data, bool endStream) { // Note padding is not implemented _outgoingFrame.PrepareData(streamId); var dataPayloadLength = (int)_maxFrameSize; // Minus padding while (data.Length > dataPayloadLength) { var currentData = data.Slice(0, dataPayloadLength); _outgoingFrame.PayloadLength = dataPayloadLength; // Plus padding WriteHeaderUnsynchronized(); foreach (var buffer in currentData) { _outputWriter.Write(buffer.Span); } // Plus padding data = data.Slice(dataPayloadLength); } if (endStream) { _outgoingFrame.DataFlags |= Http2DataFrameFlags.END_STREAM; } _outgoingFrame.PayloadLength = (int)data.Length; // Plus padding WriteHeaderUnsynchronized(); foreach (var buffer in data) { _outputWriter.Write(buffer.Span); } // Plus padding return(_flusher.FlushAsync()); }