package org.caudexorigo.jpt.web.netty;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.caudexorigo.http.netty.HttpRequestWrapper;
import org.caudexorigo.jpt.JptConfiguration;
import org.caudexorigo.jpt.web.HttpJptProcessor;
import org.caudexorigo.jpt.web.Method;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferInputStream;
import org.jboss.netty.buffer.ChannelBufferOutputStream;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
public class NettyJptProcessor implements HttpJptProcessor
{
private static final String GZIP_ENCODING = "gzip";
private static final String DEFLATE_ENCODING = "deflate";
private final HttpRequestWrapper _req;
private final HttpResponse _res;
private Writer _writer;
private OutputStream _out;
private InputStream _in;
private final String _encoding;
private final ChannelHandlerContext _ctx;
private boolean _use_compression;
public NettyJptProcessor(ChannelHandlerContext ctx, HttpRequest request, HttpResponse response)
{
this(ctx, request, response, false);
}
public NettyJptProcessor(ChannelHandlerContext ctx, HttpRequest request, HttpResponse response, boolean use_compression)
{
_ctx = ctx;
_use_compression = use_compression;
try
{
_req = (HttpRequestWrapper) request;
_res = response;
ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
response.setContent(buf);
_encoding = JptConfiguration.encoding();
if (use_compression)
{
String accept_enconding = request.headers().get(HttpHeaders.Names.ACCEPT_ENCODING);
boolean gzip_output = StringUtils.containsIgnoreCase(accept_enconding, GZIP_ENCODING);
boolean deflate_output = StringUtils.containsIgnoreCase(accept_enconding, DEFLATE_ENCODING);
if (gzip_output)
{
response.headers().set(HttpHeaders.Names.CONTENT_ENCODING, GZIP_ENCODING);
_out = new GZIPOutputStream(new ChannelBufferOutputStream(buf), true);
}
else if (deflate_output)
{
response.headers().set(HttpHeaders.Names.CONTENT_ENCODING, DEFLATE_ENCODING);
_out = new DeflaterOutputStream(new ChannelBufferOutputStream(buf), true);
}
else
{
_out = new ChannelBufferOutputStream(buf);
}
}
else
{
_out = new ChannelBufferOutputStream(buf);
}
_writer = new OutputStreamWriter(_out, _encoding);
}
catch (Throwable t)
{
throw new RuntimeException(t);
}
}
@Override
public String getRequestPath()
{
return _req.getUri();
}
@Override
public InputStream getInputStream() throws IOException
{
if (_in == null)
{
_in = new ChannelBufferInputStream(_req.getContent());
}
return _in;
}
@Override
public Method getMethod()
{
return Method.valueOf(_req.getMethod().toString());
}
@Override
public OutputStream getOutputStream() throws IOException
{
return _out;
}
@Override
public List<String> getParameters(String p_name)
{
return _req.getParameters(p_name);
}
@Override
public final String getParameter(String p_name)
{
return _req.getParameter(p_name);
}
@Override
public Map<String, List<String>> getParameters()
{
return _req.getParameters();
}
@Override
public Object getSessionValue(String attr_name)
{
throw new UnsupportedOperationException("Sessions are not implemented when using the Netty HTTP Codec");
}
@Override
public Writer getWriter() throws IOException
{
return _writer;
}
public void include(String uri)
{
throw new UnsupportedOperationException("Includes are not implemented when using the Netty HTTP Codec");
}
public void setSessionValue(String attr_name, Object value)
{
throw new UnsupportedOperationException("Sessions are not implemented when using the Netty HTTP Codec");
}
public void clearResponse()
{
_res.getContent().clear();
}
@Override
public String getHeader(String headerName)
{
return _req.getHeader(headerName);
}
@Override
public void setHeader(String headerName, String headerValue)
{
_res.headers().set(headerName, headerValue);
}
@Override
public void setStatus(int statusCode)
{
_res.setStatus(HttpResponseStatus.valueOf(statusCode));
}
@Override
public int getStatus()
{
return _res.getStatus().getCode();
}
@Override
public InetSocketAddress getClientLocalAddress()
{
return (InetSocketAddress) _ctx.getChannel().getLocalAddress();
}
@Override
public InetSocketAddress getClientRemoteAddress()
{
return (InetSocketAddress) _ctx.getChannel().getRemoteAddress();
}
public void flush()
{
try
{
_writer.close();
}
catch (Throwable t)
{
throw new RuntimeException(t);
}
}
}