<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hi,<br>
<br>
I will post the code with a separate mail.<br>
The source also contains an implementation of a cache. But this is
still buggy.<br>
<br>
-- ron<br>
<br>
On 11.01.2010 18:44, Leandro Cruz wrote:
<blockquote
cite="mid:27bc81751001110944h7e815716u7a2c39f9275086f4@mail.gmail.com"
type="cite">
<pre wrap="">Hi Ron.
Do you have the complete source code for your example?
--
Leandro Rodrigo Saad Cruz
On Fri, Jan 8, 2010 at 9:25 PM, rzo <a class="moz-txt-link-rfc2396E" href="mailto:rzo@gmx.de"><rzo@gmx.de></a> wrote:
</pre>
<blockquote type="cite">
<pre wrap=""> 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<a class="moz-txt-link-rfc2396E" href="http://de.wikipedia.org/wiki/Web_Application_Firewall"><http://de.wikipedia.org/wiki/Web_Application_Firewall></a>)
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<a class="moz-txt-link-rfc2396E" href="http://www.owasp.org/index.php/Category:OWASP_Stinger_Project"><http://www.owasp.org/index.php/Category:OWASP_Stinger_Project></a>or a similar framework.
Since these frameworks generally analyze a HttpServletRequest<a class="moz-txt-link-rfc2396E" href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html"><http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html></a>we need an
adapter <a class="moz-txt-link-rfc2396E" href="http://en.wikipedia.org/wiki/Adapter_pattern"><http://en.wikipedia.org/wiki/Adapter_pattern></a> to adapt to the
netty HttpRequest.
Implementing the adapter is straight forward.
_______________________________________________
netty-users mailing list
<a class="moz-txt-link-abbreviated" href="mailto:netty-users@lists.jboss.org">netty-users@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/netty-users">https://lists.jboss.org/mailman/listinfo/netty-users</a>
</pre>
</blockquote>
<pre wrap="">
</pre>
<pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
netty-users mailing list
<a class="moz-txt-link-abbreviated" href="mailto:netty-users@lists.jboss.org">netty-users@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/netty-users">https://lists.jboss.org/mailman/listinfo/netty-users</a>
</pre>
</blockquote>
<br>
</body>
</html>