Пример #1
0
        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));
            }
        }
Пример #2
0
        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());
        }
Пример #3
0
        /*  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());
        }