package com.webobjects.appserver; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.AbstractMap.SimpleEntry; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.handler.codec.http.Cookie; import org.jboss.netty.handler.codec.http.CookieEncoder; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpHeaders.Names; import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.HttpResponseStatus; import org.jboss.netty.handler.codec.http.HttpVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSForwardException; import com.webobjects.foundation.NSSet; /** * Wrapper for WOResponse to pass to Netty HttpResponseEncoder * * @author ravim */ public class WOResponseWrapper implements HttpResponse { private static final Logger log = LoggerFactory.getLogger(WOResponseWrapper.class); private WOResponse wrapping; private ChannelBuffer _content; /** * Converts a WOCookie to a Netty cookie * * @param wocookie * @return A Netty cookie */ private static Cookie asCookie(WOCookie wocookie) { return new WOCookieWrapper(wocookie); } public WOResponseWrapper(WOResponse response) { super(); wrapping = response; } public HttpResponseStatus getStatus() { return HttpResponseStatus.valueOf(wrapping.status()); } public void setStatus(HttpResponseStatus status) { wrapping.setStatus(status.getCode()); } public void addHeader(String name, Object value) { if (value != null) { if (value instanceof String) { wrapping.appendHeader((String) value, name); } } } public void clearHeaders() { wrapping._httpHeaders = null; } public boolean containsHeader(String name) { return wrapping.hasHeaderForKey(name); } public ChannelBuffer getContent() { if(_content == null) { // set content string if (wrapping._contentLength() > 0) { if (wrapping._content.length() > 0) { Charset charset = Charset.forName(wrapping.contentEncoding()); _content = ChannelBuffers.copiedBuffer(wrapping._content.toString(), charset); wrapping._content = null; } else { int _length = wrapping._contentData.length(); this.setHeader(Names.CONTENT_LENGTH, _length); _content = ChannelBuffers.copiedBuffer(wrapping._contentData._bytesNoCopy()); wrapping._contentData = null; } } else if (wrapping.contentInputStream() != null) { try { int length = (int)wrapping.contentInputStreamLength(); _content = ChannelBuffers.buffer(length); InputStream stream = null; try { stream = wrapping.contentInputStream(); _content.writeBytes(stream, length); wrapping.setContentStream(null, 0, 0l); } finally { try { if(stream != null) { stream.close();} } catch(IOException e) { log.error("Could not close stream.", e); } } } catch (IOException exception) { throw NSForwardException._runtimeExceptionForThrowable(exception); } } else { _content = ChannelBuffers.EMPTY_BUFFER; } } return _content; } @Deprecated public long getContentLength() { return HttpHeaders.getContentLength(this); } @Deprecated public long getContentLength(long defaultValue) { return HttpHeaders.getContentLength(this, defaultValue); } public String getHeader(String name) { if (name.equals(Names.COOKIE)) { // Encode the cookie. NSArray<WOCookie> wocookies = wrapping.cookies(); if(!wocookies.isEmpty()) { CookieEncoder cookieEncoder = new CookieEncoder(true); for (WOCookie wocookie : wocookies) { Cookie cookie = asCookie(wocookie); cookieEncoder.addCookie(cookie); } return cookieEncoder.encode(); } else return null; } else return wrapping.headerForKey(name); } public Set<String> getHeaderNames() { return new NSSet<>(wrapping.headerKeys()); } public List<Map.Entry<String, String>> getHeaders() { List<Map.Entry<String, String>> headers = new LinkedList<Map.Entry<String, String>>(); for(String headerKey: wrapping.headerKeys()) { String value = wrapping.headerForKey(headerKey); if (value != null) { headers.add(new SimpleEntry<>(headerKey, value)); } } return headers; } public List<String> getHeaders(String name) { return wrapping.headersForKey(name); } public HttpVersion getProtocolVersion() { return HttpVersion.valueOf(wrapping.httpVersion()); } public boolean isChunked() { return false; } public boolean isKeepAlive() { // TODO Auto-generated method stub return false; } public void removeHeader(String name) { wrapping.removeHeadersForKey(name); } public void setChunked(boolean chunked) { // TODO Checkme - irrelevant for http response log.error("Trying to set http response content"); } public void setContent(ChannelBuffer content) { if (content != null) { _content = content; } else _content = ChannelBuffers.EMPTY_BUFFER; } public void setHeader(String name, Object value) { if (value != null) { wrapping.setHeader(value.toString(), name); } else wrapping.setHeader(null, name); } public void setHeader(String name, Iterable<?> values) { if (values != null) { NSArray<String> value = new NSArray(values); wrapping.setHeaders(value, name); } else wrapping.setHeader(null, name); } public void setProtocolVersion(HttpVersion version) { wrapping.setHTTPVersion(version.getText()); } }