/// <summary> /// Creates a bidirectionally open stream, /// where the headers in both directions have already been sent but /// no data. /// </summary> public static async Task <Result> CreateConnectionAndStream( bool isServer, ILoggerProvider loggerProvider, IBufferedPipe iPipe, IBufferedPipe oPipe, Settings?localSettings = null, Settings?remoteSettings = null, HuffmanStrategy huffmanStrategy = HuffmanStrategy.Never) { var result = new Result(); if (isServer) { var r1 = await ServerStreamTests.StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, iPipe, oPipe, localSettings, remoteSettings, huffmanStrategy); // Headers have been received but not sent await r1.stream.WriteHeadersAsync(DefaultStatusHeaders, false); await oPipe.ReadAndDiscardHeaders(1u, false); result.conn = r1.conn; result.hEncoder = r1.hEncoder; result.stream = r1.stream; } else { var r1 = await ClientStreamTests.StreamCreator.CreateConnectionAndStream( StreamState.Open, loggerProvider, iPipe, oPipe, localSettings, remoteSettings, huffmanStrategy); // Headers have been sent but not yet received await iPipe.WriteHeaders(r1.hEncoder, 1u, false, DefaultStatusHeaders, true); result.conn = r1.conn; result.hEncoder = r1.hEncoder; result.stream = r1.stream; } return(result); }
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, }); }