public void MultipleWritesToActiveStream() { _encoder.WriteSettingsAckAsync(_ctx.Object, NewPromise()); EncoderWriteHeaders(3, NewPromise()); Assert.Equal(0, _encoder.NumBufferedStreams()); var data = Data(); int expectedBytes = data.ReadableBytes * 3; _encoder.WriteDataAsync(_ctx.Object, 3, data, 0, false, NewPromise()); _encoder.WriteDataAsync(_ctx.Object, 3, Data(), 0, false, NewPromise()); _encoder.WriteDataAsync(_ctx.Object, 3, Data(), 0, false, NewPromise()); EncoderWriteHeaders(3, NewPromise()); WriteVerifyWriteHeaders(Times.Exactly(2), 3); // Contiguous data writes are coalesced var bufCaptor = new ArgumentCaptor <IByteBuffer>(); _writer.Verify( x => x.WriteDataAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == 3), It.Is <IByteBuffer>(v => bufCaptor.Capture(v)), It.Is <int>(v => v == 0), It.Is <bool>(v => v == false), It.IsAny <IPromise>()), Times.Once); Assert.Equal(expectedBytes, bufCaptor.GetValue().ReadableBytes); }
public void LargeDataFrameShouldMatch() { // Create a large message to force chunking. var originalData = Data(1024 * 1024); int originalPadding = 100; var endOfStream = true; writer.WriteDataAsync(this.ctx.Object, STREAM_ID, originalData.Slice(), originalPadding, endOfStream, this.ctx.Object.NewPromise()); this.ReadFrames(); // Verify that at least one frame was sent with eos=false and exactly one with eos=true. this.listener.Verify( x => x.OnDataRead( It.Is <IChannelHandlerContext>(c => c == this.ctx.Object), It.Is <int>(id => id == STREAM_ID), It.IsAny <IByteBuffer>(), It.IsAny <int>(), It.Is <bool>(v => v == false)), Times.AtLeastOnce()); this.listener.Verify( x => x.OnDataRead( It.Is <IChannelHandlerContext>(c => c == this.ctx.Object), It.Is <int>(id => id == STREAM_ID), It.IsAny <IByteBuffer>(), It.IsAny <int>(), It.Is <bool>(v => v == true))); // Capture the read data and padding. var dataCaptor = new ArgumentCaptor <IByteBuffer>(); var paddingCaptor = new ArgumentCaptor <int>(); this.listener.Verify( x => x.OnDataRead( It.Is <IChannelHandlerContext>(c => c == this.ctx.Object), It.Is <int>(id => id == STREAM_ID), It.Is <IByteBuffer>(d => dataCaptor.Capture(d)), It.Is <int>(v => paddingCaptor.Capture(v)), It.IsAny <bool>()), Times.AtLeastOnce()); // Make sure the data matches the original. foreach (var chunk in dataCaptor.GetAllValues()) { var originalChunk = originalData.ReadSlice(chunk.ReadableBytes); Assert.Equal(originalChunk, chunk); } Assert.False(originalData.IsReadable()); // Make sure the padding matches the original. int totalReadPadding = 0; foreach (int framePadding in paddingCaptor.GetAllValues()) { totalReadPadding += framePadding; } Assert.Equal(originalPadding, totalReadPadding); }
private int CaptureWrite(int streamId) { var captor = new ArgumentCaptor <int>(); this.writer.Verify( x => x.Write( It.Is <IHttp2Stream>(v => ReferenceEquals(v, this.Stream(streamId))), It.Is <int>(v => captor.Capture(v)))); return(captor.GetValue()); }
public void ClientRequestStreamDependencyInHttpMessageFlow() { this.BootstrapEnv(1, 2, 1); string text = "hello world big time data!"; IByteBuffer content = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); string text2 = "hello world big time data...number 2!!"; IByteBuffer content2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2)); IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put, "/some/path/resource", content, true); IFullHttpMessage request2 = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put, "/some/path/resource2", content2, true); try { HttpHeaders httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); HttpHeaders httpHeaders2 = request2.Headers; httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 5); httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamDependencyId, 3); httpHeaders2.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 123); httpHeaders2.SetInt(HttpHeaderNames.ContentLength, text2.Length); var http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("PUT"), Path = new AsciiString("/some/path/resource"), }; var http2Headers2 = new DefaultHttp2Headers() { Method = new AsciiString("PUT"), Path = new AsciiString("/some/path/resource2"), }; Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient()); this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 5, http2Headers2, 3, 123, true, 0, false, this.NewPromiseClient()); this.clientChannel.Flush(); // Headers are queued in the flow controller and so flush them. this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, content.RetainedDuplicate(), 0, true, this.NewPromiseClient()); this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 5, content2.RetainedDuplicate(), 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var httpObjectCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => httpObjectCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2)); this.capturedRequests = httpObjectCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); Assert.Equal(request2, this.capturedRequests[1]); } finally { request.Release(); request2.Release(); } }
public void PingAckFrameShouldMatch() { writer.WritePingAsync(this.ctx.Object, true, 1234567, this.ctx.Object.NewPromise()); this.ReadFrames(); var captor = new ArgumentCaptor <long>(); this.listener.Verify( x => x.OnPingAckRead( It.Is <IChannelHandlerContext>(c => c == this.ctx.Object), It.Is <long>(v => captor.Capture(v)))); Assert.Equal(1234567, captor.GetValue()); }
private IByteBuffer CaptureWrites() { var captor = new ArgumentCaptor <IByteBuffer>(); this.ctx.Verify(x => x.WriteAsync(It.Is <IByteBuffer>(t => captor.Capture(t)), It.IsAny <IPromise>()), Times.AtLeastOnce()); var composite = (CompositeByteBuffer)this.ReleaseLater(Unpooled.CompositeBuffer()); foreach (var item in captor.GetAllValues()) { var buf = this.ReleaseLater((IByteBuffer)item.Retain()); composite.AddComponent(true, buf); } return(composite); }
public void PropagateSettings() { this.BootstrapEnv(1, 1, 2); Http2Settings settings = new Http2Settings().PushEnabled(true); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteSettingsAsync(this.CtxClient(), settings, this.NewPromiseClient()); this.clientChannel.Flush(); }); Assert.True(this.settingsLatch.Wait(TimeSpan.FromSeconds(5))); var settingsCaptor = new ArgumentCaptor <Http2Settings>(); this.settingsListener.Verify(x => x.MessageReceived(It.Is <Http2Settings>(v => settingsCaptor.Capture(v))), Times.Exactly(2)); Assert.Equal(settings, settingsCaptor.GetValue()); }
public void ServerReceivingInvalidClientPrefaceStringShouldHandleException() { _connection.Setup(x => x.IsServer).Returns(true); _handler = NewHandler(); _handler.ChannelRead(_ctx.Object, Unpooled.CopiedBuffer("BAD_PREFACE", Encoding.UTF8)); var captor = new ArgumentCaptor <IByteBuffer>(); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == 0), It.Is <Http2Error>(v => v == Http2Error.ProtocolError), It.Is <IByteBuffer>(v => captor.Capture(v)), It.Is <IPromise>(v => v == _promise))); Assert.Equal(0, captor.GetValue().ReferenceCount); }
public void ServerReceivingHttp1ClientPrefaceStringShouldIncludePreface() { _connection.Setup(x => x.IsServer).Returns(true); _handler = NewHandler(); _handler.ChannelRead(_ctx.Object, Unpooled.CopiedBuffer("GET /path HTTP/1.1", Encoding.ASCII)); var captor = new ArgumentCaptor <IByteBuffer>(); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == 0), It.Is <Http2Error>(v => v == Http2Error.ProtocolError), It.Is <IByteBuffer>(v => captor.Capture(v)), It.Is <IPromise>(v => v == _promise))); Assert.Equal(0, captor.GetValue().ReferenceCount); Assert.Contains("/path", _goAwayDebugCap); }
private int CaptureWrites(IHttp2Stream stream) { var captor = new ArgumentCaptor <int>(); this.writer.Verify( x => x.Write( It.Is <IHttp2Stream>(v => ReferenceEquals(v, stream)), It.Is <int>(v => captor.Capture(v))), Times.AtLeastOnce()); int total = 0; foreach (var x in captor.GetAllValues()) { total += x; } return(total); }
public void ClientRequestTrailingHeaders() { this.BootstrapEnv(1, 1, 1); string text = "some data"; IByteBuffer content = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get, "/some/path/resource2", content, true); try { HttpHeaders httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); HttpHeaders trailingHeaders = request.TrailingHeaders; trailingHeaders.Set(AsciiString.Of("Foo"), AsciiString.Of("goo")); trailingHeaders.Set(AsciiString.Of("fOo2"), AsciiString.Of("goo2")); trailingHeaders.Add(AsciiString.Of("foO2"), AsciiString.Of("goo3")); var http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("GET"), Path = new AsciiString("/some/path/resource2"), }; IHttp2Headers http2Headers2 = new DefaultHttp2Headers(); http2Headers2.Set(new AsciiString("foo"), new AsciiString("goo")); http2Headers2.Set(new AsciiString("foo2"), new AsciiString("goo2")); http2Headers2.Add(new AsciiString("foo2"), new AsciiString("goo3")); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient()); this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, content.RetainedDuplicate(), 0, false, this.NewPromiseClient()); this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers2, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v)))); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); } finally { request.Release(); } }
public void GoAwayFrameShouldMatch() { string text = "test"; var data = Buf(Encoding.UTF8.GetBytes(text)); writer.WriteGoAwayAsync(this.ctx.Object, STREAM_ID, ERROR_CODE, data.Slice(), this.ctx.Object.NewPromise()); this.ReadFrames(); var captor = new ArgumentCaptor <IByteBuffer>(); this.listener.Verify( x => x.OnGoAwayRead( It.Is <IChannelHandlerContext>(c => c == this.ctx.Object), It.Is <int>(id => id == STREAM_ID), It.Is <Http2Error>(v => v == ERROR_CODE), It.Is <IByteBuffer>(v => captor.Capture(v)))); Assert.Equal(data, captor.GetValue()); }
public void ServerShouldSend431OnHeaderSizeErrorWhenDecodingInitialHeaders() { int padding = 0; _handler = NewHandler(); Http2Exception e = new HeaderListSizeException(STREAM_ID, Http2Error.ProtocolError, "Header size exceeded max allowed size 8196", true); _stream.Setup(x => x.Id).Returns(STREAM_ID); _connection.Setup(x => x.IsServer).Returns(true); _stream.Setup(x => x.IsHeadersSent).Returns(false); _remote.Setup(x => x.LastStreamCreated).Returns(STREAM_ID); _frameWriter .Setup(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.Is <Http2Error>(v => v == Http2Error.ProtocolError), It.Is <IPromise>(v => v == _promise))) .Returns(_future); _handler.ExceptionCaught(_ctx.Object, e); var captor = new ArgumentCaptor <IHttp2Headers>(); _encoder.Verify( x => x.WriteHeadersAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.Is <IHttp2Headers>(v => captor.Capture(v)), It.Is <int>(v => v == padding), It.Is <bool>(v => v == true), It.Is <IPromise>(v => v == _promise))); IHttp2Headers headers = captor.GetValue(); Assert.Equal(HttpResponseStatus.RequestHeaderFieldsTooLarge.CodeAsText, headers.Status); _frameWriter.Verify( x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.Is <Http2Error>(v => v == Http2Error.ProtocolError), It.Is <IPromise>(v => v == _promise))); }
public void ClientRequestSingleHeaderCookieSplitIntoMultipleEntries() { this.BootstrapEnv(1, 1, 1); IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get, "/some/path/resource2", true); try { HttpHeaders httpHeaders = request.Headers; httpHeaders.Set(HttpConversionUtil.ExtensionHeaderNames.Scheme, "https"); httpHeaders.Set(HttpHeaderNames.Host, "example.org"); httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.Set(HttpHeaderNames.Cookie, "a=b; c=d; e=f"); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); var http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("GET"), Scheme = new AsciiString("https"), Authority = new AsciiString("example.org"), Path = new AsciiString("/some/path/resource2"), }; http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"a=b"); http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"c=d"); http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"e=f"); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v)))); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); } finally { request.Release(); } }
public void ServerReceivingClientPrefaceStringFollowedByNonSettingsShouldHandleException() { _connection.Setup(x => x.IsServer).Returns(true); _handler = NewHandler(); // Create a connection preface followed by a bunch of zeros (i.e. not a settings frame). IByteBuffer buf = Unpooled.Buffer().WriteBytes(Http2CodecUtil.ConnectionPrefaceBuf()).WriteZero(10); _handler.ChannelRead(_ctx.Object, buf); var captor = new ArgumentCaptor <IByteBuffer>(); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == 0), It.Is <Http2Error>(v => v == Http2Error.ProtocolError), It.Is <IByteBuffer>(v => captor.Capture(v)), It.Is <IPromise>(v => v == _promise)), Times.AtLeastOnce); Assert.Equal(0, captor.GetValue().ReferenceCount); }
public void ConnectionErrorShouldStartShutdown() { _handler = NewHandler(); Http2Exception e = new Http2Exception(Http2Error.ProtocolError); _remote.Setup(x => x.LastStreamCreated).Returns(STREAM_ID); _handler.ExceptionCaught(_ctx.Object, e); var captor = new ArgumentCaptor <IByteBuffer>(); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.Is <Http2Error>(v => v == Http2Error.ProtocolError), It.Is <IByteBuffer>(v => captor.Capture(v)), It.Is <IPromise>(v => v == _promise))); var buf = captor.GetValue(); Assert.Equal(0, buf.ReferenceCount); // netty future.addListener 只配置了 ChannelFutureListener 的监听,而且isDone返回的值为false // 所以 processGoAwayWriteResult 没有执行 //Assert.Equal(1, buf.ReferenceCount); //buf.Release(); }
public void ServerRequestPushPromise() { this.BootstrapEnv(1, 1, 1); string text = "hello world big time data!"; IByteBuffer content = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); string text2 = "hello world smaller data?"; IByteBuffer content2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2)); IFullHttpMessage response = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.OK, content, true); IFullHttpMessage response2 = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.Created, content2, true); IFullHttpMessage request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get, "/push/test", true); try { HttpHeaders httpHeaders = response.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); HttpHeaders httpHeaders2 = response2.Headers; httpHeaders2.Set(HttpConversionUtil.ExtensionHeaderNames.Scheme, "https"); httpHeaders2.Set(HttpHeaderNames.Host, "example.org"); httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 5); httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamDependencyId, 3); httpHeaders2.SetInt(HttpHeaderNames.ContentLength, text2.Length); httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); var http2Headers3 = new DefaultHttp2Headers() { Method = new AsciiString("GET"), Path = new AsciiString("/push/test"), }; Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers3, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v)))); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); IHttp2Headers http2Headers = new DefaultHttp2Headers() { Status = new AsciiString("200") }; // The PUSH_PROMISE frame includes a header block that contains a // complete set of request header fields that the server attributes to // the request. // https://tools.ietf.org/html/rfc7540#section-8.2.1 // Therefore, we should consider the case where there is no Http response status. IHttp2Headers http2Headers2 = new DefaultHttp2Headers() { Scheme = new AsciiString("https"), Authority = new AsciiString("example.org") }; Http2TestUtil.RunInChannel(this.serverConnectedChannel, () => { this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2Headers, 0, false, this.NewPromiseServer()); this.serverHandler.Encoder.WritePushPromiseAsync(this.CtxServer(), 3, 2, http2Headers2, 0, this.NewPromiseServer()); this.serverHandler.Encoder.WriteDataAsync(this.CtxServer(), 3, content.RetainedDuplicate(), 0, true, this.NewPromiseServer()); this.serverHandler.Encoder.WriteDataAsync(this.CtxServer(), 5, content2.RetainedDuplicate(), 0, true, this.NewPromiseServer()); this.serverConnectedChannel.Flush(); }); this.AwaitResponses(); var responseCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.clientListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => responseCaptor.Capture((IFullHttpMessage)v)))); this.capturedResponses = responseCaptor.GetAllValues(); Assert.Equal(response, this.capturedResponses[0]); } finally { request.Release(); response.Release(); response2.Release(); } }
public void EntityRequestEntityResponse() { _frameInboundWriter.WriteInboundHeaders(1, _request, 0, false); IHttp2Stream stream = _frameCodec.Connection.Stream(1); Assert.NotNull(stream); Assert.Equal(Http2StreamState.Open, stream.State); IHttp2HeadersFrame inboundHeaders = _inboundHandler.ReadInbound <IHttp2HeadersFrame>(); IHttp2FrameStream stream2 = inboundHeaders.Stream; Assert.NotNull(stream2); Assert.Equal(1, stream2.Id); Assert.Equal(new DefaultHttp2HeadersFrame(_request, false) { Stream = stream2 }, inboundHeaders); Assert.Null(_inboundHandler.ReadInbound()); IByteBuffer hello = Http2TestUtil.BB("hello"); _frameInboundWriter.WriteInboundData(1, hello, 31, true); IHttp2DataFrame inboundData = _inboundHandler.ReadInbound <IHttp2DataFrame>(); IHttp2DataFrame expected = new DefaultHttp2DataFrame(Http2TestUtil.BB("hello"), true, 31) { Stream = stream2 }; Http2TestUtil.AssertEqualsAndRelease(expected, inboundData); Assert.Null(_inboundHandler.ReadInbound()); _channel.WriteOutbound(new DefaultHttp2HeadersFrame(_response, false) { Stream = stream2 }); _frameWriter.Verify( x => x.WriteHeadersAsync( It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx), It.Is <int>(v => v == 1), It.Is <IHttp2Headers>(v => v.Equals(_response)), It.Is <int>(v => v == 0), It.Is <bool>(v => v == false), It.IsAny <IPromise>())); _channel.WriteOutbound(new DefaultHttp2DataFrame(Http2TestUtil.BB("world"), true, 27) { Stream = stream2 }); var outboundData = new ArgumentCaptor <IByteBuffer>(); _frameWriter.Verify( x => x.WriteDataAsync( It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx), It.Is <int>(v => v == 1), It.Is <IByteBuffer>(v => outboundData.Capture(v)), It.Is <int>(v => v == 27), It.Is <bool>(v => v == true), It.IsAny <IPromise>())); IByteBuffer bb = Http2TestUtil.BB("world"); Assert.Equal(bb, outboundData.GetValue()); Assert.Equal(1, outboundData.GetValue().ReferenceCount); bb.Release(); outboundData.GetValue().Release(); _frameWriter.Verify( x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx), It.IsAny <int>(), It.IsAny <Http2Error>(), It.IsAny <IPromise>()), Times.Never()); Assert.True(_channel.IsActive); }
public void ServerResponseHeaderInformational() { this.BootstrapEnv(1, 2, 1, 2, 1); IFullHttpMessage request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put, "/info/test", true); HttpHeaders httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.Set(HttpHeaderNames.Expect, HttpHeaderValues.Continue); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); IHttp2Headers http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("PUT"), Path = new AsciiString("/info/test") }; http2Headers.Set(new AsciiString(HttpHeaderNames.Expect.ToString()), new AsciiString(HttpHeaderValues.Continue.ToString())); IFullHttpMessage response = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.Continue); string text = "a big payload"; IByteBuffer payload = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); IFullHttpMessage request2 = (IFullHttpMessage)request.Replace(payload); IFullHttpMessage response2 = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.OK); try { Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); httpHeaders = response.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); IHttp2Headers http2HeadersResponse = new DefaultHttp2Headers() { Status = new AsciiString("100") }; Http2TestUtil.RunInChannel(this.serverConnectedChannel, () => { this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2HeadersResponse, 0, false, this.NewPromiseServer()); this.serverConnectedChannel.Flush(); }); this.AwaitResponses(); httpHeaders = request2.Headers; httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.Remove(HttpHeaderNames.Expect); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, payload.RetainedDuplicate(), 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests2(); httpHeaders = response2.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); IHttp2Headers http2HeadersResponse2 = new DefaultHttp2Headers() { Status = new AsciiString("200") }; Http2TestUtil.RunInChannel(this.serverConnectedChannel, () => { this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2HeadersResponse2, 0, true, this.NewPromiseServer()); this.serverConnectedChannel.Flush(); }); this.AwaitResponses2(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2)); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(2, this.capturedRequests.Count); // We do not expect to have this header in the captured request so remove it now. Assert.NotNull(request.Headers.Remove((AsciiString)"x-http2-stream-weight")); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); Assert.Equal(request2, this.capturedRequests[1]); var responseCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.clientListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => responseCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2)); this.capturedResponses = responseCaptor.GetAllValues(); Assert.Equal(2, this.capturedResponses.Count); Assert.Equal(response, this.capturedResponses[0]); Assert.Equal(response2, this.capturedResponses[1]); } finally { request.Release(); request2.Release(); response.Release(); response2.Release(); } }