14755

Simple way to use Netty to build an http proxy server?

Question:

I'm new to Netty, and am looking at using it to make a simple http proxy server that receives requests from a client, forwards the requests to another server, and then copies the response back to the response for the original request. One extra requirement is that I be able to support a timeout, so that if the proxied server takes too long to respond the proxy will respond by itself and close the connection to the proxied server.

I've already implemented such an application using Jetty, but with Jetty I need to use too many threads to keep inbound requests from getting blocked (this is a lightweight app that uses very little memory or cpu, but the latency of the proxied server is high enough that bursts in traffic cause either queueing in the proxy server, or require too many threads).

According to my understanding, I can use Netty to build a pipeline in which each stage performs a small amount of computation, then releases it's thread and waits until 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? What I have so far is a simple modification of the server code for the basic Netty tutorial, but it lacks all support for a client. I saw the netty client tutorial, but am not sure how to mix code from the two to create a simple proxy app.

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(); } }

Answer1:

you would have to look at <a href="http://www.littleshoot.org/littleproxy/" rel="nofollow">LittleProxy</a> to see how they did it as it is written on top of Netty.

Recommend

  • “Invalid use of aggregating function in this context” in a SET query (Neo4j)
  • In Swift, how do I animate a UIView with auto-layout like a page sliding in?
  • Cannot Update WPF GUI While Using Unmanaged Libraries In Background
  • spring autoconfiguration class is missing in META-INF/spring.factories
  • Reading from JSON API with C# in SSIS
  • Generate all unique combinations from a vector with repeating elements
  • Can I host (self host) a WCF Service in a Windows Service and expose it via http?
  • Azure DocumentDB Owner resource does not exist
  • syntaxError: 'continue' not properly in loop
  • Is there a Python library to list primes?
  • Documenting Macro Functions in C++ with Doxygen
  • Take picture automatically with no user interaction [closed]
  • Problem with time() function in embedded application with C
  • How to create drop down menu [closed]
  • Make a timer reset every 30 days?
  • ExecutionContext is null to non-function methods via IoC, alternative to ExecutionContext.FunctionAp
  • Bluetooth Low Energy device scanning Failed with an exception
  • HUAWEI kill a background app when the phone is locked
  • Merge objects on shared Key Value Pair with Lodash
  • Erlang record expression ignored warning
  • How can I get a spring JdbcTemplate to read_uncommitted?
  • Rotating only the MapView's content
  • Model binding not working with Stream type parameter in asp.net core webapi controller action method
  • Why context.Wait in StartAsync didn't stop the dialog
  • Quartz clustering load balancing algorithm internal implementation in Jdbcjobstore
  • Activate UISearchBar when the controller is loaded
  • Is there way to structure a QueryExpression so that you could dynamically handle a unknown number of
  • Button On Click event not firing
  • typescript multidimensional array with different types
  • Null Space Binary Matrix : Java
  • remove date from DateTimePicker for Compact Framework
  • ggplot2 facet_grid with distinct x-axis labels using facet_grid
  • watir webdriver - window not found
  • How to put an object in the air?
  • Bison does not appear to recognize C string literals appropriately
  • UIScrollView does not restore properly
  • Adding native code to an existing Worklight hybrid app
  • view details for exception in vs 2017
  • how to read to huge file into buffer
  • Android Library Projects on Windows and Mac