public static async Task WriteContinuation( this IWriteAndCloseableByteStream stream, Encoder encoder, uint streamId, IEnumerable <HeaderField> headers, bool endOfHeaders = true) { var outBuf = new byte[Settings.Default.MaxFrameSize]; var result = encoder.EncodeInto(new ArraySegment <byte>(outBuf), headers); // Check if all headers could be encoded if (result.FieldCount != headers.Count()) { throw new Exception("Could not encode all headers"); } byte flags = 0; if (endOfHeaders) { flags |= (byte)ContinuationFrameFlags.EndOfHeaders; } var fh = new FrameHeader { Type = FrameType.Continuation, Length = result.UsedBytes, Flags = flags, StreamId = streamId, }; await stream.WriteFrameHeader(fh); await stream.WriteAsync( new ArraySegment <byte>(outBuf, 0, result.UsedBytes)); }
public static async Task WriteSettingsAck( this IWriteAndCloseableByteStream stream) { var fh = new FrameHeader { Type = FrameType.Settings, Length = 0, Flags = (byte)SettingsFrameFlags.Ack, StreamId = 0, }; await stream.WriteFrameHeader(fh); }
public static async Task WritePing( this IWriteAndCloseableByteStream stream, byte[] data, bool isAck) { var pingHeader = new FrameHeader { Type = FrameType.Ping, Flags = isAck ? (byte)PingFrameFlags.Ack : (byte)0, Length = 8, StreamId = 0, }; await stream.WriteFrameHeader(pingHeader); await stream.WriteAsync(new ArraySegment <byte>(data, 0, 8)); }
public static async Task WriteFrameHeaderWithTimeout( this IWriteAndCloseableByteStream stream, FrameHeader fh) { var writeTask = stream.WriteFrameHeader(fh); var timeoutTask = Task.Delay(WriteTimeout); var combined = Task.WhenAny(new Task[] { writeTask, timeoutTask }); var done = await combined; if (done == writeTask) { await writeTask; return; } throw new TimeoutException(); }
public static async Task WriteSettings( this IWriteAndCloseableByteStream stream, Settings settings) { var settingsData = new byte[settings.RequiredSize]; var fh = new FrameHeader { Type = FrameType.Settings, Length = settingsData.Length, Flags = 0, StreamId = 0, }; settings.EncodeInto(new ArraySegment <byte>(settingsData)); await stream.WriteFrameHeader(fh); await stream.WriteAsync(new ArraySegment <byte>(settingsData)); }
public static async Task WriteData( this IWriteAndCloseableByteStream stream, uint streamId, int length, int?padLen = null, bool endOfStream = false) { byte flags = 0; if (endOfStream) { flags |= (byte)DataFrameFlags.EndOfStream; } if (padLen.HasValue) { flags |= (byte)DataFrameFlags.Padded; } var dataLen = length; if (padLen.HasValue) { dataLen += 1 + padLen.Value; } var data = new byte[dataLen]; if (padLen.HasValue) { data[0] = (byte)padLen.Value; } var fh = new FrameHeader { Type = FrameType.Data, Length = dataLen, Flags = flags, StreamId = streamId, }; await stream.WriteFrameHeader(fh); if (dataLen != 0) { await stream.WriteWithTimeout(new ArraySegment <byte>(data)); } }
public static async Task WritePriority( this IWriteAndCloseableByteStream stream, uint streamId, PriorityData prioData) { var fh = new FrameHeader { Type = FrameType.Priority, Flags = 0, Length = PriorityData.Size, StreamId = streamId, }; await stream.WriteFrameHeader(fh); var payload = new byte[PriorityData.Size]; prioData.EncodeInto(new ArraySegment <byte>(payload)); await stream.WriteAsync(new ArraySegment <byte>(payload)); }
public static async Task WriteResetStream( this IWriteAndCloseableByteStream stream, uint streamId, ErrorCode errc) { var fh = new FrameHeader { Type = FrameType.ResetStream, Flags = 0, Length = ResetFrameData.Size, StreamId = streamId, }; var data = new ResetFrameData { ErrorCode = errc, }; var dataBytes = new byte[ResetFrameData.Size]; data.EncodeInto(new ArraySegment <byte>(dataBytes)); await stream.WriteFrameHeader(fh); await stream.WriteAsync(new ArraySegment <byte>(dataBytes)); }
public static async Task WriteWindowUpdate( this IWriteAndCloseableByteStream stream, uint streamId, int amount) { var windowUpdateHeader = new FrameHeader { Type = FrameType.WindowUpdate, Flags = 0, Length = WindowUpdateData.Size, StreamId = streamId, }; var data = new WindowUpdateData { WindowSizeIncrement = amount, }; var dataBytes = new byte[WindowUpdateData.Size]; data.EncodeInto(new ArraySegment <byte>(dataBytes)); await stream.WriteFrameHeader(windowUpdateHeader); await stream.WriteAsync(new ArraySegment <byte>(dataBytes)); }
public static async Task WriteGoAway( this IWriteAndCloseableByteStream stream, uint lastStreamId, ErrorCode errc, byte[] debugData = null) { if (debugData == null) { debugData = new byte[0]; } var goAwayData = new GoAwayFrameData { Reason = new GoAwayReason { LastStreamId = lastStreamId, ErrorCode = errc, DebugData = new ArraySegment <byte>(debugData), }, }; var fh = new FrameHeader { Type = FrameType.GoAway, Flags = 0, StreamId = 0, Length = goAwayData.RequiredSize, }; var dataBytes = new byte[goAwayData.RequiredSize]; goAwayData.EncodeInto(new ArraySegment <byte>(dataBytes)); await stream.WriteFrameHeader(fh); await stream.WriteAsync(new ArraySegment <byte>(dataBytes)); }