private void GracefulShutdownTimeoutWhenConnectionErrorTest0(ShutdownHint hint) { _handler = NewHandler(); long expectedMillis = 1234; _handler.GracefulShutdownTimeout = TimeSpan.FromMilliseconds(expectedMillis); Http2Exception exception = new Http2Exception(Http2Error.ProtocolError, "Test error", hint); _handler.OnConnectionError(_ctx.Object, false, exception, exception); if (hint == ShutdownHint.GracefulShutdown) { _executor.Verify( x => x.Schedule( It.IsAny <Action <object> >(), It.IsAny <object>(), It.Is <TimeSpan>(v => v == TimeSpan.FromMilliseconds(expectedMillis))), Times.AtLeastOnce()); } else { _executor.Verify( x => x.Schedule( It.IsAny <Action <object, object> >(), It.IsAny <object>(), It.IsAny <object>(), It.Is <TimeSpan>(v => v == TimeSpan.FromMilliseconds(expectedMillis))), Times.AtLeastOnce()); } }
private static void TestUpgrade(Http2ConnectionHandler handler, Http2MultiplexHandler multiplexer) { IFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Options, "*"); EmbeddedChannel channel = new EmbeddedChannel(new ChannelHandlerAdapter()); IChannelHandlerContext ctx = channel.Pipeline.FirstContext(); Http2ClientUpgradeCodec codec; if (multiplexer == null) { codec = new Http2ClientUpgradeCodec("connectionHandler", handler); } else { codec = new Http2ClientUpgradeCodec("connectionHandler", handler, multiplexer); } codec.SetUpgradeHeaders(ctx, request); // Flush the channel to ensure we write out all buffered data channel.Flush(); codec.UpgradeTo(ctx, null); Assert.NotNull(channel.Pipeline.Get("connectionHandler")); if (multiplexer != null) { Assert.NotNull(channel.Pipeline.Get <Http2MultiplexHandler>()); } Assert.True(channel.FinishAndReleaseAll()); }
public void VerifyChannelHandlerCanBeReusedInPipeline() { _connection.Setup(x => x.IsServer).Returns(true); _handler = NewHandler(); // Only read the connection preface...after preface is read internal state of Http2ConnectionHandler // is expected to change relative to the pipeline. IByteBuffer preface = Http2CodecUtil.ConnectionPrefaceBuf(); _handler.ChannelRead(_ctx.Object, preface); _decoder.Verify( x => x.DecodeFrame( It.IsAny <IChannelHandlerContext>(), It.IsAny <IByteBuffer>(), It.IsAny <List <object> >()), Times.Never()); // Now remove and add the this.handler...this is setting up the test condition. _handler.HandlerRemoved(_ctx.Object); _handler.HandlerAdded(_ctx.Object); // Now verify we can continue as normal, reading connection preface plus more. IByteBuffer prefacePlusSome = AddSettingsHeader(Unpooled.Buffer().WriteBytes(Http2CodecUtil.ConnectionPrefaceBuf())); _handler.ChannelRead(_ctx.Object, prefacePlusSome); _decoder.Verify( x => x.DecodeFrame( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.IsAny <IByteBuffer>(), It.IsAny <List <object> >()), Times.AtLeastOnce); }
public void CanSendGoAwayFramesWithDecreasingLastStreamIds() { _handler = NewHandler(); IByteBuffer data = DummyData(); var errorCode = Http2Error.InternalError; _handler.GoAwayAsync(_ctx.Object, STREAM_ID + 2, errorCode, (IByteBuffer)data.Retain(), _promise); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID + 2), It.Is <Http2Error>(v => v == errorCode), It.Is <IByteBuffer>(v => v.Equals(data)), It.Is <IPromise>(v => v == _promise))); _connection.Verify( x => x.GoAwaySent( It.Is <int>(v => v == STREAM_ID + 2), It.Is <Http2Error>(v => v == errorCode), It.Is <IByteBuffer>(v => v.Equals(data)))); _promise = new TaskCompletionSource(); _handler.GoAwayAsync(_ctx.Object, STREAM_ID, errorCode, data, _promise); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.Is <Http2Error>(v => v == errorCode), It.Is <IByteBuffer>(v => v.Equals(data)), It.Is <IPromise>(v => v == _promise))); _connection.Verify( x => x.GoAwaySent( It.Is <int>(v => v == STREAM_ID), It.Is <Http2Error>(v => v == errorCode), It.Is <IByteBuffer>(v => v.Equals(data)))); Assert.Equal(0, data.ReferenceCount); }
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 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 ChannelReadCompleteCallsReadWhenAutoReadFalse() { _channel.Object.Configuration.IsAutoRead = false; _handler = NewHandler(); _handler.ChannelReadComplete(_ctx.Object); _ctx.Verify(x => x.Read(), Times.Once()); }
public void ClientShouldveSentPrefaceAndSettingsFrameWhenUserEventIsTriggered() { _connection.Setup(x => x.IsServer).Returns(false); _channel.Setup(x => x.IsActive).Returns(false); _handler = NewHandler(); _channel.Setup(x => x.IsActive).Returns(true); var evt = Http2ConnectionPrefaceAndSettingsFrameWrittenEvent.Instance; AtomicBoolean verified = new AtomicBoolean(false); _ctx .Setup(x => x.FireUserEventTriggered(It.Is <object>(v => ReferenceEquals(v, evt)))) .Returns <object>(msg => { Assert.Same(msg, evt); _ctx.Verify(x => x.WriteAsync(It.Is <object>(d => Http2CodecUtil.ConnectionPrefaceBuf().Equals((IByteBuffer)d)))); _encoder.Verify( x => x.WriteSettingsAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.IsAny <Http2Settings>(), It.IsAny <IPromise>())); verified.Value = true; return(_ctx.Object); }); _handler.ChannelActive(_ctx.Object); Assert.True(verified.Value); }
public void PrefaceUserEventProcessed() { var latch = new CountdownEvent(1); _handler = new PrefaceUserEventHttp2ConnectionHandler(latch, _decoder.Object, _encoder.Object, new Http2Settings()); _handler.HandlerAdded(_ctx.Object); Assert.True(latch.Wait(TimeSpan.FromSeconds(5))); }
public void EncoderAndDecoderAreClosedOnChannelInactive() { _handler = NewHandler(); _handler.ChannelActive(_ctx.Object); _channel.Setup(x => x.IsActive).Returns(false); _handler.ChannelInactive(_ctx.Object); _encoder.Verify(x => x.Close()); _decoder.Verify(x => x.Close()); }
public void ServerShouldNotSendClientPrefaceStringWhenActive() { _connection.Setup(x => x.IsServer).Returns(true); _channel.Setup(x => x.IsActive).Returns(false); _handler = NewHandler(); _channel.Setup(x => x.IsActive).Returns(true); _handler.ChannelActive(_ctx.Object); _ctx.Verify(x => x.WriteAsync(It.Is <object>(d => Http2CodecUtil.ConnectionPrefaceBuf().Equals((IByteBuffer)d))), Times.Never()); }
public void OnHttpClientUpgradeWithoutHandlerAdded() { var b = new Http2ConnectionHandlerBuilder(); b.FrameListener = new Http2FrameAdapter(); b.IsServer = false; _handler = b.Build(); var e = Assert.Throws <Http2Exception>(() => _handler.OnHttpClientUpgrade()); Assert.Equal(Http2Error.InternalError, e.Error); }
public void GracefulShutdownIndefiniteTimeoutTest() { _handler = NewHandler(); _handler.GracefulShutdownTimeout = TimeSpan.FromMilliseconds(-1); _handler.Close(_ctx.Object, _promise); _executor.Verify( x => x.Schedule( It.IsAny <Action <object, object> >(), It.IsAny <object>(), It.IsAny <object>(), It.IsAny <TimeSpan>()), Times.Never()); }
public void WriteRstOnIdleStreamShouldNotWriteButStillSucceed() { _handler = NewHandler(); _stream.Setup(x => x.State).Returns(Http2StreamState.Idle); _handler.ResetStreamAsync(_ctx.Object, STREAM_ID, Http2Error.StreamClosed, _promise); _frameWriter .Verify(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.IsAny <Http2Error>(), It.IsAny <IPromise>()), Times.Never()); _stream.Verify(x => x.Close()); }
private static void TestUpgrade(Http2ConnectionHandler handler, IChannelHandler multiplexer) { IFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Options, "*"); request.Headers.Set(HttpHeaderNames.Host, "netty.io"); request.Headers.Set(HttpHeaderNames.Connection, "Upgrade, HTTP2-Settings"); request.Headers.Set(HttpHeaderNames.Upgrade, "h2c"); request.Headers.Set((AsciiString)"HTTP2-Settings", "AAMAAABkAAQAAP__"); var parent = new Mock <IServerChannel>(); EmbeddedChannel channel = new EmbeddedChannel(parent.Object, DefaultChannelId.NewInstance(), false, true, new ChannelHandlerAdapter()); IChannelHandlerContext ctx = channel.Pipeline.FirstContext(); Http2ServerUpgradeCodec codec; if (multiplexer == null) { codec = new Http2ServerUpgradeCodec(handler); } else { codec = new Http2ServerUpgradeCodec((Http2FrameCodec)handler, multiplexer); } Assert.True(codec.PrepareUpgradeResponse(ctx, request, new DefaultHttpHeaders())); codec.UpgradeTo(ctx, request); // Flush the channel to ensure we write out all buffered data channel.Flush(); channel.WriteInbound(Http2CodecUtil.ConnectionPrefaceBuf()); Http2FrameInboundWriter writer = new Http2FrameInboundWriter(channel); writer.WriteInboundSettings(new Http2Settings()); writer.WriteInboundRstStream(Http2CodecUtil.HttpUpgradeStreamId, Http2Error.Cancel); Assert.Same(handler, channel.Pipeline.Remove <Http2ConnectionHandler>()); Assert.Null(channel.Pipeline.Get <Http2ConnectionHandler>()); Assert.True(channel.Finish()); // Check that the preface was send (a.k.a the settings frame) var settingsBuffer = channel.ReadOutbound <IByteBuffer>(); Assert.NotNull(settingsBuffer); settingsBuffer.Release(); var buf = channel.ReadOutbound <IByteBuffer>(); Assert.NotNull(buf); buf.Release(); Assert.Null(channel.ReadOutbound()); }
public void ServerReceivingValidClientPrefaceStringShouldContinueReadingFrames() { _connection.Setup(x => x.IsServer).Returns(true); _handler = NewHandler(); IByteBuffer prefacePlusSome = AddSettingsHeader(Unpooled.Buffer().WriteBytes(Http2CodecUtil.ConnectionPrefaceBuf())); _handler.ChannelRead(_ctx.Object, prefacePlusSome); _decoder.Verify( x => x.DecodeFrame( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.IsAny <IByteBuffer>(), It.IsAny <List <object> >()), Times.AtLeastOnce); }
public void GracefulShutdownTimeoutTest() { _handler = NewHandler(); long expectedMillis = 1234; _handler.GracefulShutdownTimeout = TimeSpan.FromMilliseconds(expectedMillis); _handler.Close(_ctx.Object, _promise); _executor.Verify( x => x.Schedule( It.IsAny <Action <object> >(), It.IsAny <object>(), It.Is <TimeSpan>(v => v == TimeSpan.FromMilliseconds(expectedMillis))), Times.AtLeastOnce()); }
public void ServerShouldCreateStreamIfNeededBeforeSending431() { int padding = 0; _handler = NewHandler(); Http2Exception e = new HeaderListSizeException(STREAM_ID, Http2Error.ProtocolError, "Header size exceeded max allowed size 8196", true); _connection.Setup(x => x.Stream(It.Is <int>(v => v == STREAM_ID))).Returns(default(IHttp2Stream)); _remote .Setup(x => x.CreateStream( It.Is <int>(v => v == STREAM_ID), It.Is <bool>(v => v == true))) .Returns(_stream.Object); _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); _remote.Verify( x => x.CreateStream( It.Is <int>(v => v == STREAM_ID), It.Is <bool>(v => v == true))); _encoder.Verify( x => x.WriteHeadersAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.IsAny <IHttp2Headers>(), It.Is <int>(v => v == padding), It.Is <bool>(v => v == true), It.Is <IPromise>(v => v == _promise))); _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 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); }
public void WriteRstOnNonExistantStreamShouldSucceed() { _handler = NewHandler(); _frameWriter .Setup(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == NON_EXISTANT_STREAM_ID), It.Is <Http2Error>(v => v == Http2Error.StreamClosed), It.Is <IPromise>(v => v == _promise))) .Returns(_future); _handler.ResetStreamAsync(_ctx.Object, NON_EXISTANT_STREAM_ID, Http2Error.StreamClosed, _promise); _frameWriter .Verify(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == NON_EXISTANT_STREAM_ID), It.Is <Http2Error>(v => v == Http2Error.StreamClosed), It.Is <IPromise>(v => v == _promise))); }
protected virtual void SetInitialChannelPipeline(IChannel ch) { var p = ch.Pipeline; var connection = new DefaultHttp2Connection(false); this.clientHandler = new Http2ConnectionHandlerBuilder() { FrameListener = new InboundHttp2ToHttpAdapterBuilder(connection) { MaxContentLength = this.maxContentLength, }.Build(), Connection = connection, GracefulShutdownTimeout = TimeSpan.Zero }.Build(); p.AddLast(this.clientHandler); this.clientDelegator = new HttpResponseDelegator(this.clientListener.Object, this.clientLatch, this.clientLatch2); p.AddLast(this.clientDelegator); }
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 WriteMultipleRstFramesForSameStream() { _handler = NewHandler(); _stream.SetupGet(x => x.Id).Returns(STREAM_ID); AtomicBoolean resetSent = new AtomicBoolean(); _stream.Setup(x => x.ResetSent()).Returns(() => { resetSent.Value = true; return(_stream.Object); }); _stream.SetupGet(x => x.IsResetSent).Returns(() => resetSent.Value); _frameWriter .Setup(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.IsAny <Http2Error>(), It.IsAny <IPromise>())) .Returns <IChannelHandlerContext, int, Http2Error, IPromise>((ctx, id, err, p) => { p.TryComplete(); return(p.Task); }); var promise = new TaskCompletionSource(); var promise2 = new TaskCompletionSource(); promise.Task.ContinueWith(t => { _handler.ResetStreamAsync(_ctx.Object, STREAM_ID, Http2Error.StreamClosed, promise2); }, TaskContinuationOptions.ExecuteSynchronously); _handler.ResetStreamAsync(_ctx.Object, STREAM_ID, Http2Error.Cancel, promise); _frameWriter.Verify( x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.IsAny <Http2Error>(), It.IsAny <IPromise>())); Assert.True(promise.IsSuccess); Assert.True(promise2.IsSuccess); }
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 ChannelClosedDoesNotThrowPrefaceException() { _connection.Setup(x => x.IsServer).Returns(true); _handler = NewHandler(); _channel.Setup(x => x.IsActive).Returns(false); _handler.ChannelInactive(_ctx.Object); _frameWriter.Verify( x => x.WriteGoAwayAsync( It.IsAny <IChannelHandlerContext>(), It.IsAny <int>(), It.IsAny <Http2Error>(), It.IsAny <IByteBuffer>(), It.IsAny <IPromise>()), Times.Never()); _frameWriter.Verify( x => x.WriteRstStreamAsync( It.IsAny <IChannelHandlerContext>(), It.IsAny <int>(), It.IsAny <Http2Error>(), It.IsAny <IPromise>()), Times.Never()); }
public void CloseListenerShouldBeNotifiedOnlyOneTime() { _handler = NewHandler(); _future = TaskUtil.Completed; //doAnswer(new Answer<ChannelFuture>() { // @Override // public ChannelFuture answer(InvocationOnMock invocation) throws Throwable { // Object[] args = invocation.getArguments(); // GenericFutureListener<ChannelFuture> listener = (GenericFutureListener<ChannelFuture>) args[0]; // // Simulate that all streams have become inactive by the time the future completes. // doAnswer(new Answer<Http2Stream>() { // @Override // public Http2Stream answer(InvocationOnMock in) throws Throwable { // return null; // } // }).when(connection).forEachActiveStream(any(Http2StreamVisitor_class)); // when(connection.numActiveStreams()).thenReturn(0); // // Simulate the future being completed. // listener.operationComplete(future); // return future; // } //}).when(future).addListener(any(GenericFutureListener_class)); _handler.Close(_ctx.Object, _promise); _connection .Setup(x => x.ForEachActiveStream(It.IsAny <IHttp2StreamVisitor>())) .Returns(default(IHttp2Stream)); _connection .Setup(x => x.ForEachActiveStream(It.IsAny <Func <IHttp2Stream, bool> >())) .Returns(default(IHttp2Stream)); if (_future.IsCompleted) { _connection.Setup(x => x.NumActiveStreams).Returns(0); } _handler.CloseStream(_stream.Object, _future); // Simulate another stream close call being made after the context should already be closed. _handler.CloseStream(_stream.Object, _future); _ctx.Verify(x => x.CloseAsync(It.IsAny <IPromise>()), Times.Once); }
public void WriteRstOnClosedStreamShouldSucceed() { _handler = NewHandler(); _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 == STREAM_ID), It.IsAny <Http2Error>(), It.IsAny <IPromise>())) .Returns(_future); _stream.Setup(x => x.State).Returns(Http2StreamState.Closed); _stream.Setup(x => x.IsHeadersSent).Returns(true); // The stream is "closed" but is still known about by the connection (connection().stream(..) // will return the stream). We should still write a RST_STREAM frame in this scenario. _handler.ResetStreamAsync(_ctx.Object, STREAM_ID, Http2Error.StreamClosed, _promise); _frameWriter .Verify(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.IsAny <Http2Error>(), It.IsAny <IPromise>())); }
protected virtual void SetInitialChannelPipeline(IChannel ch) { var p = ch.Pipeline; IHttp2FrameWriter frameWriter = new DefaultHttp2FrameWriter(); this.clientConnection.Remote.FlowController = new DefaultHttp2RemoteFlowController(this.clientConnection); this.clientConnection.Local.FlowController = new DefaultHttp2LocalFlowController(this.clientConnection).FrameWriter(frameWriter); this.clientEncoder = new CompressorHttp2ConnectionEncoder( new DefaultHttp2ConnectionEncoder(this.clientConnection, frameWriter)); IHttp2ConnectionDecoder decoder = new DefaultHttp2ConnectionDecoder(this.clientConnection, this.clientEncoder, new DefaultHttp2FrameReader()); this.clientHandler = new Http2ConnectionHandlerBuilder() { FrameListener = new DelegatingDecompressorFrameListener(this.clientConnection, this.clientListener.Object), // By default tests don't wait for server to gracefully shutdown streams GracefulShutdownTimeout = TimeSpan.Zero } .Codec(decoder, this.clientEncoder).Build(); p.AddLast(this.clientHandler); }
protected virtual void SetInitialServerChannelPipeline(IChannel ch) { this.serverConnectedChannel = ch; var p = ch.Pipeline; var connection = new DefaultHttp2Connection(true); this.serverHandler = new Http2ConnectionHandlerBuilder() { FrameListener = new InboundHttp2ToHttpAdapterBuilder(connection) { MaxContentLength = this.maxContentLength, IsValidateHttpHeaders = true, IsPropagateSettings = true, }.Build(), Connection = connection, GracefulShutdownTimeout = TimeSpan.Zero }.Build(); p.AddLast(this.serverHandler); this.serverDelegator = new HttpResponseDelegator(this.serverListener.Object, this.serverLatch, this.serverLatch2); p.AddLast(this.serverDelegator); this.settingsDelegator = new HttpSettingsDelegator(this.settingsListener.Object, this.settingsLatch); p.AddLast(this.settingsDelegator); }