public void SendGoAway() { _frameInboundWriter.WriteInboundHeaders(3, _request, 31, false); IHttp2Stream stream = _frameCodec.Connection.Stream(3); Assert.NotNull(stream); Assert.Equal(Http2StreamState.Open, stream.State); IByteBuffer debugData = Http2TestUtil.BB("debug"); IByteBuffer expected = debugData.Copy(); IHttp2GoAwayFrame goAwayFrame = new DefaultHttp2GoAwayFrame(Http2Error.NoError, debugData.RetainedDuplicate()); goAwayFrame.ExtraStreamIds = 2; _channel.WriteOutbound(goAwayFrame); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx), It.Is <int>(v => v == 7), It.Is <Http2Error>(v => v == Http2Error.NoError), It.Is <IByteBuffer>(v => v.Equals(expected)), It.IsAny <IPromise>())); Assert.Equal(Http2StreamState.Open, stream.State); Assert.True(_channel.IsActive); expected.Release(); debugData.Release(); }
public void CanSendGoAwayUsingVoidPromise() { _handler = NewHandler(); IByteBuffer data = DummyData(); var errorCode = Http2Error.InternalError; _handler = NewHandler(); var cause = new Http2RuntimeException("fake exception"); _frameWriter .Setup(x => x.WriteGoAwayAsync( It.IsAny <IChannelHandlerContext>(), It.IsAny <int>(), It.IsAny <Http2Error>(), It.IsAny <IByteBuffer>(), It.IsAny <IPromise>() )) .Returns <IChannelHandlerContext, int, Http2Error, IByteBuffer, IPromise>((c, id, err, buf, p) => { Assert.False(p.IsVoid); // This is what DefaultHttp2FrameWriter does... I hate mocking :-(. var aggregatedPromise = new SimplePromiseAggregator(p); aggregatedPromise.NewPromise(); aggregatedPromise.DoneAllocatingPromises(); aggregatedPromise.SetException(cause); return(aggregatedPromise.Task); }); _handler.GoAwayAsync(_ctx.Object, STREAM_ID, errorCode, data, Http2TestUtil.NewVoidPromise(_channel.Object)); _pipeline.Verify(x => x.FireExceptionCaught(It.Is <Exception>(v => ReferenceEquals(v, cause)))); }
public void GoAwayLastStreamIdOverflowed() { _frameInboundWriter.WriteInboundHeaders(5, _request, 31, false); IHttp2Stream stream = _frameCodec.Connection.Stream(5); Assert.NotNull(stream); Assert.Equal(Http2StreamState.Open, stream.State); var debugData = Http2TestUtil.BB("debug"); IHttp2GoAwayFrame goAwayFrame = new DefaultHttp2GoAwayFrame(Http2Error.NoError, debugData.RetainedDuplicate()); goAwayFrame.ExtraStreamIds = int.MaxValue; _channel.WriteOutbound(goAwayFrame); // When the last stream id computation overflows, the last stream id should just be set to 2^31 - 1. _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx), It.Is <int>(v => v == int.MaxValue), It.Is <Http2Error>(v => v == Http2Error.NoError), It.Is <IByteBuffer>(v => v.Equals(debugData)), It.IsAny <IPromise>())); debugData.Release(); Assert.Equal(Http2StreamState.Open, stream.State); Assert.True(_channel.IsActive); }
public async Task GzipEncodingMultipleMessages() { string text1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc"; string text2 = "dddddddddddddddddddeeeeeeeeeeeeeeeeeeeffffffffffffffffffff"; var data1 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text1)); var data2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2)); await this.BootstrapEnv(data1.ReadableBytes + data2.ReadableBytes); try { IHttp2Headers headers = new DefaultHttp2Headers() { Method = POST, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data1.Retain(), 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data2.Retain(), 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); Assert.Equal(text1 + text2, Encoding.UTF8.GetString(this.serverOut.ToArray())); } finally { data1.Release(); data2.Release(); } }
public async Task JustHeadersNoData() { await this.BootstrapEnv(0); IHttp2Headers headers = new DefaultHttp2Headers() { Method = GET, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); this.serverListener.Verify( x => x.OnHeadersRead( It.IsAny <IChannelHandlerContext>(), It.Is <int>(v => v == 3), It.Is <IHttp2Headers>(v => v.Equals(headers)), It.Is <int>(v => v == 0), It.Is <short>(v => v == Http2CodecUtil.DefaultPriorityWeight), It.Is <bool>(v => v == false), It.Is <int>(v => v == 0), It.Is <bool>(v => v == true))); }
public void GzipEncodingSingleEmptyMessage() { string text = ""; var data = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); this.BootstrapEnv(data.ReadableBytes); try { IHttp2Headers headers = new DefaultHttp2Headers() { Method = POST, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data.Retain(), 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); Assert.Equal(text, Encoding.UTF8.GetString(this.serverOut.ToArray())); } finally { data.Release(); } }
public async Task DeflateEncodingWriteLargeMessage() { int BUFFER_SIZE = 1 << 12; byte[] bytes = new byte[BUFFER_SIZE]; new Random().NextBytes(bytes); await this.BootstrapEnv(BUFFER_SIZE); var data = Unpooled.WrappedBuffer(bytes); try { IHttp2Headers headers = new DefaultHttp2Headers() { Method = POST, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data.Retain(), 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); Assert.Equal(data.ResetReaderIndex().ToString(Encoding.UTF8), Encoding.UTF8.GetString(this.serverOut.ToArray())); } finally { data.Release(); } }
private static IHttp2Headers BinaryHeaders() { DefaultHttp2Headers headers = new DefaultHttp2Headers(false); for (int ix = 0; ix < 10; ++ix) { headers.Add(Http2TestUtil.RandomString(), Http2TestUtil.RandomString()); } return(headers); }
public void TestExceedHeaderSize() { int maxListSize = 100; decoder.Configuration.SetMaxHeaderListSize(maxListSize, maxListSize); var buf = Encode(Http2TestUtil.RandomBytes(maxListSize), Http2TestUtil.RandomBytes(1)); Assert.Throws <Http2Exception>(() => decoder.DecodeHeaders(0, buf)); buf.Release(); }
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 ReceiveGoaway() { IByteBuffer debugData = Http2TestUtil.BB("foo"); _frameInboundWriter.WriteInboundGoAway(2, Http2Error.NoError, debugData); IHttp2GoAwayFrame expectedFrame = new DefaultHttp2GoAwayFrame(2, Http2Error.NoError, Http2TestUtil.BB("foo")); IHttp2GoAwayFrame actualFrame = _inboundHandler.ReadInbound <IHttp2GoAwayFrame>(); Http2TestUtil.AssertEqualsAndRelease(expectedFrame, actualFrame); Assert.Null(_inboundHandler.ReadInbound()); }
private static IHttp2Headers Headers() { var headers = new DefaultHttp2Headers(false); headers.Method = AsciiString.Of("GET"); headers.Scheme = AsciiString.Of("https"); headers.Authority = AsciiString.Of("example.org"); headers.Path = AsciiString.Of("/some/path/resource2"); headers.Add(Http2TestUtil.RandomString(), Http2TestUtil.RandomString()); return(headers); }
private static IByteBuffer Encode(params byte[][] entries) { HpackEncoder hpackEncoder = Http2TestUtil.NewTestEncoder(); var output = Unpooled.Buffer(); var http2Headers = new DefaultHttp2Headers(false); for (int ix = 0; ix < entries.Length;) { http2Headers.Add(new AsciiString(entries[ix++], false), new AsciiString(entries[ix++], false)); } hpackEncoder.EncodeHeaders(3 /* randomly chosen */, output, http2Headers, NeverSensitiveDetector.Instance); return(output); }
public void DecodeShouldSucceed() { var buf = Encode(B(":method"), B("GET"), B("akey"), B("avalue"), Http2TestUtil.RandomBytes(), Http2TestUtil.RandomBytes()); try { var headers = decoder.DecodeHeaders(0, buf); Assert.Equal(3, headers.Size); Assert.Equal("GET", headers.Method); Assert.Equal("avalue", headers.Get(new AsciiString("akey"), null)); } finally { buf.Release(); } }
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()); }
private void SetUp(Http2FrameCodecBuilder frameCodecBuilder, Http2Settings initialRemoteSettings) { // Some tests call this method twice. Once with JUnit's @Before and once directly to pass special settings. // This call ensures that in case of two consecutive calls to setUp(), the previous channel is shutdown and // ByteBufs are released correctly. Dispose0(); _frameWriter = Http2TestUtil.MockedFrameWriter(); var builder = frameCodecBuilder.FrameWriter(_frameWriter.Object); builder.FrameLogger = new Http2FrameLogger(Common.Internal.Logging.InternalLogLevel.TRACE); builder.InitialSettings = initialRemoteSettings; _frameCodec = frameCodecBuilder.Build(); _inboundHandler = new LastInboundHandler(); _channel = new EmbeddedChannel(); _frameInboundWriter = new Http2FrameInboundWriter(_channel); //channel.Connect(new InetSocketAddress(0)); _channel.Pipeline.AddLast(_frameCodec); _channel.Pipeline.AddLast(_inboundHandler); _channel.Pipeline.FireChannelActive(); // Handshake _frameWriter.Verify( x => x.WriteSettingsAsync( It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx), It.IsAny <Http2Settings>(), It.IsAny <IPromise>())); _frameWriter.VerifyNoOtherCalls(); _channel.WriteInbound(Http2CodecUtil.ConnectionPrefaceBuf()); _frameInboundWriter.WriteInboundSettings(initialRemoteSettings); _frameWriter.Verify( x => x.WriteSettingsAckAsync( It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx), It.IsAny <IPromise>())); _frameInboundWriter.WriteInboundSettingsAck(); var settingsFrame = _inboundHandler.ReadInbound <IHttp2SettingsFrame>(); Assert.NotNull(settingsFrame); var settingsAckFrame = _inboundHandler.ReadInbound <IHttp2SettingsAckFrame>(); Assert.NotNull(settingsAckFrame); }
private static IHttp2Headers Headers() { var headers = new DefaultHttp2Headers(false); headers.Method = new AsciiString("GET"); headers.Scheme = new AsciiString("https"); headers.Authority = new AsciiString("example.org"); headers.Path = new AsciiString("/some/path/resource2"); headers.Add(new AsciiString("accept"), new AsciiString("image/png")); headers.Add(new AsciiString("cache-control"), new AsciiString("no-cache")); headers.Add(new AsciiString("custom"), new AsciiString("value1")); headers.Add(new AsciiString("custom"), new AsciiString("value2")); headers.Add(new AsciiString("custom"), new AsciiString("value3")); headers.Add(new AsciiString("custom"), new AsciiString("custom4")); headers.Add(Http2TestUtil.RandomString(), Http2TestUtil.RandomString()); return(headers); }
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(); } }
private HpackEncoder CreateEncoder() { int maxHeaderTableSize = this.maxHeaderTableSize; if (maxHeaderTableSize == -1) { maxHeaderTableSize = int.MaxValue; } try { return(Http2TestUtil.NewTestEncoder(true, Http2CodecUtil.MaxHeaderListSize, maxHeaderTableSize)); } catch (Http2Exception e) { throw new Exception("invalid initial values!", e); } }
public void UpgradeWithoutFlowControlling() { _channel.Pipeline.AddAfter(_frameCodec._ctx.Name, null, new TestUpgradeChannelHandler()); _frameInboundWriter.WriteInboundHeaders(Http2CodecUtil.HttpUpgradeStreamId, _request, 31, false); string longString = "*".PadRight(70000, '*'); DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/", Http2TestUtil.BB(longString)); var constructors = typeof(HttpServerUpgradeHandler.UpgradeEvent).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var upgradeEvent = (HttpServerUpgradeHandler.UpgradeEvent)constructors[0].Invoke(new object[] { (AsciiString)"HTTP/2", request }); _channel.Pipeline.FireUserEventTriggered(upgradeEvent); }
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 ClientRequestSingleHeaderNonAsciiShouldThrow() { this.BootstrapEnv(1, 1, 1); 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(new AsciiString(Encoding.UTF8.GetBytes("çã"), true), new AsciiString(Encoding.UTF8.GetBytes("Ãã"), true)); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitResponses(); Assert.True(Http2Exception.IsStreamError(this.clientException)); }
private void WriteRstStreamUsingVoidPromise(int streamId) { _handler = NewHandler(); var cause = new Http2RuntimeException("fake exception"); _stream.Setup(x => x.Id).Returns(STREAM_ID); _frameWriter .Setup(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == streamId), It.IsAny <Http2Error>(), It.IsAny <IPromise>())) .Returns <IChannelHandlerContext, int, Http2Error, IPromise>((ctx, id, err, p) => { Assert.False(p.IsVoid); p.SetException(cause); return(p.Task); }); _handler.ResetStreamAsync(_ctx.Object, streamId, Http2Error.StreamClosed, Http2TestUtil.NewVoidPromise(_channel.Object)); _frameWriter.Verify( x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == streamId), It.IsAny <Http2Error>(), It.IsAny <IPromise>())); _pipeline.Verify(x => x.FireExceptionCaught(It.Is <Exception>(v => ReferenceEquals(v, cause)))); }
public DefaultHttp2HeadersEncoderTest() { encoder = new DefaultHttp2HeadersEncoder(NeverSensitiveDetector.Instance, Http2TestUtil.NewTestEncoder()); }
public Http2FrameRoundtripTest() { this.alloc = new Mock <IByteBufferAllocator>(); this.alloc.Setup(x => x.Buffer()).Returns(() => Unpooled.Buffer()); this.alloc.Setup(x => x.Buffer(It.IsAny <int>())).Returns <int>(c => Unpooled.Buffer(c)); this.channel = new Mock <IChannel>(); this.executor = new Mock <IEventExecutor>(); this.listener = new Mock <IHttp2FrameListener>(); this.ctx = new Mock <IChannelHandlerContext>(); this.ctx.Setup(x => x.Allocator).Returns(this.alloc.Object); this.ctx.Setup(x => x.Executor).Returns(this.executor.Object); this.ctx.Setup(x => x.Channel).Returns(this.channel.Object); this.ctx.Setup(x => x.NewPromise()).Returns(() => new DefaultPromise()); this.writer = new DefaultHttp2FrameWriter(new DefaultHttp2HeadersEncoder(NeverSensitiveDetector.Instance, Http2TestUtil.NewTestEncoder())); this.reader = new DefaultHttp2FrameReader(new DefaultHttp2HeadersDecoder(false, Http2TestUtil.NewTestDecoder())); }
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 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(); } }
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); }