Search in sources :

Example 76 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project netty by netty.

the class DefaultHttp2ConnectionEncoder method writeHeaders.

@Override
public ChannelFuture writeHeaders(final ChannelHandlerContext ctx, final int streamId, final Http2Headers headers, final int streamDependency, final short weight, final boolean exclusive, final int padding, final boolean endOfStream, ChannelPromise promise) {
    try {
        Http2Stream stream = connection.stream(streamId);
        if (stream == null) {
            stream = connection.local().createStream(streamId, endOfStream);
        } else {
            switch(stream.state()) {
                case RESERVED_LOCAL:
                    stream.open(endOfStream);
                    break;
                case OPEN:
                case HALF_CLOSED_REMOTE:
                    // Allowed sending headers in these states.
                    break;
                default:
                    throw new IllegalStateException(String.format("Stream %d in unexpected state: %s", stream.id(), stream.state()));
            }
        }
        // Trailing headers must go through flow control if there are other frames queued in flow control
        // for this stream.
        Http2RemoteFlowController flowController = flowController();
        if (!endOfStream || !flowController.hasFlowControlled(stream)) {
            if (endOfStream) {
                final Http2Stream finalStream = stream;
                final ChannelFutureListener closeStreamLocalListener = new ChannelFutureListener() {

                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        lifecycleManager.closeStreamLocal(finalStream, future);
                    }
                };
                promise = promise.unvoid().addListener(closeStreamLocalListener);
            }
            ChannelFuture future = frameWriter.writeHeaders(ctx, streamId, headers, streamDependency, weight, exclusive, padding, endOfStream, promise);
            // Writing headers may fail during the encode state if they violate HPACK limits.
            Throwable failureCause = future.cause();
            if (failureCause == null) {
                // Synchronously set the headersSent flag to ensure that we do not subsequently write
                // other headers containing pseudo-header fields.
                stream.headersSent();
            } else {
                lifecycleManager.onError(ctx, failureCause);
            }
            return future;
        } else {
            // Pass headers to the flow-controller so it can maintain their sequence relative to DATA frames.
            flowController.addFlowControlled(stream, new FlowControlledHeaders(stream, headers, streamDependency, weight, exclusive, padding, true, promise));
            return promise;
        }
    } catch (Throwable t) {
        lifecycleManager.onError(ctx, t);
        promise.tryFailure(t);
        return promise;
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelFutureListener(io.netty.channel.ChannelFutureListener)

Example 77 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2ConnectionHandler method resetStream.

private ChannelFuture resetStream(final ChannelHandlerContext ctx, final Http2Stream stream, long errorCode, ChannelPromise promise) {
    promise = promise.unvoid();
    if (stream.isResetSent()) {
        // Don't write a RST_STREAM frame if we have already written one.
        return promise.setSuccess();
    }
    final ChannelFuture future;
    // https://tools.ietf.org/html/rfc7540#section-6.4.
    if (stream.state() == IDLE || connection().local().created(stream) && !stream.isHeadersSent() && !stream.isPushPromiseSent()) {
        future = promise.setSuccess();
    } else {
        future = frameWriter().writeRstStream(ctx, stream.id(), errorCode, promise);
    }
    // Synchronously set the resetSent flag to prevent any subsequent calls
    // from resulting in multiple reset frames being sent.
    stream.resetSent();
    if (future.isDone()) {
        processRstStreamWriteResult(ctx, stream, future);
    } else {
        future.addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                processRstStreamWriteResult(ctx, stream, future);
            }
        });
    }
    return future;
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelFutureListener(io.netty.channel.ChannelFutureListener) StreamException(io.netty.handler.codec.http2.Http2Exception.StreamException) Http2CodecUtil.getEmbeddedHttp2Exception(io.netty.handler.codec.http2.Http2CodecUtil.getEmbeddedHttp2Exception) CompositeStreamException(io.netty.handler.codec.http2.Http2Exception.CompositeStreamException)

Example 78 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2ConnectionRoundtripTest method http2ExceptionInPipelineShouldCloseConnection.

