Reverse Proxy Using Jetty/Undertow

Reverse Proxy Using Jetty/Undertow

Undertow is an extremely lightweight flexible performant web server written in java, providing both blocking and non-blocking API’s based on NIO.

Jetty is another lightweight embeddable web server and servlet container.

Any of these servers can be embedded in your java application easily. Both these servers provide proxy implementation which you can use to build a reverse proxy pretty easily.

For example, a website abc-website.com can also be made available on a different server on a specific port. This stackoverflow answer provides a good explanation of the differences between  forward and reverse proxies.

As explained in Undertow documentation, two proxy clients are provided:

A sample implementation is as shown below:

ProxyClient proxyClientProvider = new SimpleProxyClientProvider(URI.create(getHost()));
final HttpHandler handler = new ProxyHandler(proxyClientProvider, 30000, ResponseCodeHandler.HANDLE_404);
   Undertow server = Undertow.builder()
    .addHttpListener(getPort(),"localhost")
    .setHandler(new HttpHandler() {
      @Override
      public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
        httpServerExchange.setRelativePath(httpServerExchange.getRequestPath());
        handler.handleRequest(httpServerExchange);
      }
   }).build();
   server.start();

Jetty provides a ProxyServlet to achieve a similar result. Sample implementation follows:

Server server = new Server(getPort());
ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
contextHandler.setContextPath("/");
server.setHandler(contextHandler);
contextHandler.addServlet(new ServletHolder(new ProxyServlet(){
    @Override
    protected URI rewriteURI(HttpServletRequest request) {
    return URI.create(getHost()+request.getRequestURI());
   }
}), "/*");
server.start();
server.join();

Maven dependencies are as below:

<!--Jetty-->
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-proxy</artifactId>
  <version>9.3.0.M1</version>
</dependency>
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-servlet</artifactId>
  <version>9.3.0.M1</version>
</dependency>
<!--Undertow-->
<dependency>
  <groupId>io.undertow</groupId>
  <artifactId>undertow-core</artifactId>
  <version>1.3.18.Final</version>
</dependency>

These are very simple implementations as they rely on updating the url paths only. This wont work with most websites that check the header information also, but the above methods can be modified to work with most sites.

A working application that uses Jetty/Undertow servers can be found in github.

Leave a Reply

Your email address will not be published. Required fields are marked *