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; } }