netty выбрасывает исключение «Не удалось пометить обещание как успех» при выполнении clientRequest - PullRequest
0 голосов
/ 21 мая 2019

У меня есть прокси-сервер netty, который работает и работает.Как только netty получает httpRequest, он выполняет следующие действия:

1) Метод MainHandler # channelRead создает объект FullHttpRequest, который передается другому методу.В этом методе я клонирую объект fullHttpRequest, изменяю содержимое (тело запроса), создаю клиентский bootStrap с SubHandler и делаю запрос с измененным объектом на удаленный сервер.
После завершения этой обработки я позволил исходному объекту запроса выполнитьпрокси на удаленный сервер.То, что я наблюдаю, если я закомментировал invokeAndParseClient (который является клиентской загрузкой), прокси работает нормально.Если у меня есть invokeAndParseClient, я получаю сообщение об ошибке (трассировка стека ниже)

ПРИМЕЧАНИЕ: исключение выдается из proxyRequest и НЕ invokeAndParseClient.

Вот действующий код

class MainHandler extends ChannelDuplexHandler {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    if (msg instanceof HttpRequest) {
        FullHttpRequest request = (FullHttpRequest) msg;
        invokeAndParseClient(request);
        proxyRequest(ctx, request);
        }
}


public void invokeAndParseClient(FullHttpRequest request) {
    FullHttpRequest dup = req.duplicate();
     ByteBuf content = dup.content().copy();
    String newContent = modifiedContent(content); //modifies content to String, do some String replacments
    ByteBuf buf = Unpooled.wrappedBuffer(newContent.getBytes(Charset.forName("UTF-8")));
    dup.replace(buf); //replace content on the request
    BootStrap b = new Bootstrap()
                .group(bossGroup())
                .channel(NioSocketChannel.class)
                .handler(new RemoteChannelInitializer());
                Channel ch = bootstrap.connect(remoteSocketAddress).sync().channel();
                ChannelFuture f = ch.writeAndFlush(clonedReq);
                //need to close channel. but have to figure out when

}

public class RemoteChannelInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    public void initChannel(SocketChannel ch) {
        ChannelPipeline p = ch.pipeline();
        p.addLast(new LoggingHandler(LogLevel.INFO));
        p.addLast(new HttpClientCodec());
        p.addLast(new HttpObjectAggregator(1024 * 1024, true));
        p.addLast(new ClientHandler()));
    }
}


public class ClientHandler extends ChannelInboundHandlerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientRequestHandler.class);

    @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) {
        LOGGER.info("here you gooooo");

        if (msg instanceof FullHttpResponse) {
            LOGGER.info("this is fullHttpResponse");
            FullHttpResponse full = (FullHttpResponse) msg;
            FullHttpResponse dup = full.copy();
            LOGGER.info("response code ===> " + full.status());
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
    }

С этим кодом я получаю следующее исключение.но как только я закомментирую invokeAndParseClient (запрос), он работает нормально.в чем здесь проблема?

2019-05-21 16:08:59.524  WARN 45091 --- [tLoopGroup-3-25] io.netty.channel.ChannelOutboundBuffer   : Failed to mark a promise as success because it has failed already: DefaultChannelPromise@2e4d789f(failure: io.netty.handler.codec.EncoderException: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1), unnotified cause:

io.netty.handler.codec.EncoderException: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:106) ~[netty-codec-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.write(CombinedChannelDuplexHandler.java:348) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:801) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:837) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1071) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at com.example.MainHandler.proxyRequest(ClientRequestHandler.java:178) ~[classes/:na]
...