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 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); }
public void CancelRequestAfterReceivingFin_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(), true); 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); // TODO: Should we send a reset after sending and receiving a fin? // Because the write queue gets purged, we're not positive our fin got sent. RstStreamFrame rstFrame = (RstStreamFrame)reader.ReadFrameAsync().Result; Assert.Equal(ResetStatusCode.Cancel, rstFrame.StatusCode); }
public void CancelRequestAfterSendingHeaders_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 responseTask = clientStream.GetResponseAsync(); writeQueue.FlushAsync(Priority.Pri7).Wait(); cts.Cancel(); Assert.True(responseTask.IsCanceled); 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); }
protected Http2BaseStream(int id, WriteQueue writeQueue, HeaderWriter headerWriter, CancellationToken cancel) { _id = id; _writeQueue = writeQueue; _cancel = cancel; _headerWriter = headerWriter; }
public Http2ClientStream(int id, Priority priority, WriteQueue writeQueue, HeaderWriter headerWriter, CancellationToken cancel) : base(id, writeQueue, headerWriter, cancel) { _priority = priority; _responseTask = new TaskCompletionSource<IList<KeyValuePair<string, string>>>(); _outputStream = new OutputStream(id, _priority, writeQueue); _cancellation = _cancel.Register(Cancel, this); }