//
//  ========================================================================
//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.Locale;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletOutputStream;
import javax.servlet.SessionTrackingMode;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpHeaderValues;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/** Response.
 * <p>
 * Implements {@link javax.servlet.http.HttpServletResponse} from the <code>javax.servlet.http</code> package.
 * </p>
 */
public class Response implements HttpServletResponse
{
    private static final Logger LOG = Log.getLogger(Response.class);

    
    public static final int
        NONE=0,
        STREAM=1,
        WRITER=2;

    /**
     * If a header name starts with this string,  the header (stripped of the prefix)
     * can be set during include using only {@link #setHeader(String, String)} or
     * {@link #addHeader(String, String)}.
     */
    public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include.";

    /**
     * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie 
     * will be set as HTTP ONLY.
     */
    public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__";
    
    
    /* ------------------------------------------------------------ */
    public static Response getResponse(HttpServletResponse response)
    {
        if (response instanceof Response)
            return (Response)response;

        return AbstractHttpConnection.getCurrentConnection().getResponse();
    }
    
    private final AbstractHttpConnection _connection;
    private int _status=SC_OK;
    private String _reason;
    private Locale _locale;
    private String _mimeType;
    private CachedBuffer _cachedMimeType;
    private String _characterEncoding;
    private boolean _explicitEncoding;
    private String _contentType;
    private volatile int _outputState;
    private PrintWriter _writer;

