internal async Task InnerProcessRequestsAsync <TContext>(IHttpApplication <TContext> application) { // Start other three unidirectional streams here. var controlTask = CreateControlStream(application); var encoderTask = CreateEncoderStream(application); var decoderTask = CreateDecoderStream(application); try { while (true) { var streamContext = await _multiplexedContext.AcceptAsync(); if (streamContext == null || _haveSentGoAway) { break; } var quicStreamFeature = streamContext.Features.Get <IStreamDirectionFeature>(); var streamIdFeature = streamContext.Features.Get <IStreamIdFeature>(); Debug.Assert(quicStreamFeature != null); var httpConnectionContext = new Http3StreamContext { ConnectionId = streamContext.ConnectionId, StreamContext = streamContext, // TODO connection context is null here. Should we set it to anything? ServiceContext = _context.ServiceContext, ConnectionFeatures = streamContext.Features, MemoryPool = _context.MemoryPool, Transport = streamContext.Transport, TimeoutControl = _context.TimeoutControl, LocalEndPoint = streamContext.LocalEndPoint as IPEndPoint, RemoteEndPoint = streamContext.RemoteEndPoint as IPEndPoint }; if (!quicStreamFeature.CanWrite) { // Unidirectional stream var stream = new Http3ControlStream <TContext>(application, this, httpConnectionContext); ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false); } else { // Keep track of highest stream id seen for GOAWAY var streamId = streamIdFeature.StreamId; HighestStreamId = streamId; var http3Stream = new Http3Stream <TContext>(application, this, httpConnectionContext); var stream = http3Stream; lock (_streams) { _streams[streamId] = http3Stream; } KestrelEventSource.Log.RequestQueuedStart(stream, AspNetCore.Http.HttpProtocol.Http3); ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false); } } } finally { // Abort all streams as connection has shutdown. lock (_streams) { foreach (var stream in _streams.Values) { stream.Abort(new ConnectionAbortedException("Connection is shutting down.")); } } ControlStream?.Abort(new ConnectionAbortedException("Connection is shutting down.")); EncoderStream?.Abort(new ConnectionAbortedException("Connection is shutting down.")); DecoderStream?.Abort(new ConnectionAbortedException("Connection is shutting down.")); await controlTask; await encoderTask; await decoderTask; } }
static void Main(string[] args) { #region Test1 IAbstractValue[] Test1_InitialDataArray = new IAbstractValue[] { new IntValue(685000), new StringValue("Hello!") }; TableValue Test1_InitialData = TableValue.ArrayToTable(Test1_InitialDataArray); Console.WriteLine("Begin Test 1"); Console.WriteLine(); EncoderStream Test1_EnStream = new EncoderStream(); string Test1_EncodeResult; Console.Write("Encoding..."); Test1_EnStream.InputValue(Test1_InitialData); Test1_EncodeResult = Test1_EnStream.PopOutput(); Console.WriteLine(" Done!"); Console.WriteLine(string.Concat("Encode Result: ", Test1_EncodeResult)); Console.WriteLine(); Console.WriteLine("End Test 1"); #endregion Console.WriteLine(); #region Test2 // The string that was in the Specification.odt document. string Test2_InitialString = "[\"My name is PC!\";800;]||[\"Data1\":0.56;\"Data2\":\"true \\| false\";]||[[\"My home.\";T;1000;F;];]||"; Console.WriteLine("Begin Test 2"); Console.WriteLine(); Console.WriteLine(string.Concat("Initial String: ", Test2_InitialString)); Console.WriteLine(); DecoderStream Test2_DeStream = new DecoderStream(); EncoderStream Test2_EnStream = new EncoderStream(); IAbstractValue[] Test2_DecodeResult; string Test2_EncodeResult; Console.Write("Decoding..."); Test2_DeStream.InputValue(Test2_InitialString); Test2_DeStream.RunParser(); Test2_DecodeResult = Test2_DeStream.PopOutput(); // ((TableValue)Test2_DeStream.PopOutput()[0]).Value; Console.WriteLine(" Done!"); Console.Write("Encoding..."); foreach (var item in Test2_DecodeResult) { Test2_EnStream.InputValue(item); } Test2_EncodeResult = Test2_EnStream.PopOutput(); Console.WriteLine(" Done!"); Console.WriteLine(); Console.WriteLine(string.Concat("Encode Result: ", Test2_EncodeResult)); Console.WriteLine(string.Concat("Strings Match: ", (Test2_InitialString == Test2_EncodeResult).ToString())); Console.WriteLine(); Console.WriteLine("End Test 2"); #endregion Console.WriteLine(); Console.WriteLine("Exiting Program..."); return; }
/// <summary> /// Reset state for encoding/decoding. Does not change lengths, only indices /// </summary> public void Reset() { LiteralIndex = TokenIndex = DecisionIndex = DatumIndex = 0; SymbolCallIndex = 0; DecoderStream.Clear(); }
public async Task ProcessRequestsAsync <TContext>(IHttpApplication <TContext> application) { var streamListenerFeature = Context.ConnectionFeatures.Get <IQuicStreamListenerFeature>(); // Start other three unidirectional streams here. var controlTask = CreateControlStream(application); var encoderTask = CreateEncoderStream(application); var decoderTask = CreateDecoderStream(application); try { while (true) { var connectionContext = await streamListenerFeature.AcceptAsync(); if (connectionContext == null || _haveSentGoAway) { break; } var httpConnectionContext = new HttpConnectionContext { ConnectionId = connectionContext.ConnectionId, ConnectionContext = connectionContext, Protocols = Context.Protocols, ServiceContext = Context.ServiceContext, ConnectionFeatures = connectionContext.Features, MemoryPool = Context.MemoryPool, Transport = connectionContext.Transport, TimeoutControl = Context.TimeoutControl, LocalEndPoint = connectionContext.LocalEndPoint as IPEndPoint, RemoteEndPoint = connectionContext.RemoteEndPoint as IPEndPoint }; var streamFeature = httpConnectionContext.ConnectionFeatures.Get <IQuicStreamFeature>(); if (!streamFeature.CanWrite) { // Unidirectional stream var stream = new Http3ControlStream <TContext>(application, this, httpConnectionContext); ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false); } else { // Keep track of highest stream id seen for GOAWAY var streamId = streamFeature.StreamId; HighestStreamId = streamId; var http3Stream = new Http3Stream <TContext>(application, this, httpConnectionContext); var stream = http3Stream; _streams[streamId] = http3Stream; ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false); } } } finally { // Abort all streams as connection has shutdown. foreach (var stream in _streams.Values) { stream.Abort(new ConnectionAbortedException("Connection is shutting down.")); } ControlStream.Abort(new ConnectionAbortedException("Connection is shutting down.")); EncoderStream.Abort(new ConnectionAbortedException("Connection is shutting down.")); DecoderStream.Abort(new ConnectionAbortedException("Connection is shutting down.")); await controlTask; await encoderTask; await decoderTask; } }