使用Netty作为基本的透明HTTP代理

使用Netty作为基本的透明HTTP代理,netty,Netty,我需要实现一个充当透明HTTP代理的服务,它需要执行以下操作: 接收HTTP请求TLS已经被终止,所以我们这里只讨论普通HTTP 向请求添加标题 以非阻塞方式将修改后的请求转发到其预期目的地 保存/保留请求以备日后使用 当响应返回时,将其返回给调用者。 将存储在4中的响应和请求打包,并以非阻塞方式将它们发送到另一个系统。 阅读了Netty文档后,我成功地将一些非常原始的东西放在一起,它接受来自客户端的HTTP请求并返回HTTP响应,这在单个服务器管道中使用了以下Netty组件: HttpServ

我需要实现一个充当透明HTTP代理的服务,它需要执行以下操作:

接收HTTP请求TLS已经被终止,所以我们这里只讨论普通HTTP 向请求添加标题 以非阻塞方式将修改后的请求转发到其预期目的地 保存/保留请求以备日后使用 当响应返回时,将其返回给调用者。 将存储在4中的响应和请求打包,并以非阻塞方式将它们发送到另一个系统。 阅读了Netty文档后,我成功地将一些非常原始的东西放在一起,它接受来自客户端的HTTP请求并返回HTTP响应,这在单个服务器管道中使用了以下Netty组件:

HttpServerCodec HttpObjectAggregator 我编写的一个处理程序,它扩展了ChannelInboundHandlerAdapter,如下所示:

void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
    try {
        FullHttpRequest httpRequest = (FullHttpRequest) msg
        ensureAuditingHeaderIsPresent(httpRequest)
        ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK))
        println("Response written...")
    }
    finally {
        ReferenceCountUtil.release(msg)
    }
}```
这一切都如我所期望的那样工作,结果是一个200响应返回到客户端,尽管是一个空响应。然而,我很难理解我现在可能采取什么样的方法来实现HTTP请求的转发和向客户端返回响应

我最初的想法是使用一个异步HTTP客户端库,但我感觉我缺少了Netty内置的东西,它可以让我在管道中完成这项工作?也许是某种出站通道OutboundHandlerAdapter

正如你可以告诉我的,我目前对Netty内部的理解是非常基本的,所以感谢你的指点

最后一个问题:2015年netty in action的书还值得一读吗?我不愿意买它,如果它将完全过时,但它仍然相关,那么可能值得一读

非常感谢,


Edd

您需要两条管道-一条用于服务器端(也称为传入通道),另一条用于客户端(称为传出通道),通向目标服务器。从传入通道的处理程序接收到请求后,您将希望启动到目标服务器的新连接,并传递a根据需要修改的HTTP请求和b对传入通道上下文的引用。从目标服务器、传出通道处理程序接收到响应后,只需将根据需要修改的响应写回传入通道。不需要外部库

一个非常简化的伪代码示例为您指明了正确的方向:

您的服务器端处理程序看起来像:

void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
    try {
        FullHttpRequest httpRequest = (FullHttpRequest) msg;
        ensureAuditingHeaderIsPresent(httpRequest);
        Bootstrap b = new Bootstrap();
        b.group(eventLoopGroup) // use the same eventLoopGroup as the server's
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new HttpClientCodec())
                                     .addLast(new HttpObjectAggregator())
                                     .addLast(new MyProxyOutgoingChannelHandler(httpRequest.copy(), ctx));
                    }
                });
        String targetHost = getTargetHostFromRequest(httpRequest);
        int targetPort = getTargetPortFromRequest(httpRequest);
        b.connect(targetHost, targetPort);
    }
    finally {
        ReferenceCountUtil.release(msg);
    }
}
Re:Netty在行动中,我自己没有读过,但作者Norman Maurer仍然是项目负责人,我毫不怀疑书中的概念仍然相关,即使代码示例可能已经过时

希望有帮助

class MyProxyOutgoingChannelHandler extends SimpleChannelInboundHandler {

    private final ChannelHandlerContext incomingChannelCtx;
    private final HttpRequest httpRequest;

    void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
        FullHttpResponse response = (FullHttpResponse) msg;
        incomingChannelCtx.writeAndFlush(response);
    }

    @Override
    void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.write(httpRequest);
    }