Hi Ron.<div>Do you have the complete source code for your example?</div><div><br></div><div>--<br clear="all">Leandro Rodrigo Saad Cruz<br>
<br><br><div class="gmail_quote">On Fri, Jan 8, 2010 at 9:25 PM, rzo <span dir="ltr">&lt;<a href="mailto:rzo@gmx.de">rzo@gmx.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">



  
  

<div bgcolor="#ffffff" text="#000000">
Hello,<br>
<br>
I tried a few times to create an entry on the jboss wiki.<br>
But it hangs every time I click the create new entry.<br>
<br>
I am therefore including it here:<br>
<br>
<h3>Netty Example: implementing a simple WAF (Web Application Firewall)</h3>
<br>
This example shows how to implement a simple WAF (<a href="http://de.wikipedia.org/wiki/Web_Application_Firewall" target="_blank">Web
Application Firewall</a>) using netty.<br>
For this we create a proxy server which receives the http requests. If
 the request is ok, the &quot;bytes&quot;<br>
received are forwarded to the web server.<br>
<br>
As starting point we use the <span style="font-weight:bold">HexDumpProxy</span>
example which comes with the netty distribution.<br>
We adapt the PipelineFactory from the example by adding the <span style="font-weight:bold">InterceptStart</span>, <span style="font-weight:bold">HttpDecoder</span> and <span style="font-weight:bold">InterceptStop</span> handlers.<br>

<br>
<address>
public class WafPipelineFactory implements ChannelPipelineFactory {</address>
<address>
    </address>
<address>
    private final ClientSocketChannelFactory cf;</address>
<address>
    private final String remoteHost;</address>
<address>
    private final int remotePort;</address>
<address><br>
    public WafPipelineFactory(ClientSocketChannelFactory cf, String
remoteHost, int remotePort) {</address>
<address>
        <a href="http://this.cf" target="_blank">this.cf</a> = cf;</address>
<address>
        this.remoteHost = remoteHost;</address>
<address>
        this.remotePort = remotePort;</address>
<address>
    }</address>
<address>
   </address>
<address>
        public ChannelPipeline getPipeline() throws Exception {</address>
<address>
            ChannelPipeline pipeline = pipeline();</address>
<address>
           <b> pipeline.addLast(&quot;interceptStart&quot;, new InterceptStart());</b></address>
<address>
           <b> pipeline.addLast(&quot;decoder&quot;, new HttpRequestDecoder());</b></address>
<address><b>
            pipeline.addLast(&quot;aggregator&quot;, new
HttpChunkAggregator(1048576));</b></address>
<address><b>
             pipeline.addLast(&quot;interceptStop&quot;, new InterceptStop());</b></address>
<address>
           
pipeline.addLast(&quot;handler&quot;, new HexDumpProxyInboundHandler(cf,
remoteHost, remotePort));</address>
<address><br>
            return pipeline;</address>
<address>
        }    </address>
<address>
}</address>
<br>
<span style="font-weight:bold">InterceptStart</span> intercepts all
incoming messages and makes a copy into a local buffer<br>
<br>
<address>
public class InterceptStart extends SimpleChannelUpstreamHandler {</address>
<address><br>
    ChannelBuffer buf = null;</address>
<address>
    </address>
<address>
    @Override</address>
<address>
     public void messageReceived(ChannelHandlerContext ctx,
MessageEvent evt) throws Exception</address>
<address>
     {</address>
<address>
         ChannelBuffer m = (ChannelBuffer) evt.getMessage();</address>
<address>
         ChannelBuffer buf = (ChannelBuffer) ctx.getAttachment();</address>
<address>
         if (buf == null)</address>
<address>
         {</address>
<address>
             // if this is a new connection create a new buffer and
attach it to the context</address>
<address>
             buf = dynamicBuffer();</address>
<address>
             ctx.setAttachment(buf);</address>
<address>
         }</address>
<address>
         // copy the incoming bytes to the buffer</address>
<address>
         m.markReaderIndex();</address>
<address>
         buf.writeBytes(m);</address>
<address>
         m.resetReaderIndex();</address>
<address>
         // send the buffer further upstream to the HttpDecoder</address>
<address>
         super.messageReceived(ctx, evt);</address>
<address>
        }</address>
<address>
}</address>
<br>
<span style="font-weight:bold">InterceptStop</span> receives the http
request, analyzes it, and if ok gets
the copy buffer from InterceptStart and forwards it to the http proxy<br>
<br>
<address>
public class InterceptStop extends SimpleChannelUpstreamHandler {</address>
<address><br>
            @Override</address>
<address>
             public
void messageReceived(ChannelHandlerContext ctx, MessageEvent evt) {</address>
<address>
                 if (evt.getMessage() != null)</address>
<address>
                 {</address>
<address>
           
         HttpRequest request =
(HttpRequest) evt.getMessage();</address>
<address>
                     // make sure that the http request is complete<br>
                    // this may not be necessary ??<br>
</address>
<address>
              
     if (request.getContentLength() == 0 ||
request.getContentLength() == request.getContent().writerIndex())</address>
<address>
                     {</address>
<address>
           
         ChannelBuffer buf =
(ChannelBuffer)
ctx.getPipeline().getContext(&quot;interceptStart&quot;).getAttachment();</address>
<address>
                    if (buf == null)</address>
<address>
                     {</address>
<address>
           
           
 System.out.println(&quot;this should not happen&quot;);</address>
<address>
                     }</address>
<address>
           
         else if (buf.writerIndex()
!= 0)</address>
<address>
                     {</address>
<address>
           
             
 // check the request</address>
<address>
                          if ( ! wafCheck(request))</address>
<address>
                          {</address>
<address>
           
           
            // bad request
-&gt; close the channel</address>
<address>
                   
             
 cts.getChannel.close();</address>
<address>
                   
               return;</address>
<address>
           
           
    }</address>
<address>
                   
       // request is ok, remove the copy the
interceptor</address>
<address>
            
           
 ctx.getPipeline().getContext(&quot;interceptStart&quot;).setAttachment(null);</address>
<address>
                          // forward the buffer to the proxy</address>
<address>
             
           
ctx.sendUpstream(new UpstreamMessageEvent(evt.getChannel(), buf,
evt.getRemoteAddress()));</address>
<address>
                     }</address>
<address>
                     }</address>
<address><br>
                 }</address>
<address>
                }</address>
<address>
}</address>
<br>
To check the http request one may use the <a href="http://www.owasp.org/index.php/Category:OWASP_Stinger_Project" target="_blank">OWASP
Stinger Project</a> or a similar framework.<br>
Since these frameworks generally analyze a <a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html" target="_blank">HttpServletRequest</a>
we need an <a href="http://en.wikipedia.org/wiki/Adapter_pattern" target="_blank">adapter</a>
to adapt to the netty HttpRequest.<br>
Implementing the adapter is straight forward.<br>
<br>
<br>
<br>
<br>
</div>

<br>_______________________________________________<br>
netty-users mailing list<br>
<a href="mailto:netty-users@lists.jboss.org">netty-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/netty-users" target="_blank">https://lists.jboss.org/mailman/listinfo/netty-users</a><br>
<br></blockquote></div><br></div>