package org.jboss.resteasy.plugins.server.netty; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBufferOutputStream; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; 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.HttpResponseStatus; import org.jboss.resteasy.plugins.server.netty.i18n.Messages; import org.jboss.resteasy.specimpl.MultivaluedMapImpl; import org.jboss.resteasy.spi.HttpResponse; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.NewCookie; import java.io.IOException; import java.io.OutputStream; import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public class NettyHttpResponse implements HttpResponse { private int status = 200; private ChannelBufferOutputStream underlyingOutputStream; private OutputStream os; private MultivaluedMap<String, Object> outputHeaders; private final Channel channel; private boolean committed; private boolean keepAlive; private HttpMethod method; public NettyHttpResponse(Channel channel, boolean keepAlive) { this(channel, keepAlive, null); } public NettyHttpResponse(Channel channel, boolean keepAlive, HttpMethod method) { outputHeaders = new MultivaluedMapImpl<String, Object>(); os = underlyingOutputStream = new ChannelBufferOutputStream(ChannelBuffers.dynamicBuffer()); this.channel = channel; this.keepAlive = keepAlive; this.method = method; } @Override public void setOutputStream(OutputStream os) { this.os = os; } public ChannelBuffer getBuffer() { return underlyingOutputStream.buffer(); } @Override public int getStatus() { return status; } @Override public void setStatus(int status) { this.status = status; } @Override public MultivaluedMap<String, Object> getOutputHeaders() { return outputHeaders; } @Override public OutputStream getOutputStream() throws IOException { return os; } @Override public void addNewCookie(NewCookie cookie) { outputHeaders.add(HttpHeaders.SET_COOKIE, cookie); } @Override public void sendError(int status) throws IOException { sendError(status, null); } @Override public void sendError(int status, String message) throws IOException { if (committed) { throw new IllegalStateException(); } HttpResponseStatus responseStatus = null; if (message != null) { responseStatus = new HttpResponseStatus(status, message); } else { responseStatus = HttpResponseStatus.valueOf(status); } DefaultHttpResponse response = new DefaultHttpResponse(HTTP_1_1, responseStatus); if (keepAlive) { // Add keep alive and content length if needed response.headers() .add(Names.CONNECTION, Values.KEEP_ALIVE) .add(Names.CONTENT_LENGTH, 0); } channel.write(response); committed = true; } @Override public boolean isCommitted() { return committed; } @Override public void reset() { if (committed) { throw new IllegalStateException(Messages.MESSAGES.alreadyCommitted()); } outputHeaders.clear(); underlyingOutputStream.buffer().clear(); outputHeaders.clear(); } public boolean isKeepAlive() { return keepAlive; } public HttpMethod getMethod() { return method; } }