public void WriteMoreDataThanCredited_OnlyCreditedDataWritten()
        {
            using (Stream transport = new QueueStream())
            using (WriteQueue queue = new WriteQueue(transport))
            {
                Task pumpTask = queue.PumpToStreamAsync();
                OutputStream output = new OutputStream(1, Framing.Priority.Pri1, queue);
                FrameReader reader = new FrameReader(transport, false, CancellationToken.None);

                int dataLength = 0x1FFFF; // More than the 0x10000 default
                Task writeTask = output.WriteAsync(new byte[dataLength], 0, dataLength);
                Assert.False(writeTask.IsCompleted);

                Frame frame = reader.ReadFrameAsync().Result;
                Assert.False(frame.IsControl);
                Assert.Equal(0x10000, frame.FrameLength);

                Task<Frame> nextFrameTask = reader.ReadFrameAsync();
                Assert.False(nextFrameTask.IsCompleted);

                // Free up some space
                output.AddFlowControlCredit(10);

                frame = nextFrameTask.Result;
                Assert.False(frame.IsControl);
                Assert.Equal(10, frame.FrameLength);

                nextFrameTask = reader.ReadFrameAsync();
                Assert.False(nextFrameTask.IsCompleted);
            }
        }
        public void WriteMultipleData_OneFramePerWrite()
        {
            using (Stream transport = new QueueStream())
            using (WriteQueue queue = new WriteQueue(transport))
            {
                Task pumpTask = queue.PumpToStreamAsync();
                Stream output = new OutputStream(1, Framing.Priority.Pri1, queue);
                FrameReader reader = new FrameReader(transport, false, CancellationToken.None);

                int dataLength = 100;
                output.Write(new byte[dataLength], 0, dataLength);
                output.Write(new byte[dataLength * 2], 0, dataLength * 2);
                output.Write(new byte[dataLength * 3], 0, dataLength * 3);

                Frame frame = reader.ReadFrameAsync().Result;
                Assert.False(frame.IsControl);
                Assert.Equal(dataLength, frame.FrameLength);

                frame = reader.ReadFrameAsync().Result;
                Assert.False(frame.IsControl);
                Assert.Equal(dataLength * 2, frame.FrameLength);

                frame = reader.ReadFrameAsync().Result;
                Assert.False(frame.IsControl);
                Assert.Equal(dataLength * 3, frame.FrameLength);
            }
        }
        public void StreamException_AfterSendingHeaders_Reset()
        {
            MemoryStream rawStream = new MemoryStream();
            WriteQueue writeQueue = new WriteQueue(rawStream);
            HeaderWriter headerWriter = new HeaderWriter(writeQueue);
            Task pumpTask = writeQueue.PumpToStreamAsync();
            Http2ServerStream stream = new Http2ServerStream(1, new TransportInformation(), CreateEnvironment(), writeQueue, headerWriter, CancellationToken.None);
            Task task = stream.Run(env =>
            {
                new OwinResponse(env).Write("Hello World");
                throw new NotImplementedException();
            });
            Assert.True(task.IsCompleted);
            Assert.False(task.IsFaulted);
            writeQueue.FlushAsync(Priority.Pri7).Wait();

            rawStream.Seek(0, SeekOrigin.Begin);
            FrameReader reader = new FrameReader(rawStream, true, CancellationToken.None);

            SynReplyFrame reply = (SynReplyFrame)reader.ReadFrameAsync().Result;
            var headers = FrameHelpers.DeserializeHeaderBlock(new CompressionProcessor().Decompress(reply.CompressedHeaders));
            Assert.Equal(2, headers.Count);
            Assert.Equal(":status", headers[0].Key);
            Assert.Equal("200 OK", headers[0].Value);
            Assert.False(reply.IsFin);

            DataFrame data = (DataFrame)reader.ReadFrameAsync().Result;
            Assert.Equal("Hello World", FrameHelpers.GetAsciiAt(data.Data));

            RstStreamFrame reset = (RstStreamFrame)reader.ReadFrameAsync().Result;
            Assert.Equal(ResetStatusCode.InternalError, reset.StatusCode);
        }
        public void CancelRequestAfterReceivingHeaders_ResetSent()
        {
            MemoryStream rawStream = new MemoryStream();
            WriteQueue writeQueue = new WriteQueue(rawStream);
            HeaderWriter headerWriter = new HeaderWriter(writeQueue);
            Task pumpTask = writeQueue.PumpToStreamAsync();
            CancellationTokenSource cts = new CancellationTokenSource();
            Http2ClientStream clientStream = new Http2ClientStream(1, Priority.Pri3, writeQueue, headerWriter, cts.Token);
            clientStream.StartRequest(GenerateHeaders(), 0, false);
            Task<IList<KeyValuePair<string, string>>> responseTask = clientStream.GetResponseAsync();
            writeQueue.FlushAsync(Priority.Pri7).Wait();

            clientStream.SetReply(GenerateHeaders(), false);

            var response = responseTask.Result;

            cts.Cancel();
            writeQueue.FlushAsync(Priority.Pri7).Wait();

            rawStream.Seek(0, SeekOrigin.Begin);
            FrameReader reader = new FrameReader(rawStream, true, CancellationToken.None);

            SynStreamFrame synFrame = (SynStreamFrame)reader.ReadFrameAsync().Result;
            Assert.True(synFrame.IsFin);

            RstStreamFrame rstFrame = (RstStreamFrame)reader.ReadFrameAsync().Result;
            Assert.Equal(ResetStatusCode.Cancel, rstFrame.StatusCode);
        }
        public void StreamException_BeforeSendingHeaders_500Response()
        {
            MemoryStream rawStream = new MemoryStream();
            WriteQueue writeQueue = new WriteQueue(rawStream);
            HeaderWriter headerWriter = new HeaderWriter(writeQueue);
            Task pumpTask = writeQueue.PumpToStreamAsync();
            Http2ServerStream stream = new Http2ServerStream(1, new TransportInformation(), CreateEnvironment(), writeQueue, headerWriter, CancellationToken.None);
            Task task = stream.Run(env => { throw new NotImplementedException(); });
            Assert.True(task.IsCompleted);
            Assert.False(task.IsFaulted);
            writeQueue.FlushAsync(Priority.Pri7).Wait();

            rawStream.Seek(0, SeekOrigin.Begin);
            FrameReader reader = new FrameReader(rawStream, true, CancellationToken.None);
            Frame frame = reader.ReadFrameAsync().Result;
            Assert.True(frame.IsControl);
            ControlFrame controlFrame = (ControlFrame)frame;
            Assert.Equal(ControlFrameType.SynReply, controlFrame.FrameType);
            SynReplyFrame reply = (SynReplyFrame)controlFrame;
            CompressionProcessor compresser = new CompressionProcessor();
            var headers = FrameHelpers.DeserializeHeaderBlock(compresser.Decompress(reply.CompressedHeaders));
            Assert.Equal(2, headers.Count);
            Assert.Equal(":status", headers[0].Key);
            Assert.Equal("500 Internal Server Error", headers[0].Value);
            Assert.True(reply.IsFin);
        }