    /* ------------------------------------------------------------ */
    /**
     *
     */
    public Response(AbstractHttpConnection connection)
    {
        _connection=connection;
    }


    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#reset()
     */
    protected void recycle()
    {
        _status=SC_OK;
        _reason=null;
        _locale=null;
        _mimeType=null;
        _cachedMimeType=null;
        _characterEncoding=null;
        _explicitEncoding=false;
        _contentType=null;
        _writer=null;
        _outputState=NONE;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie)
     */
    public void addCookie(HttpCookie cookie)
    {
        _connection.getResponseFields().addSetCookie(cookie);
    }
    
    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie)
     */
    public void addCookie(Cookie cookie)
    {
        String comment=cookie.getComment();
        boolean http_only=false;
        
        if (comment!=null)
        {
            int i=comment.indexOf(HTTP_ONLY_COMMENT);
            if (i>=0)
            {
                http_only=true;
                comment=comment.replace(HTTP_ONLY_COMMENT,"").trim();
                if (comment.length()==0)
                    comment=null;
            }
        }
        _connection.getResponseFields().addSetCookie(cookie.getName(),
                cookie.getValue(),
                cookie.getDomain(),
                cookie.getPath(),
                cookie.getMaxAge(),
                comment,
                cookie.getSecure(),
                http_only || cookie.isHttpOnly(),
                cookie.getVersion());
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String)
     */
    public boolean containsHeader(String name)
    {
        return _connection.getResponseFields().containsKey(name);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String)
     */
    public String encodeURL(String url)
    {
        final Request request=_connection.getRequest();
        SessionManager sessionManager = request.getSessionManager();
        if (sessionManager==null)
            return url;
        
        HttpURI uri = null;
        if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url))
        {
            uri = new HttpURI(url);
            String path = uri.getPath();
            path = (path == null?"":path);
            int port=uri.getPort();
            if (port<0) 
                port = HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80;
            if (!request.getServerName().equalsIgnoreCase(uri.getHost()) ||
                request.getServerPort()!=port ||
                !path.startsWith(request.getContextPath())) //TODO the root context path is "", with which every non null string starts
                return url;
        }
        
        String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix();
        if (sessionURLPrefix==null)
            return url;

        if (url==null)
            return null;
        
        // should not encode if cookies in evidence
        if ((sessionManager.isUsingCookies() && request.isRequestedSessionIdFromCookie()) || !sessionManager.isUsingURLs()) 
        {
            int prefix=url.indexOf(sessionURLPrefix);
            if (prefix!=-1)
            {
                int suffix=url.indexOf("?",prefix);
                if (suffix<0)
                    suffix=url.indexOf("#",prefix);

                if (suffix<=prefix)
                    return url.substring(0,prefix);
                return url.substring(0,prefix)+url.substring(suffix);
            }
            return url;
        }

        // get session;
        HttpSession session=request.getSession(false);

        // no session
        if (session == null)
            return url;

        // invalid session
        if (!sessionManager.isValid(session))
            return url;

        String id=sessionManager.getNodeId(session);

        if (uri == null)
                uri = new HttpURI(url);
     
        
        // Already encoded
        int prefix=url.indexOf(sessionURLPrefix);
        if (prefix!=-1)
        {
            int suffix=url.indexOf("?",prefix);
            if (suffix<0)
                suffix=url.indexOf("#",prefix);

            if (suffix<=prefix)
                return url.substring(0,prefix+sessionURLPrefix.length())+id;
            return url.substring(0,prefix+sessionURLPrefix.length())+id+
                url.substring(suffix);
        }

        // edit the session
        int suffix=url.indexOf('?');
        if (suffix<0)
            suffix=url.indexOf('#');
        if (suffix<0) 
        {          
            return url+ 
                   ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path
                   sessionURLPrefix+id;
        }
     
        
        return url.substring(0,suffix)+
            ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path
            sessionURLPrefix+id+url.substring(suffix);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String)
     */
    public String encodeRedirectURL(String url)
    {
        return encodeURL(url);
    }

    /* ------------------------------------------------------------ */
    @Deprecated
    public String encodeUrl(String url)
    {
        return encodeURL(url);
    }

    /* ------------------------------------------------------------ */
    @Deprecated
    public String encodeRedirectUrl(String url)
    {
        return encodeRedirectURL(url);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String)
     */
    public void sendError(int code, String message) throws IOException
    {
    	if (_connection.isIncluding())
    		return;

        if (isCommitted())
            LOG.warn("Committed before "+code+" "+message);

        resetBuffer();
        _characterEncoding=null;
        setHeader(HttpHeaders.EXPIRES,null);
        setHeader(HttpHeaders.LAST_MODIFIED,null);
        setHeader(HttpHeaders.CACHE_CONTROL,null);
        setHeader(HttpHeaders.CONTENT_TYPE,null);
        setHeader(HttpHeaders.CONTENT_LENGTH,null);

        _outputState=NONE;
        setStatus(code,message);

        if (message==null)
            message=HttpStatus.getMessage(code);

        // If we are allowed to have a body
        if (code!=SC_NO_CONTENT &&
            code!=SC_NOT_MODIFIED &&
            code!=SC_PARTIAL_CONTENT &&
            code>=SC_OK)
        {
            Request request = _connection.getRequest();

            ErrorHandler error_handler = null;
            ContextHandler.Context context = request.getContext();
            if (context!=null)
                error_handler=context.getContextHandler().getErrorHandler();
            if (error_handler==null)
                error_handler = _connection.getConnector().getServer().getBean(ErrorHandler.class);
            if (error_handler!=null)
            {
                request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(code));
                request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message);
                request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI());
                request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME,request.getServletName());
                error_handler.handle(null,_connection.getRequest(),_connection.getRequest(),this );
            }
            else
            {
                setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store");
                setContentType(MimeTypes.TEXT_HTML_8859_1);
                ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(2048);
                if (message != null)
                {
                    message= StringUtil.replace(message, "&", "&amp;");
                    message= StringUtil.replace(message, "<", "&lt;");
                    message= StringUtil.replace(message, ">", "&gt;");
                }
                String uri= request.getRequestURI();
                if (uri!=null)
                {
                    uri= StringUtil.replace(uri, "&", "&amp;");
                    uri= StringUtil.replace(uri, "<", "&lt;");
                    uri= StringUtil.replace(uri, ">", "&gt;");
                }

                writer.write("<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n");
                writer.write("<title>Error ");
                writer.write(Integer.toString(code));
                writer.write(' ');
                if (message==null)
                    message=HttpStatus.getMessage(code);
                writer.write(message);
                writer.write("</title>\n</head>\n<body>\n<h2>HTTP ERROR: ");
                writer.write(Integer.toString(code));
                writer.write("</h2>\n<p>Problem accessing ");
                writer.write(uri);
                writer.write(". Reason:\n<pre>    ");
                writer.write(message);
                writer.write("</pre>");
                writer.write("</p>\n<hr /><i><small>Powered by Jetty://</small></i>");

                for (int i= 0; i < 20; i++)
                    writer.write("\n                                                ");
                writer.write("\n</body>\n</html>\n");

                writer.flush();
                setContentLength(writer.size());
                writer.writeTo(getOutputStream());
                writer.destroy();
            }
        }
        else if (code!=SC_PARTIAL_CONTENT)
        {
            _connection.getRequestFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
            _connection.getRequestFields().remove(HttpHeaders.CONTENT_LENGTH_BUFFER);
            _characterEncoding=null;
            _mimeType=null;
            _cachedMimeType=null;
        }

        complete();
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#sendError(int)
     */
    public void sendError(int sc) throws IOException
    {
        if (sc==102)
            sendProcessing();
        else
            sendError(sc,null);
    }

    /* ------------------------------------------------------------ */
    /* Send a 102-Processing response.
     * If the connection is a HTTP connection, the version is 1.1 and the
     * request has a Expect header starting with 102, then a 102 response is
     * sent. This indicates that the request still be processed and real response
     * can still be sent.   This method is called by sendError if it is passed 102.
     * @see javax.servlet.http.HttpServletResponse#sendError(int)
     */
    public void sendProcessing() throws IOException
    {
        if (_connection.isExpecting102Processing() && !isCommitted())
            ((HttpGenerator)_connection.getGenerator()).send1xx(HttpStatus.PROCESSING_102);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String)
     */
    public void sendRedirect(String location) throws IOException
    {
    	if (_connection.isIncluding())
    		return;

        if (location==null)
            throw new IllegalArgumentException();

        if (!URIUtil.hasScheme(location))
        {
            StringBuilder buf = _connection.getRequest().getRootURL();
            if (location.startsWith("/"))
                buf.append(location);
            else
            {
                String path=_connection.getRequest().getRequestURI();
                String parent=(path.endsWith("/"))?path:URIUtil.parentPath(path);
                location=URIUtil.addPaths(parent,location);
                if(location==null)
                    throw new IllegalStateException("path cannot be above root");
                if (!location.startsWith("/"))
                    buf.append('/');
                buf.append(location);
            }

            location=buf.toString();
            HttpURI uri = new HttpURI(location);
            String path=uri.getDecodedPath();
            String canonical=URIUtil.canonicalPath(path);
            if (canonical==null)
                throw new IllegalArgumentException();
            if (!canonical.equals(path))
            {
                buf = _connection.getRequest().getRootURL();
                buf.append(URIUtil.encodePath(canonical));
                String param=uri.getParam();
                if (param!=null)
                {
                    buf.append(';');
                    buf.append(param);
                }
                String query=uri.getQuery();
                if (query!=null)
                {
                    buf.append('?');
                    buf.append(query);
                }
                String fragment=uri.getFragment();
                if (fragment!=null)
                {
                    buf.append('#');
                    buf.append(fragment);
                }
                location=buf.toString();
            }
        }
        
        resetBuffer();
        setHeader(HttpHeaders.LOCATION,location);
        setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
        complete();

    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long)
     */
    public void setDateHeader(String name, long date)
    {
        if (!_connection.isIncluding())
            _connection.getResponseFields().putDateField(name, date);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long)
     */
    public void addDateHeader(String name, long date)
    {
        if (!_connection.isIncluding())
            _connection.getResponseFields().addDateField(name, date);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String)
     */
    public void setHeader(String name, String value)
    {
        if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name))
            setContentType(value);
        else
        {
            if (_connection.isIncluding())
            {
                if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
                    name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
                else
                    return;
            }
            _connection.getResponseFields().put(name, value);
            if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
            {
                if (value==null)
                    _connection._generator.setContentLength(-1);
                else
                    _connection._generator.setContentLength(Long.parseLong(value));
            }
        }
    }


    /* ------------------------------------------------------------ */
    public Collection<String> getHeaderNames()
    {
        final HttpFields fields=_connection.getResponseFields();
        return fields.getFieldNamesCollection();
    }
    
    /* ------------------------------------------------------------ */
    /*
     */
    public String getHeader(String name)
    {
        return _connection.getResponseFields().getStringField(name);
    }

    /* ------------------------------------------------------------ */
    /*
     */
    public Collection<String> getHeaders(String name)
    {
        final HttpFields fields=_connection.getResponseFields();
        Collection<String> i = fields.getValuesCollection(name);
        if (i==null)
            return Collections.EMPTY_LIST;
        return i;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String)
     */
    public void addHeader(String name, String value)
    {

        if (_connection.isIncluding())
        {
            if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
                name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
            else
                return;
        }

        if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name))
        {
            setContentType(value);
            return;
        }
        
        _connection.getResponseFields().add(name, value);
        if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
            _connection._generator.setContentLength(Long.parseLong(value));
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int)
     */
    public void setIntHeader(String name, int value)
    {
        if (!_connection.isIncluding())
        {
            _connection.getResponseFields().putLongField(name, value);
            if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
                _connection._generator.setContentLength(value);
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int)
     */
    public void addIntHeader(String name, int value)
    {
        if (!_connection.isIncluding())
        {
            _connection.getResponseFields().addLongField(name, value);
            if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
                _connection._generator.setContentLength(value);
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#setStatus(int)
     */
    public void setStatus(int sc)
    {
        setStatus(sc,null);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpServletResponse#setStatus(int, java.lang.String)
     */
    public void setStatus(int sc, String sm)
    {
        if (sc<=0)
            throw new IllegalArgumentException();
        if (!_connection.isIncluding())
        {
            _status=sc;
            _reason=sm;
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#getCharacterEncoding()
     */
    public String getCharacterEncoding()
    {
        if (_characterEncoding==null)
            _characterEncoding=StringUtil.__ISO_8859_1;
        return _characterEncoding;
    }
    
    /* ------------------------------------------------------------ */
    String getSetCharacterEncoding()
    {
        return _characterEncoding;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#getContentType()
     */
    public String getContentType()
    {
        return _contentType;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#getOutputStream()
     */
    public ServletOutputStream getOutputStream() throws IOException
    {
        if (_outputState!=NONE && _outputState!=STREAM)
            throw new IllegalStateException("WRITER");

        ServletOutputStream out = _connection.getOutputStream();
        _outputState=STREAM;
        return out;
    }

    /* ------------------------------------------------------------ */
    public boolean isWriting()
    {
        return _outputState==WRITER;
    }

    /* ------------------------------------------------------------ */
    public boolean isOutputing()
    {
        return _outputState!=NONE;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#getWriter()
     */
    public PrintWriter getWriter() throws IOException
    {
        if (_outputState!=NONE && _outputState!=WRITER)
            throw new IllegalStateException("STREAM");

        /* if there is no writer yet */
        if (_writer==null)
        {
            /* get encoding from Content-Type header */
            String encoding = _characterEncoding;

            if (encoding==null)
            {
                /* implementation of educated defaults */
                if(_cachedMimeType != null)
                    encoding = MimeTypes.getCharsetFromContentType(_cachedMimeType);

                if (encoding==null)
                    encoding = StringUtil.__ISO_8859_1;

                setCharacterEncoding(encoding);
            }

            /* construct Writer using correct encoding */
            _writer = _connection.getPrintWriter(encoding);
        }
        _outputState=WRITER;
        return _writer;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String)
     */
    public void setCharacterEncoding(String encoding)
    {
    	if (_connection.isIncluding())
    		return;

        if (this._outputState==0 && !isCommitted())
        {
            _explicitEncoding=true;

            if (encoding==null)
            {
                // Clear any encoding.
                if (_characterEncoding!=null)
                {
                    _characterEncoding=null;
                    if (_cachedMimeType!=null)
                        _contentType=_cachedMimeType.toString();
                    else if (_mimeType!=null)
                        _contentType=_mimeType;
                    else
                        _contentType=null;

                    if (_contentType==null)
                        _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
                    else
                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                }
            }
            else
            {
                // No, so just add this one to the mimetype
                _characterEncoding=encoding;
                if (_contentType!=null)
                {
                    int i0=_contentType.indexOf(';');
                    if (i0<0)
                    {
                        _contentType=null;
                        if(_cachedMimeType!=null)
                        {
                            CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
                            if (content_type!=null)
                            {
                                _contentType=content_type.toString();
                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
                            }
                        }

                        if (_contentType==null)
                        {
                            _contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                        }
                    }
                    else
                    {
                        int i1=_contentType.indexOf("charset=",i0);
                        if (i1<0)
                        {
                            _contentType = _contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                        }
                        else
                        {
                            int i8=i1+8;
                            int i2=_contentType.indexOf(" ",i8);
                            if (i2<0)
                                _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                            else
                                _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ")+_contentType.substring(i2);
                        }
                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                    }
                }
            }
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#setContentLength(int)
     */
    public void setContentLength(int len)
    {
        // Protect from setting after committed as default handling
        // of a servlet HEAD request ALWAYS sets _content length, even
        // if the getHandling committed the response!
        if (isCommitted() || _connection.isIncluding())
            return;
        _connection._generator.setContentLength(len);
        if (len>0)
        {
            _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
            if (_connection._generator.isAllContentWritten())
            {
                if (_outputState==WRITER)
                    _writer.close();
                else if (_outputState==STREAM)
                {
                    try
                    {
                        getOutputStream().close();
                    }
                    catch(IOException e)
                    {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#setContentLength(int)
     */
    public void setLongContentLength(long len)
    {
        // Protect from setting after committed as default handling
        // of a servlet HEAD request ALWAYS sets _content length, even
        // if the getHandling committed the response!
        if (isCommitted() || _connection.isIncluding())
        	return;
        _connection._generator.setContentLength(len);
        _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#setContentType(java.lang.String)
     */
    public void setContentType(String contentType)
    {
        if (isCommitted() || _connection.isIncluding())
            return;

        // Yes this method is horribly complex.... but there are lots of special cases and
        // as this method is called on every request, it is worth trying to save string creation.
        //

        if (contentType==null)
        {
            if (_locale==null)
                _characterEncoding=null;
            _mimeType=null;
            _cachedMimeType=null;
            _contentType=null;
            _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
        }
        else
        {
            // Look for encoding in contentType
            int i0=contentType.indexOf(';');

            if (i0>0)
            {
                // we have content type parameters

                // Extract params off mimetype
                _mimeType=contentType.substring(0,i0).trim();
                _cachedMimeType=MimeTypes.CACHE.get(_mimeType);

                // Look for charset
                int i1=contentType.indexOf("charset=",i0+1);
                if (i1>=0)
                {
                    _explicitEncoding=true;
                    int i8=i1+8;
                    int i2 = contentType.indexOf(' ',i8);

                    if (_outputState==WRITER)
                    {
                        // strip the charset and ignore;
                        if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
                        {
                            if (_cachedMimeType!=null)
                            {
                                CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
                                if (content_type!=null)
                                {
                                    _contentType=content_type.toString();
                                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
                                }
                                else
                                {
                                    _contentType=_mimeType+";charset="+_characterEncoding;
                                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                                }
                            }
                            else
                            {
                                _contentType=_mimeType+";charset="+_characterEncoding;
                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                            }
                        }
                        else if (i2<0)
                        {
                            _contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                        }
                        else
                        {
                            _contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                        }
                    }
                    else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
                    {
                        // The params are just the char encoding
                        _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
                        _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));

                        if (_cachedMimeType!=null)
                        {
                            CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
                            if (content_type!=null)
                            {
                                _contentType=content_type.toString();
                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
                            }
                            else
                            {
                                _contentType=contentType;
                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                            }
                        }
                        else
                        {
                            _contentType=contentType;
                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                        }
                    }
                    else if (i2>0)
                    {
                        _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2));
                        _contentType=contentType;
                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                    }
                    else
                    {
                        _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
                        _contentType=contentType;
                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                    }
                }
                else // No encoding in the params.
                {
                    _cachedMimeType=null;
                    _contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                }
            }
            else // No params at all
            {
                _mimeType=contentType;
                _cachedMimeType=MimeTypes.CACHE.get(_mimeType);

                if (_characterEncoding!=null)
                {
                    if (_cachedMimeType!=null)
                    {
                        CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
                        if (content_type!=null)
                        {
                            _contentType=content_type.toString();
                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
                        }
                        else
                        {
                            _contentType=_mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                        }
                    }
                    else
                    {
                        _contentType=contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                    }
                }
                else if (_cachedMimeType!=null)
                {
                    _contentType=_cachedMimeType.toString();
                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType);
                }
                else
                {
                    _contentType=contentType;
                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
                }
            }
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#setBufferSize(int)
     */
    public void setBufferSize(int size)
    {
        if (isCommitted() || getContentCount()>0)
            throw new IllegalStateException("Committed or content written");
        _connection.getGenerator().increaseContentBufferSize(size);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#getBufferSize()
     */
    public int getBufferSize()
    {
        return _connection.getGenerator().getContentBufferSize();
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#flushBuffer()
     */
    public void flushBuffer() throws IOException
    {
        _connection.flushResponse();
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#reset()
     */
    public void reset()
    {
        resetBuffer();
        fwdReset();
        _status=200;
        _reason=null;
        
        HttpFields response_fields=_connection.getResponseFields();
        
        response_fields.clear();
        String connection=_connection.getRequestFields().getStringField(HttpHeaders.CONNECTION_BUFFER);
        if (connection!=null)
        {
            String[] values = connection.split(",");
            for  (int i=0;values!=null && i<values.length;i++)
            {
                CachedBuffer cb = HttpHeaderValues.CACHE.get(values[0].trim());

                if (cb!=null)
                {
                    switch(cb.getOrdinal())
                    {
                        case HttpHeaderValues.CLOSE_ORDINAL:
                            response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
                            break;

                        case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
                            if (HttpVersions.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol()))
                                response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.KEEP_ALIVE);
                            break;
                        case HttpHeaderValues.TE_ORDINAL:
                            response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.TE);
                            break;
                    }
                }
            }
        }
    }
    

    public void reset(boolean preserveCookies)
    { 
        if (!preserveCookies)
            reset();
        else
        {
            HttpFields response_fields=_connection.getResponseFields();

            ArrayList<String> cookieValues = new ArrayList<String>(5);
            Enumeration<String> vals = response_fields.getValues(HttpHeaders.SET_COOKIE);
            while (vals.hasMoreElements())
                cookieValues.add((String)vals.nextElement());

            reset();

            for (String v:cookieValues)
                response_fields.add(HttpHeaders.SET_COOKIE, v);
        }
    }
    
    
    
    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#reset()
     */
    public void fwdReset()
    {
        resetBuffer();

        _writer=null;
        _outputState=NONE;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#resetBuffer()
     */
    public void resetBuffer()
    {
        if (isCommitted())
            throw new IllegalStateException("Committed");
        _connection.getGenerator().resetBuffer();
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#isCommitted()
     */
    public boolean isCommitted()
    {
        return _connection.isResponseCommitted();
    }


    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#setLocale(java.util.Locale)
     */
    public void setLocale(Locale locale)
    {
        if (locale == null || isCommitted() ||_connection.isIncluding())
            return;

        _locale = locale;
        _connection.getResponseFields().put(HttpHeaders.CONTENT_LANGUAGE_BUFFER,locale.toString().replace('_','-'));

        if (_explicitEncoding || _outputState!=0 )
            return;

        if (_connection.getRequest().getContext()==null)
            return;

        String charset = _connection.getRequest().getContext().getContextHandler().getLocaleEncoding(locale);

        if (charset!=null && charset.length()>0)
        {
            _characterEncoding=charset;

            /* get current MIME type from Content-Type header */
            String type=getContentType();
            if (type!=null)
            {
                _characterEncoding=charset;
                int semi=type.indexOf(';');
                if (semi<0)
                {
                    _mimeType=type;
                    _contentType= type += ";charset="+charset;
                }
                else
                {
                    _mimeType=type.substring(0,semi);
                    _contentType= _mimeType += ";charset="+charset;
                }

                _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
            }
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.ServletResponse#getLocale()
     */
    public Locale getLocale()
    {
        if (_locale==null)
            return Locale.getDefault();
        return _locale;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The HTTP status code that has been set for this request. This will be <code>200<code>
     *    ({@link HttpServletResponse#SC_OK}), unless explicitly set through one of the <code>setStatus</code> methods.
     */
    public int getStatus()
    {
        return _status;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The reason associated with the current {@link #getStatus() status}. This will be <code>null</code>,
     *    unless one of the <code>setStatus</code> methods have been called.
     */
    public String getReason()
    {
        return _reason;
    }

    /* ------------------------------------------------------------ */
    /**
     */
    public void complete()
        throws IOException
    {
        _connection.completeResponse();
    }

    /* ------------------------------------------------------------- */
    /**
     * @return the number of bytes actually written in response body
     */
    public long getContentCount()
    {
        if (_connection==null || _connection.getGenerator()==null)
            return -1;
        return _connection.getGenerator().getContentWritten();
    }

    /* ------------------------------------------------------------ */
    public HttpFields getHttpFields()
    {
        return _connection.getResponseFields();
    }

    /* ------------------------------------------------------------ */
    @Override
    public String toString()
    {
        return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+
        _connection.getResponseFields().toString();
    }
    
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    private static class NullOutput extends ServletOutputStream
    {
        @Override
        public void write(int b) throws IOException
        {
        }

        @Override
        public void print(String s) throws IOException
        {
        }

        @Override
        public void println(String s) throws IOException
        {
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException
        {
        }

    }

}