@Test
public void http2ExceptionInPipelineShouldCloseConnection() throws Exception {
    bootstrapEnv(1, 1, 2, 1);
    // Create a latch to track when the close occurs.
    final CountDownLatch closeLatch = new CountDownLatch(1);
    clientChannel.closeFuture().addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            closeLatch.countDown();
        }
    });
    // Create a single stream by sending a HEADERS frame to the server.
    final Http2Headers headers = dummyHeaders();
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, false, newPromise());
            http2Client.flush(ctx());
        }
    });
    // Wait for the server to create the stream.
    assertTrue(serverSettingsAckLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertTrue(requestLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    // Add a handler that will immediately throw an exception.
    clientChannel.pipeline().addFirst(new ChannelHandlerAdapter() {

        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            throw Http2Exception.connectionError(PROTOCOL_ERROR, "Fake Exception");
        }
    });
    // Wait for the close to occur.
    assertTrue(closeLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertFalse(clientChannel.isOpen());
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelHandlerAdapter(io.netty.channel.ChannelHandlerAdapter) Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Test(org.junit.Test)

Example 79 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2ConnectionRoundtripTest method nonHttp2ExceptionInPipelineShouldNotCloseConnection.

@Test
public void nonHttp2ExceptionInPipelineShouldNotCloseConnection() throws Exception {
    bootstrapEnv(1, 1, 2, 1);
    // Create a latch to track when the close occurs.
    final CountDownLatch closeLatch = new CountDownLatch(1);
    clientChannel.closeFuture().addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            closeLatch.countDown();
        }
    });
    // Create a single stream by sending a HEADERS frame to the server.
    final Http2Headers headers = dummyHeaders();
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, false, newPromise());
            http2Client.flush(ctx());
        }
    });
    // Wait for the server to create the stream.
    assertTrue(serverSettingsAckLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertTrue(requestLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    // Add a handler that will immediately throw an exception.
    clientChannel.pipeline().addFirst(new ChannelHandlerAdapter() {

        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            throw new RuntimeException("Fake Exception");
        }
    });
    // The close should NOT occur.
    assertFalse(closeLatch.await(2, SECONDS));
    assertTrue(clientChannel.isOpen());
    // Set the timeout very low because we know graceful shutdown won't complete
    http2Client.gracefulShutdownTimeoutMillis(0);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelHandlerAdapter(io.netty.channel.ChannelHandlerAdapter) Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Test(org.junit.Test)

Example 80 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2ConnectionHandlerTest method setup.

@SuppressWarnings("unchecked")
@Before
public void setup() throws Exception {
    MockitoAnnotations.initMocks(this);
    promise = new DefaultChannelPromise(channel, ImmediateEventExecutor.INSTANCE);
    voidPromise = new DefaultChannelPromise(channel, ImmediateEventExecutor.INSTANCE);
    Throwable fakeException = new RuntimeException("Fake exception");
    when(encoder.connection()).thenReturn(connection);
    when(decoder.connection()).thenReturn(connection);
    when(encoder.frameWriter()).thenReturn(frameWriter);
    when(encoder.flowController()).thenReturn(remoteFlow);
    when(decoder.flowController()).thenReturn(localFlow);
    doAnswer(new Answer<ChannelFuture>() {

        @Override
        public ChannelFuture answer(InvocationOnMock invocation) throws Throwable {
            ByteBuf buf = invocation.getArgument(3);
            goAwayDebugCap = buf.toString(UTF_8);
            buf.release();
            return future;
        }
    }).when(frameWriter).writeGoAway(any(ChannelHandlerContext.class), anyInt(), anyLong(), any(ByteBuf.class), any(ChannelPromise.class));
    doAnswer(new Answer<ChannelFuture>() {

        @Override
        public ChannelFuture answer(InvocationOnMock invocation) throws Throwable {
            Object o = invocation.getArguments()[0];
            if (o instanceof ChannelFutureListener) {
                ((ChannelFutureListener) o).operationComplete(future);
            }
            return future;
        }
    }).when(future).addListener(any(GenericFutureListener.class));
    when(future.cause()).thenReturn(fakeException);
    when(future.channel()).thenReturn(channel);
    when(channel.isActive()).thenReturn(true);
    when(channel.pipeline()).thenReturn(pipeline);
    when(connection.remote()).thenReturn(remote);
    when(remote.flowController()).thenReturn(remoteFlowController);
    when(connection.local()).thenReturn(local);
    when(local.flowController()).thenReturn(localFlowController);
    doAnswer(new Answer<Http2Stream>() {

        @Override
        public Http2Stream answer(InvocationOnMock in) throws Throwable {
            Http2StreamVisitor visitor = in.getArgument(0);
            if (!visitor.visit(stream)) {
                return stream;
            }
            return null;
        }
    }).when(connection).forEachActiveStream(any(Http2StreamVisitor.class));
    when(connection.stream(NON_EXISTANT_STREAM_ID)).thenReturn(null);
    when(connection.numActiveStreams()).thenReturn(1);
    when(connection.stream(STREAM_ID)).thenReturn(stream);
    when(stream.open(anyBoolean())).thenReturn(stream);
    when(encoder.writeSettings(eq(ctx), any(Http2Settings.class), eq(promise))).thenReturn(future);
    when(ctx.alloc()).thenReturn(UnpooledByteBufAllocator.DEFAULT);
    when(ctx.channel()).thenReturn(channel);
    when(ctx.newSucceededFuture()).thenReturn(future);
    when(ctx.newPromise()).thenReturn(promise);
    when(ctx.voidPromise()).thenReturn(voidPromise);
    when(ctx.write(any())).thenReturn(future);
    when(ctx.executor()).thenReturn(executor);
    doAnswer(new Answer() {

        @Override
        public Object answer(InvocationOnMock in) throws Throwable {
            Object msg = in.getArgument(0);
            ReferenceCountUtil.release(msg);
            return null;
        }
    }).when(ctx).fireChannelRead(any());
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelPromise(io.netty.channel.ChannelPromise) DefaultChannelPromise(io.netty.channel.DefaultChannelPromise) ByteBuf(io.netty.buffer.ByteBuf) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Answer(org.mockito.stubbing.Answer) DefaultChannelPromise(io.netty.channel.DefaultChannelPromise) InvocationOnMock(org.mockito.invocation.InvocationOnMock) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) Before(org.junit.Before)

Aggregations

ChannelFutureListener (io.netty.channel.ChannelFutureListener)92 ChannelFuture (io.netty.channel.ChannelFuture)87 Channel (io.netty.channel.Channel)29 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)24 Bootstrap (io.netty.bootstrap.Bootstrap)20 Test (org.junit.Test)19 ByteBuf (io.netty.buffer.ByteBuf)18 ClosedChannelException (java.nio.channels.ClosedChannelException)17 CountDownLatch (java.util.concurrent.CountDownLatch)16 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)15 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)15 IOException (java.io.IOException)12 ChannelPromise (io.netty.channel.ChannelPromise)11 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)11 ConnectException (java.net.ConnectException)11 InetSocketAddress (java.net.InetSocketAddress)8 AtomicReference (java.util.concurrent.atomic.AtomicReference)7 AbstractChannel (io.netty.channel.AbstractChannel)6 EventLoopGroup (io.netty.channel.EventLoopGroup)6 ChannelPipeline (io.netty.channel.ChannelPipeline)5