package org.jboss.resteasy.plugins.server.netty;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
import javax.ws.rs.ext.RuntimeDelegate;
import java.util.List;
import java.util.Map;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
/**
* {@link OneToOneEncoder} implementation which encodes {@link org.jboss.resteasy.spi.HttpResponse}'s to
* {@link HttpResponse}'s
*
* This implementation is {@link Sharable}
*
* @author Norman Maurer
*
*/
@Sharable
public class RestEasyHttpResponseEncoder extends OneToOneEncoder
{
private final RequestDispatcher dispatcher;
public RestEasyHttpResponseEncoder(RequestDispatcher dispatcher)
{
this.dispatcher = dispatcher;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception
{
if (msg instanceof org.jboss.resteasy.spi.HttpResponse) {
NettyHttpResponse nettyResponse = (NettyHttpResponse) msg;
// Build the response object.
HttpResponseStatus status = HttpResponseStatus.valueOf(nettyResponse.getStatus());
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status);
for (Map.Entry<String, List<Object>> entry : nettyResponse.getOutputHeaders().entrySet())
{
String key = entry.getKey();
for (Object value : entry.getValue())
{
RuntimeDelegate.HeaderDelegate delegate = dispatcher.providerFactory.getHeaderDelegate(value.getClass());
if (delegate != null)
{
response.headers().add(key, delegate.toString(value));
}
else
{
response.headers().add(key, value.toString());
}
}
}
nettyResponse.getOutputStream().flush();
final ChannelBuffer buffer = nettyResponse.getBuffer();
if (nettyResponse.getMethod() == null || nettyResponse.getMethod() != HttpMethod.HEAD) {
response.setContent(buffer);
}
if (nettyResponse.isKeepAlive())
{
// Add content length and connection header if needed
response.headers()
.set(Names.CONTENT_LENGTH, buffer.readableBytes())
.set(Names.CONNECTION, Values.KEEP_ALIVE);
}
return response;
}
return msg;
}
}