public static async Task <Result> CreateClientConnectionAndStream( StreamState state, ILoggerProvider loggerProvider, IBufferedPipe iPipe, IBufferedPipe oPipe, Settings?localSettings = null, Settings?remoteSettings = null, HuffmanStrategy huffmanStrategy = HuffmanStrategy.Never) { if (state == StreamState.Idle) { throw new Exception("Not supported"); } var hEncoder = new Encoder(); var conn = await Http2ConnectionUtils.BuildEstablishedConnection( false, iPipe, oPipe, loggerProvider, null, localSettings : localSettings, remoteSettings : remoteSettings, huffmanStrategy : huffmanStrategy); var endOfStream = false; if (state == StreamState.HalfClosedLocal || state == StreamState.Closed) { endOfStream = true; } var stream = await conn.CreateStreamAsync( DefaultGetHeaders, endOfStream : endOfStream); await oPipe.ReadAndDiscardHeaders(1u, endOfStream); if (state == StreamState.HalfClosedRemote || state == StreamState.Closed) { var outBuf = new byte[Settings.Default.MaxFrameSize]; var result = hEncoder.EncodeInto( new ArraySegment <byte>(outBuf), DefaultStatusHeaders); await iPipe.WriteFrameHeaderWithTimeout( new FrameHeader { Type = FrameType.Headers, Flags = (byte)(HeadersFrameFlags.EndOfHeaders | HeadersFrameFlags.EndOfStream), StreamId = 1u, Length = result.UsedBytes, }); await iPipe.WriteAsync(new ArraySegment <byte>(outBuf, 0, result.UsedBytes)); var readHeadersTask = stream.ReadHeadersAsync(); var combined = await Task.WhenAny(readHeadersTask, Task.Delay( Http2ReadableStreamTestExtensions.ReadTimeout)); Assert.True(readHeadersTask == combined, "Expected to receive headers"); var headers = await readHeadersTask; Assert.True(headers.SequenceEqual(DefaultStatusHeaders)); } else if (state == StreamState.Reset) { await iPipe.WriteResetStream(1u, ErrorCode.Cancel); } return(new Result { hEncoder = hEncoder, conn = conn, stream = stream, }); }
public static async Task <Result> CreateServerConnectionAndStream(HeaderField[] getHeaders, StreamState state, ILoggerProvider loggerProvider, IBufferedPipe iPipe, IBufferedPipe oPipe, Settings?localSettings = null, Settings?remoteSettings = null, HuffmanStrategy huffmanStrategy = HuffmanStrategy.Never) { IStream stream = null; var handlerDone = new SemaphoreSlim(0); if (state == StreamState.Idle) { throw new Exception("Not supported"); } Func <IStream, bool> listener = (s) => { Task.Run(async() => { stream = s; try { await s.ReadHeadersAsync(); if (state == StreamState.Reset) { s.Cancel(); return; } if (state == StreamState.HalfClosedRemote || state == StreamState.Closed) { await s.ReadAllToArrayWithTimeout(); } if (state == StreamState.HalfClosedLocal || state == StreamState.Closed) { await s.WriteHeadersAsync( DefaultStatusHeaders, true); } } finally { handlerDone.Release(); } }); return(true); }; var conn = await Http2ConnectionUtils.BuildEstablishedConnection( true, iPipe, oPipe, loggerProvider, listener, localSettings : localSettings, remoteSettings : remoteSettings, huffmanStrategy : huffmanStrategy); var hEncoder = new Encoder(); await iPipe.WriteHeaders( hEncoder, 1, false, getHeaders); if (state == StreamState.HalfClosedRemote || state == StreamState.Closed) { await iPipe.WriteData(1u, 0, endOfStream : true); } var ok = await handlerDone.WaitAsync( Http2ReadableStreamTestExtensions.ReadTimeout); if (!ok) { throw new Exception("Stream handler did not finish"); } if (state == StreamState.HalfClosedLocal || state == StreamState.Closed) { // Consume the sent headers and data await oPipe.ReadAndDiscardHeaders(1u, true); } else if (state == StreamState.Reset) { // Consume the sent reset frame await oPipe.AssertResetStreamReception(1, ErrorCode.Cancel); } return(new Result { conn = conn, stream = stream, hEncoder = hEncoder, }); }