org.eclipse.jetty.server.Response Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
//
// ========================================================================
// 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.
*
* Implements {@link javax.servlet.http.HttpServletResponse} from the javax.servlet.http
package.
*
*/
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, "&", "&");
message= StringUtil.replace(message, "<", "<");
message= StringUtil.replace(message, ">", ">");
}
String uri= request.getRequestURI();
if (uri!=null)
{
uri= StringUtil.replace(uri, "&", "&");
uri= StringUtil.replace(uri, "<", "<");
uri= StringUtil.replace(uri, ">", ">");
}
writer.write("\n\n\n");
writer.write("Error ");
writer.write(Integer.toString(code));
writer.write(' ');
if (message==null)
message=HttpStatus.getMessage(code);
writer.write(message);
writer.write(" \n\n\nHTTP ERROR: ");
writer.write(Integer.toString(code));
writer.write("
\nProblem accessing ");
writer.write(uri);
writer.write(". Reason:\n
");
writer.write(message);
writer.write("
");
writer.write("\n
Powered by Jetty://");
for (int i= 0; i < 20; i++)
writer.write("\n ");
writer.write("\n\n\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 getHeaderNames()
{
final HttpFields fields=_connection.getResponseFields();
return fields.getFieldNamesCollection();
}
/* ------------------------------------------------------------ */
/*
*/
public String getHeader(String name)
{
return _connection.getResponseFields().getStringField(name);
}
/* ------------------------------------------------------------ */
/*
*/
public Collection getHeaders(String name)
{
final HttpFields fields=_connection.getResponseFields();
Collection 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 cookieValues = new ArrayList(5);
Enumeration 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 200
* ({@link HttpServletResponse#SC_OK}), unless explicitly set through one of the setStatus
methods.
*/
public int getStatus()
{
return _status;
}
/* ------------------------------------------------------------ */
/**
* @return The reason associated with the current {@link #getStatus() status}. This will be null
,
* unless one of the setStatus
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
{
}
}
}