Easy way to use Netty to create an HTTP proxy?

I'm new to Netty and consider it to create a simple HTTP proxy server that receives requests from a client, forwards requests to another server and then copies the response back to the response for the original request.One additional requirement is that I can support timeout, so if the proxy server takes too long to respond, the proxy server will itself respond and close the connection to the proxy server.

I have already implemented such an application using Jetty, but with Jetty I need to use too many threads to block incoming requests (this is a lightweight application that uses very little memory or processor, but the proxy server latency is high enough that traffic spikes cause either queue on the proxy server, or require too many threads).

In my opinion, I can use Netty to build a pipeline in which each stage performs a small amount of computation, then frees the stream and waits until the data is ready for the next stage in the pipeline to be executed.

My question is: is there a simple example of such an application? That I still represent a simple change of server code for the basic Netty tutorial, but it lacks all the support for the client. I saw a tutorial on the Netty client, but am not sure how to combine the code from the two to create a proxy application.

public static void main(String[] args) throws Exception {
    ChannelFactory factory =
            new NioServerSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());

    ServerBootstrap bootstrap = new ServerBootstrap(factory);

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            return Channels.pipeline(
                    new HttpRequestDecoder(),
                    new HttpResponseEncoder(),
                    /* 
                     * Is there something I can put here to make a
                     * request to another server asynchronously and
                     * copy the result to the response inside
                     * MySimpleChannelHandler?
                     */
                    new MySimpleChannelHandler()
                    );
        }
    });

    bootstrap.setOption("child.tcpNoDelay", true);
    bootstrap.setOption("child.keepAlive", true);

    bootstrap.bind(new InetSocketAddress(8080));
}

private static class MySimpleChannelHandler extends SimpleChannelHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
        HttpRequest request = (HttpRequest) e.getMessage();
        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.setContent(request.getContent());

        Channel ch = e.getChannel();
        ChannelFuture f = ch.write(response);
        f.addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture future) {
                Channel ch = future.getChannel();
                ch.close();
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        e.getCause().printStackTrace();

        Channel ch = e.getChannel();
        ch.close();
    }
}
+5
source share
1 answer

you need to look at LittleProxy to see how they did it, since it is written on top of Netty.

+4
source

All Articles