Forward http message as is

rzo rzo at gmx.de
Fri Jan 8 18:25:29 EST 2010


Hello,

I tried a few times to create an entry on the jboss wiki.
But it hangs every time I click the create new entry.

I am therefore including it here:


      Netty Example: implementing a simple WAF (Web Application Firewall)


This example shows how to implement a simple WAF (Web Application 
Firewall <http://de.wikipedia.org/wiki/Web_Application_Firewall>) using 
netty.
For this we create a proxy server which receives the http requests. If 
  the request is ok, the "bytes"
received are forwarded to the web server.

As starting point we use the HexDumpProxy example which comes with the 
netty distribution.
We adapt the PipelineFactory from the example by adding the 
InterceptStart, HttpDecoder and InterceptStop handlers.

public class WafPipelineFactory implements ChannelPipelineFactory {

     private final ClientSocketChannelFactory cf;

     private final String remoteHost;

     private final int remotePort;


     public WafPipelineFactory(ClientSocketChannelFactory cf, String 
remoteHost, int remotePort) {

         this.cf = cf;

         this.remoteHost = remoteHost;

         this.remotePort = remotePort;

     }

         public ChannelPipeline getPipeline() throws Exception {

             ChannelPipeline pipeline = pipeline();

* pipeline.addLast("interceptStart", new InterceptStart());*

* pipeline.addLast("decoder", new HttpRequestDecoder());*

*             pipeline.addLast("aggregator", new 
HttpChunkAggregator(1048576));*

*              pipeline.addLast("interceptStop", new InterceptStop());*

             pipeline.addLast("handler", new 
HexDumpProxyInboundHandler(cf, remoteHost, remotePort));


             return pipeline;

         }

}


InterceptStart intercepts all incoming messages and makes a copy into a 
local buffer

public class InterceptStart extends SimpleChannelUpstreamHandler {


     ChannelBuffer buf = null;

     @Override

      public void messageReceived(ChannelHandlerContext ctx, 
MessageEvent evt) throws Exception

      {

          ChannelBuffer m = (ChannelBuffer) evt.getMessage();

          ChannelBuffer buf = (ChannelBuffer) ctx.getAttachment();

          if (buf == null)

          {

              // if this is a new connection create a new buffer and 
attach it to the context

              buf = dynamicBuffer();

              ctx.setAttachment(buf);

          }

          // copy the incoming bytes to the buffer

          m.markReaderIndex();

          buf.writeBytes(m);

          m.resetReaderIndex();

          // send the buffer further upstream to the HttpDecoder

          super.messageReceived(ctx, evt);

         }

}


InterceptStop receives the http request, analyzes it, and if ok gets the 
copy buffer from InterceptStart and forwards it to the http proxy

public class InterceptStop extends SimpleChannelUpstreamHandler {


             @Override

              public void messageReceived(ChannelHandlerContext ctx, 
MessageEvent evt) {

                  if (evt.getMessage() != null)

                  {

                      HttpRequest request = (HttpRequest) evt.getMessage();

                      // make sure that the http request is complete
                     // this may not be necessary ??

                     if (request.getContentLength() == 0 || 
request.getContentLength() == request.getContent().writerIndex())

                      {

                      ChannelBuffer buf = (ChannelBuffer) 
ctx.getPipeline().getContext("interceptStart").getAttachment();

                     if (buf == null)

                      {

                          System.out.println("this should not happen");

                      }

                      else if (buf.writerIndex() != 0)

                      {

                            // check the request

                           if ( ! wafCheck(request))

                           {

                                     // bad request -> close the channel

                                    cts.getChannel.close();

                                    return;

                             }

                            // request is ok, remove the copy the 
interceptor

                          
  ctx.getPipeline().getContext("interceptStart").setAttachment(null);

                           // forward the buffer to the proxy

                           ctx.sendUpstream(new 
UpstreamMessageEvent(evt.getChannel(), buf, evt.getRemoteAddress()));

                      }

                      }


                  }

                 }

}


To check the http request one may use the OWASP Stinger Project 
<http://www.owasp.org/index.php/Category:OWASP_Stinger_Project> or a 
similar framework.
Since these frameworks generally analyze a HttpServletRequest 
<http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html> 
we need an adapter <http://en.wikipedia.org/wiki/Adapter_pattern> to 
adapt to the netty HttpRequest.
Implementing the adapter is straight forward.




-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/netty-users/attachments/20100109/50995231/attachment-0001.html 


More information about the netty-users mailing list