在netty 4中记录HTTP请求

时间:2018-06-19 13:05:59

标签: netty

我正在构建一个Netty代理服务器来查询Opentsdb,类似这样:https://github.com/AllenDevelop/Netty-proxy

效果很好。但是出于调试目的,我添加了一段代码来记录接收和发送的http请求,而问题是当我这样做时,Opentsdb不会向我发送回响应。

我添加的代码和原始代码在一起是这样的(我提取了添加为logMessage方法的代码)(该代码也不起作用)

public class NettyProxyServerHandler extends ChannelInboundHandlerAdapter {

private String remoteHost = "192.168.235.138";
private int remotePort = 4399;

private Channel outBoundChannel;

public NettyProxyServerHandler() {
    super();
}
public NettyProxyServerHandler(String remoteHost, int remotePort) {
    super();
    this.remoteHost = remoteHost;
    this.remotePort = remotePort;
}

@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
    if(outBoundChannel==null || !ctx.channel().isActive()) {
        /* 创建netty client,连接到远程地址 */
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(ctx.channel().eventLoop())
                 .channel(ctx.channel().getClass())
                 .handler(new ChannelInitializer<SocketChannel>(){
                    @Override
                    protected void initChannel(SocketChannel ch)
                            throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast("codec", new HttpClientCodec());
                        pipeline.addLast("aggregator", new HttpObjectAggregator(1048576));
                        pipeline.addLast(new NettyProxyClientHandler(ctx.channel()));
                    }});
        ChannelFuture future = bootstrap.connect(remoteHost,remotePort);
        outBoundChannel = future.channel();

        /* channel建立成功后,将请求发送给远程主机 */
        future.addListener(new ChannelFutureListener(){
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    //this is what I added
                    logMessage((FullHttpRequest) msg);
                    future.channel().writeAndFlush(msg);
                } else {
                    future.channel().close();
                }
            }

        });
    } else {
        //this is what I added
        logMessage((FullHttpRequest) msg);
        outBoundChannel.writeAndFlush(msg);
    }
}

//I added this method.
private void logMessage(FullHttpRequest msg){
    ByteBuf m = msg.content();
    StringBuilder sb = new StringBuilder();
    while (m.isReadable()) {
        sb.append((char) m.readByte());
    }
    String content = sb.toString();
    StringBuilder sblog = new StringBuilder();
    sblog.append("msg:\n").append(msg.getMethod() + " " + msg.getUri() + " " + msg.getProtocolVersion() + "\n");
    for (Map.Entry<String, String> entry : msg.headers().entries()) {
        sblog.append(entry.getKey() + ": " + entry.getValue() + "\n");
    }
    sblog.append("\n").append(content);
    System.out.println(sblog.toString());
}

任何想法为何以及在netty中记录http请求和响应的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

发现出了什么问题。我在logMessage方法中使用了readByte()方法,该方法将更改消息的ByteBuf的readerIndex,这意味着减少了消息的实际内容。如果我改用ByteBuf.toString(Charset)(此方法不会更改readerIndex),则会得到服务器响应,如下所示:

String content = null;
    if(msg.content().isReadable()) {
        content = msg.content().toString(Charset.forName("UTF-8"));
    }