/*
* $Id: Response.java,v 1.9 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.server.listener;
import java.net.Socket;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import anvil.java.util.Hashlist;
import anvil.server.MimeTypes;
import anvil.server.Templates;
import anvil.server.Zone;
import anvil.server.Resource;
import anvil.util.HttpDate;
/**
* class Response
*
* @author: Jani Lehtim�ki
*/
public class Response implements HttpServletResponse
{
private Zone _zone;
private Request _request;
private ResponseOutputStream _output;
private PrintWriter _writer;
private String _encoding = "ISO-8859-1";
private int _inputstate = 0;
private Locale _locale = Locale.getDefault();
private String _contenttype = "text/html";
private int _contentlength = -1;
private int _status = 200;
private Hashlist _headers = new Hashlist();
private ArrayList _cookies = new ArrayList();
private boolean _keepalive;
public Response(Zone zone, Request request, Socket socket, ResponseOutputStream output, boolean keepalive) throws IOException
{
_zone = zone;
_request = request;
_output = output;
_keepalive = keepalive;
reset();
}
void destroy()
{
_output = null;
_writer = null;
_encoding = null;
_locale = null;
_contenttype = null;
_headers.clear();
_headers = null;
_cookies.clear();
_cookies = null;
}
public byte[] commit()
{
setHeader("Connection", _keepalive ? "Keep-Alive" : "Close");
setDateHeader("Date", System.currentTimeMillis());
setHeader("Server", anvil.server.Server.VERSION);
StringBuffer buf = new StringBuffer();
buf.append("HTTP/");
if (_request.getVersion() >= 11) {
buf.append("1.1 ");
} else {
buf.append("1.0 ");
}
buf.append(_status);
buf.append(' ');
buf.append(MimeTypes.getErrorText(_status));
buf.append("\r\n");
Enumeration e = _headers.elements();
while(e.hasMoreElements()) {
Header header = (Header)e.nextElement();
header.toString(buf);
}
int size = _cookies.size();
for(int i=0; i<size; i++) {
Cookie cookie = (Cookie)_cookies.get(i);
buf.append("Set-Cookie: ");
getCookieValue(buf, cookie);
buf.append("\r\n");
}
buf.append("\r\n");
//System.out.println("{"+buf+"}");
return anvil.util.Conversions.getBytes(buf.toString());
}
protected StringBuffer getCookieValue(StringBuffer buf, Cookie cookie)
{
buf.append(cookie.getName());
buf.append('=');
buf.append(cookie.getValue());
buf.append(';');
int maxage = cookie.getMaxAge();
if (maxage > -1) {
buf.append(" expires=");
HttpDate expires = new HttpDate(System.currentTimeMillis() + maxage*1000);
buf.append(expires.toCookieString());
buf.append(';');
}
String path = cookie.getPath();
if (path != null) {
buf.append(" path=");
buf.append(path);
buf.append(';');
}
String domain = cookie.getDomain();
if (domain != null) {
buf.append(" domain=");
buf.append(domain);
buf.append(';');
}
if (cookie.getSecure()) {
buf.append(" secure");
}
buf.append("\r\n");
return buf;
}
public synchronized ServletOutputStream getOutputStream()
{
switch(_inputstate) {
case 0:
_inputstate = 1;
case 1:
break;
case 2:
throw new IllegalStateException("getWriter() already called");
}
return _output;
}
public synchronized PrintWriter getWriter()
{
switch(_inputstate) {
case 0:
_writer = new PrintWriter(_output);
_inputstate = 2;
break;
case 1:
throw new IllegalStateException("getOutputStream() already called");
case 2:
}
return _writer;
}
public synchronized void flushBuffer() throws IOException
{
if (_inputstate == 2) {
_writer.flush();
} else {
_output.flush();
}
}
public int getBufferSize()
{
return 0;
}
public String getCharacterEncoding()
{
return _encoding;
}
public Locale getLocale()
{
return _locale;
}
public boolean isCommitted()
{
return _output.isCommitted();
}
public void reset()
{
_contentlength = -1;
_contenttype = "text/html";
_headers.clear();
_cookies.clear();
}
public void setBufferSize(int size)
{
}
public void setContentLength(int length)
{
_contentlength = length;
setIntHeader("Content-Length", length);
}
public void setContentType(String type)
{
_contenttype = type;
setHeader("Content-Type", type);
}
public void setLocale(java.util.Locale locale)
{
_locale = locale;
}
public void addCookie(Cookie cookie)
{
_cookies.add(cookie);
}
public boolean containsHeader(String name)
{
return _headers.containsKey(name);
}
public String encodeRedirectURL(String url)
{
return url;
}
public String encodeRedirectUrl(String url)
{
return url;
}
public String encodeURL(String url)
{
return url;
}
public String encodeUrl(String url)
{
return url;
}
public void sendError(int code) throws IOException
{
Templates.message(_request, this, MimeTypes.TEXT_HTML, code);
}
public void sendError(int code, String msg) throws IOException
{
Templates.message(_request, this, MimeTypes.TEXT_HTML, code, msg);
}
public void sendRedirect(String url)
throws IOException, IllegalArgumentException
{
setStatus(302);
setHeader("Location", url);
_output.println("<html><head><title>302 Document moved</title></head>");
_output.println("<body><h1>302 Document moved</h1>");
_output.print("This document has moved <a href=\"");
_output.print(url);
_output.println("\">here</a></body></html>");
_output.flush();
}
public void setHeader(String name, String value)
{
_headers.put(name.toLowerCase(), new Header(name, value));
}
public void setDateHeader(String name, long time)
{
setHeader(name, new HttpDate(time).toString());
}
public void setIntHeader(String name, int num)
{
setHeader(name, String.valueOf(num));
}
public void addHeader(String name, String value)
{
name = name.toLowerCase();
Header header = (Header)_headers.get(name);
if (header == null) {
header = new Header(name, value);
_headers.put(name, header);
} else {
header.addValue(value);
}
}
public void addDateHeader(String name, long time)
{
addHeader(name, new HttpDate(time).toString());
}
public void addIntHeader(String name, int num)
{
addHeader(name, String.valueOf(num));
}
public void setStatus(int status)
{
_status = status;
}
public void setStatus(int status, String msg)
{
_status = status;
}
}