【问题标题】:How to configure a netty pipeline for a http proxy如何为 http 代理配置 netty 管道
【发布时间】:2015-10-17 17:40:18
【问题描述】:

我使用 Netty 编写了一个小型 http 代理,它已经运行了一段时间。今天我开始在来自单个客户端的日志文件中收到奇怪的异常:

java.lang.UnsupportedOperationException: unsupported message type: DefaultFullHttpResponse (expected: ByteBuf, FileRegion)
    at io.netty.channel.nio.AbstractNioByteChannel.filterOutboundMessage(AbstractNioByteChannel.java:276) ~[netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:654) ~[netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1054) ~[netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:651) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.handler.logging.LoggingHandler.write(LoggingHandler.java:289) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:706) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:741) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.handler.codec.http.HttpObjectAggregator.decode(HttpObjectAggregator.java:131) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.handler.codec.http.HttpObjectAggregator.decode(HttpObjectAggregator.java:54) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:163) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:283) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:130) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) [netty-all-4.0.23.Final.jar:4.0.23.Final]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]

查找源代码似乎在发送100 Continue 状态以响应POST 请求时出现问题(HttpObjectAggregator 第 130-139 行)

if (is100ContinueExpected(m)) {
    ctx.writeAndFlush(CONTINUE).addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) 
                throws Exception {
            if (!future.isSuccess()) {
                ctx.fireExceptionCaught(future.cause());
            }
        }
    });
}

确实,导致问题的客户端似乎是唯一一个与请求一起发送Expect: 100-continue 标头的客户端。这让我觉得我的处理程序管道可能设置错误:

p.addLast(new LoggingHandler(LogLevel.DEBUG));
p.addLast(new HttpRequestDecoder());
p.addLast(new HttpObjectAggregator(MAX_CONTENT_LENGTH));
p.addLast(new HttpResponseEncoder());
p.addLast(new MyHandler(...));

HttpObjectAggregator 的 API 文档声明

请注意,您需要在 ChannelPipeline 中的 HttpObjectAggregator 之前有 HttpResponseEncoder 或 HttpRequestEncoder。

所以我认为HttpRequestDecoderHttpResponseEncoder 应该在管道中的HttpObjectAggregator 之前。会不会是我的问题?

【问题讨论】:

  • 您是否尝试更改顺序(聚合器是您的 MyHandler 之前的最后一个)?
  • 做到了。如果您添加答案,我会接受。

标签: java http netty http-proxy


【解决方案1】:

您是否尝试更改顺序(聚合器是您的 MyHandler 之前的最后一个)?

【讨论】:

    猜你喜欢
    • 2019-09-20
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    相关资源
    最近更新 更多