changeset 1020:6be43ef1eb96

HttpHeaderValues uses StringCache
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 31 Oct 2016 22:24:41 -0600
parents f126d30e04a4
children e350c11242be
files src/org/eclipse/jetty/http/HttpFields.java src/org/eclipse/jetty/http/HttpGenerator.java src/org/eclipse/jetty/http/HttpHeaderValues.java src/org/eclipse/jetty/http/HttpParser.java src/org/eclipse/jetty/http/MimeTypes.java src/org/eclipse/jetty/io/AbstractBuffer.java src/org/eclipse/jetty/io/BufferUtil.java src/org/eclipse/jetty/io/StringCache.java src/org/eclipse/jetty/server/AbstractHttpConnection.java src/org/eclipse/jetty/server/Request.java src/org/eclipse/jetty/server/Response.java
diffstat 11 files changed, 443 insertions(+), 534 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/eclipse/jetty/http/HttpFields.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/http/HttpFields.java	Mon Oct 31 22:24:41 2016 -0600
@@ -277,46 +277,19 @@
 
 	private final ArrayList<Field> _fields = new ArrayList<Field>(20);
 	private final HashMap<Buffer,Field> _names = new HashMap<Buffer,Field>(32);
-	
-	/* ------------------------------------------------------------ */
-	/**
-	 * Constructor.
-	 */
-	public HttpFields()
-	{
-	}
-
-	// TODO externalize this cache so it can be configurable
-	private static ConcurrentMap<String, Buffer> __cache = new ConcurrentHashMap<String, Buffer>();
-	private static int __cacheSize = Integer.getInteger("org.eclipse.jetty.http.HttpFields.CACHE",2000);
-	
-	/* -------------------------------------------------------------- */
+/*
 	private Buffer convertValue(String value)
 	{
-		Buffer buffer = __cache.get(value);
-		if (buffer!=null)
-			return buffer;
-		
 		try
 		{   
-			buffer = new ByteArrayBuffer(value,StringUtil.__ISO_8859_1);
-			
-			if (__cacheSize>0)
-			{
-				if (__cache.size()>__cacheSize)
-					__cache.clear();
-				Buffer b=__cache.putIfAbsent(value,buffer);
-				if (b!=null)
-					buffer=b;
-			}
-			
-			return buffer;
+			return new ByteArrayBuffer(value,StringUtil.__ISO_8859_1);
 		}
 		catch (UnsupportedEncodingException e)
 		{
 			throw new RuntimeException(e);
 		}
 	}
+*/
 	
 	/* -------------------------------------------------------------- */
 	/**
@@ -423,19 +396,6 @@
 
 	/* -------------------------------------------------------------- */
 	/**
-	 * @return the value of a field, or null if not found. For multiple fields of the same name,
-	 *         only the first is returned.
-	 * @param name the case-insensitive field name
-	 */
-	public Buffer get(Buffer name)
-	{
-		Field field = getField(name);
-		return field==null?null:field._value;
-	}
-
-
-	/* -------------------------------------------------------------- */
-	/**
 	 * Get multi headers
 	 * 
 	 * @return Enumeration of the values, or null if no such header.
@@ -444,17 +404,17 @@
 	public Collection<String> getValuesCollection(String name)
 	{
 		Field field = getField(name);
-	if (field==null)
-		return null;
-
-		final List<String> list = new ArrayList<String>();
-
-	while(field!=null)
-	{
-		list.add(field.getValue());
-		field=field._next;
-	}
-	return list;
+		if (field==null)
+			return null;
+	
+			final List<String> list = new ArrayList<String>();
+	
+		while(field!=null)
+		{
+			list.add(field.getValue());
+			field=field._next;
+		}
+		return list;
 	}
 
 	/* -------------------------------------------------------------- */
@@ -584,8 +544,7 @@
 		else
 		{
 			Buffer n = HttpHeaders.CACHE.lookup(name);
-			Buffer v = convertValue(value);
-			put(n, v);
+			put(n, value);
 		}
 	}
 
@@ -598,9 +557,23 @@
 	 */
 	public void put(Buffer name, String value)
 	{
+/*
 		Buffer n = HttpHeaders.CACHE.lookup(name);
 		Buffer v = convertValue(value);
 		put(n, v);
+*/
+		remove(name);
+		if (value == null)
+			return;
+
+		if (!(name instanceof BufferCache.CachedBuffer)) 
+			name = HttpHeaders.CACHE.lookup(name);
+		int valueOrdinal = HttpHeaderValues.CACHE.getOrdinal(value);
+		
+		// new value;
+		Field field = new Field(name, value, valueOrdinal);
+		_fields.add(field);
+		_names.put(name, field);
 	}
 
 	/* -------------------------------------------------------------- */
@@ -612,6 +585,7 @@
 	 */
 	public void put(Buffer name, Buffer value)
 	{
+/*
 		remove(name);
 		if (value == null)
 			return;
@@ -619,46 +593,15 @@
 		if (!(name instanceof BufferCache.CachedBuffer)) 
 			name = HttpHeaders.CACHE.lookup(name);
 		if (!(value instanceof CachedBuffer))
-			value= HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer();
+			value = HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer();
 		
 		// new value;
 		Field field = new Field(name, value);
 		_fields.add(field);
 		_names.put(name, field);
-	}
-
-	/* -------------------------------------------------------------- */
-	/**
-	 * Set a field.
-	 * 
-	 * @param name the name of the field
-	 * @param list the List value of the field. If null the field is cleared.
-	 */
-	public void put(String name, List<?> list)
-	{
-		if (list == null || list.size() == 0)
-		{
-			remove(name);
-			return;
-		}
-		Buffer n = HttpHeaders.CACHE.lookup(name);
-
-		Object v = list.get(0);
-		if (v != null)
-			put(n, HttpHeaderValues.CACHE.lookup(v.toString()));
-		else
-			remove(n);
-
-		if (list.size() > 1)
-		{
-			java.util.Iterator<?> iter = list.iterator();
-			iter.next();
-			while (iter.hasNext())
-			{
-				v = iter.next();
-				if (v != null) put(n, HttpHeaderValues.CACHE.lookup(v.toString()));
-			}
-		}
+*/
+		String s = value==null ? null : value.toString();
+		put(name,s);
 	}
 
 	/* -------------------------------------------------------------- */
@@ -676,8 +619,7 @@
 		if (value==null)
 			return;
 		Buffer n = HttpHeaders.CACHE.lookup(name);
-		Buffer v = convertValue(value);
-		add(n, v);
+		add(n, value);
 	}
 
 	/* -------------------------------------------------------------- */
@@ -690,18 +632,18 @@
 	 * @exception IllegalArgumentException If the name is a single valued field and already has a
 	 *                value.
 	 */
-	public void add(Buffer name, Buffer value) throws IllegalArgumentException
+	public void add(Buffer name, String value) throws IllegalArgumentException
 	{   
 		if (value == null) throw new IllegalArgumentException("null value");
 
 		if (!(name instanceof CachedBuffer))
 			name = HttpHeaders.CACHE.lookup(name);
 		name=name.asImmutableBuffer();
-		
+/*
 		if (!(value instanceof CachedBuffer) && HttpHeaderValues.hasKnownValues(HttpHeaders.CACHE.getOrdinal(name)))
 			value= HttpHeaderValues.CACHE.lookup(value);
 		value=value.asImmutableBuffer();
-		
+*/
 		Field field = _names.get(name);
 		Field last = null;
 		while (field != null)
@@ -711,7 +653,8 @@
 		}
 
 		// create the field
-		field = new Field(name, value);
+		int valueOrdinal = HttpHeaderValues.CACHE.getOrdinal(value);
+		field = new Field(name, value, valueOrdinal);
 		_fields.add(field);
 
 		// look for chain to add too
@@ -791,7 +734,7 @@
 		if (field == null) 
 			return -1;
 
-		String val = valueParameters(BufferUtil.to8859_1_String(field._value), null);
+		String val = valueParameters(field._value, null);
 		if (val == null) 
 			return -1;
 
@@ -810,7 +753,8 @@
 	 */
 	public void putLongField(Buffer name, long value)
 	{
-		Buffer v = BufferUtil.toBuffer(value);
+//		Buffer v = BufferUtil.toBuffer(value);
+		String v = Long.toString(value);
 		put(name, v);
 	}
 
@@ -824,7 +768,8 @@
 	public void putLongField(String name, long value)
 	{
 		Buffer n = HttpHeaders.CACHE.lookup(name);
-		Buffer v = BufferUtil.toBuffer(value);
+//		Buffer v = BufferUtil.toBuffer(value);
+		String v = Long.toString(value);
 		put(n, v);
 	}
 
@@ -838,7 +783,8 @@
 	public void addLongField(String name, long value)
 	{
 		Buffer n = HttpHeaders.CACHE.lookup(name);
-		Buffer v = BufferUtil.toBuffer(value);
+//		Buffer v = BufferUtil.toBuffer(value);
+		String v = Long.toString(value);
 		add(n, v);
 	}
 
@@ -851,7 +797,8 @@
 	 */
 	public void addLongField(Buffer name, long value)
 	{
-		Buffer v = BufferUtil.toBuffer(value);
+//		Buffer v = BufferUtil.toBuffer(value);
+		String v = Long.toString(value);
 		add(name, v);
 	}
 
@@ -893,8 +840,8 @@
 	{
 		String d=formatDate(date);
 		Buffer n = HttpHeaders.CACHE.lookup(name);
-		Buffer v = new ByteArrayBuffer(d);
-		add(n, v);
+//		Buffer v = new ByteArrayBuffer(d);
+		add(n, d);
 	}
 
 	/* ------------------------------------------------------------ */
@@ -1028,25 +975,13 @@
 			field=field._next;
 		}
 
-		add(HttpHeaders.SET_COOKIE_BUFFER, new ByteArrayBuffer(name_value_params));
+		add(HttpHeaders.SET_COOKIE_BUFFER, name_value_params);
 		
 		// Expire responses with set-cookie headers so they do not get cached.
 		put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER);
 	}
 
-	/* -------------------------------------------------------------- */
-	public void putTo(Buffer buffer) throws IOException
-	{
-		for (int i = 0; i < _fields.size(); i++)
-		{
-			Field field = _fields.get(i);
-			if (field != null) 
-				field.putTo(buffer);
-		}
-		BufferUtil.putCRLF(buffer);
-	}
-
-	/* -------------------------------------------------------------- */
+	@Override
 	public String toString()
 	{
 		try
@@ -1221,24 +1156,27 @@
 		return vl;
 	}
 
-	/* ------------------------------------------------------------ */
-	/* ------------------------------------------------------------ */
-	/* ------------------------------------------------------------ */
+
 	public static final class Field
 	{
-		private Buffer _name;
-		private Buffer _value;
+		private final Buffer _name;
+		private final String _value;
+		private final int _valueOrdinal;
 		private Field _next;
 
-		/* ------------------------------------------------------------ */
-		private Field(Buffer name, Buffer value)
+		private Field(Buffer name, String value, int valueOrdinal)
 		{
 			_name = name;
 			_value = value;
+			_valueOrdinal = valueOrdinal;
 			_next = null;
 		}
-		
-		/* ------------------------------------------------------------ */
+/*
+		private Field(Buffer name, Buffer value)
+		{
+			this(name,value.toString(),HttpHeaderValues.CACHE.getOrdinal(value));
+		}
+*/
 		public void putTo(Buffer buffer) throws IOException
 		{
 			int o=(_name instanceof CachedBuffer)?((CachedBuffer)_name).getOrdinal():-1;
@@ -1266,16 +1204,13 @@
 			buffer.put((byte) ':');
 			buffer.put((byte) ' ');
 			
-			o=(_value instanceof CachedBuffer)?((CachedBuffer)_value).getOrdinal():-1;
+			o = _valueOrdinal;
+			byte[] valueBytes = StringUtil.getBytes(_value);
 			if (o>=0)
-				buffer.put(_value);
+				buffer.put(valueBytes);
 			else
 			{
-				int s=_value.getIndex();
-				int e=_value.putIndex();
-				while (s<e)
-				{
-					byte b=_value.peek(s++);
+				for( byte b : valueBytes ) {
 					switch(b)
 					{
 						case '\r':
@@ -1290,55 +1225,37 @@
 			BufferUtil.putCRLF(buffer);
 		}
 
-		/* ------------------------------------------------------------ */
-		public String getName()
+		private String getName()
 		{
 			return BufferUtil.to8859_1_String(_name);
 		}
 
-		/* ------------------------------------------------------------ */
-		Buffer getNameBuffer()
-		{
-			return _name;
-		}
-
-		/* ------------------------------------------------------------ */
 		public int getNameOrdinal()
 		{
 			return HttpHeaders.CACHE.getOrdinal(_name);
 		}
 
-		/* ------------------------------------------------------------ */
 		public String getValue()
 		{
-			return BufferUtil.to8859_1_String(_value);
-		}
-
-		/* ------------------------------------------------------------ */
-		public Buffer getValueBuffer()
-		{
 			return _value;
 		}
 
-		/* ------------------------------------------------------------ */
 		public int getValueOrdinal()
 		{
-			return HttpHeaderValues.CACHE.getOrdinal(_value);
+			return _valueOrdinal;
 		}
 
-		/* ------------------------------------------------------------ */
 		public int getIntValue()
 		{
 			return (int) getLongValue();
 		}
 
-		/* ------------------------------------------------------------ */
 		public long getLongValue()
 		{
 			return BufferUtil.toLong(_value);
 		}
 
-		/* ------------------------------------------------------------ */
+		@Override
 		public String toString()
 		{
 			return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]");
--- a/src/org/eclipse/jetty/http/HttpGenerator.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/http/HttpGenerator.java	Mon Oct 31 22:24:41 2016 -0600
@@ -458,7 +458,9 @@
 							break;
 
 						case HttpHeaders.CONTENT_TYPE_ORDINAL:
-							if (BufferUtil.isPrefix(MimeTypes.MULTIPART_BYTERANGES_BUFFER, field.getValueBuffer())) _contentLength = HttpTokens.SELF_DEFINING_CONTENT;
+//							if (BufferUtil.isPrefix(MimeTypes.MULTIPART_BYTERANGES_BUFFER, field.getValueBuffer()))
+							if (field.getValue().startsWith(MimeTypes.MULTIPART_BYTERANGES))
+								_contentLength = HttpTokens.SELF_DEFINING_CONTENT;
 
 							// write the field to the header buffer
 							content_type=true;
@@ -483,11 +485,11 @@
 									String[] values = field.getValue().split(",");
 									for  (int i=0;values!=null && i<values.length;i++)
 									{
-										CachedBuffer cb = HttpHeaderValues.CACHE.get(values[i].trim());
+										int ord = HttpHeaderValues.CACHE.getOrdinal(values[i].trim());
 
-										if (cb!=null)
+										if (ord != -1)
 										{
-											switch(cb.getOrdinal())
+											switch(ord)
 											{
 												case HttpHeaderValues.CLOSE_ORDINAL:
 													close=true;
--- a/src/org/eclipse/jetty/http/HttpHeaderValues.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/http/HttpHeaderValues.java	Mon Oct 31 22:24:41 2016 -0600
@@ -18,19 +18,16 @@
 
 package org.eclipse.jetty.http;
 
-import org.eclipse.jetty.io.Buffer;
-import org.eclipse.jetty.io.BufferCache;
-import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.StringCache;
 
 /**
  * Cached HTTP Header values.
- * This class caches the conversion of common HTTP Header values to and from {@link ByteArrayBuffer} instances.
  * The resource "/org/eclipse/jetty/useragents" is checked for a list of common user agents, so that repeated
  * creation of strings for these agents can be avoided.
  * 
  * 
  */
-public class HttpHeaderValues extends BufferCache
+public final class HttpHeaderValues
 {
 	public final static String
 		CLOSE="close",
@@ -58,20 +55,20 @@
 		NO_CACHE_ORDINAL=10,
 		UPGRADE_ORDINAL=11;
 	
-	public final static HttpHeaderValues CACHE = new HttpHeaderValues();
+    public final static StringCache CACHE = new StringCache();
 
-	public final static Buffer 
-		CLOSE_BUFFER=CACHE.add(CLOSE,CLOSE_ORDINAL),
-		CHUNKED_BUFFER=CACHE.add(CHUNKED,CHUNKED_ORDINAL),
-		GZIP_BUFFER=CACHE.add(GZIP,GZIP_ORDINAL),
-		IDENTITY_BUFFER=CACHE.add(IDENTITY,IDENTITY_ORDINAL),
-		KEEP_ALIVE_BUFFER=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL),
-		CONTINUE_BUFFER=CACHE.add(CONTINUE, CONTINUE_ORDINAL),
-		PROCESSING_BUFFER=CACHE.add(PROCESSING, PROCESSING_ORDINAL),
-		TE_BUFFER=CACHE.add(TE,TE_ORDINAL),
-		BYTES_BUFFER=CACHE.add(BYTES,BYTES_ORDINAL),
-		NO_CACHE_BUFFER=CACHE.add(NO_CACHE,NO_CACHE_ORDINAL),
-		UPGRADE_BUFFER=CACHE.add(UPGRADE,UPGRADE_ORDINAL);
+	public final static byte[] 
+		CLOSE_BYTES=CACHE.add(CLOSE,CLOSE_ORDINAL),
+		CHUNKED_BYTES=CACHE.add(CHUNKED,CHUNKED_ORDINAL),
+		GZIP_BYTES=CACHE.add(GZIP,GZIP_ORDINAL),
+		IDENTITY_BYTES=CACHE.add(IDENTITY,IDENTITY_ORDINAL),
+		KEEP_ALIVE_BYTES=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL),
+		CONTINUE_BYTES=CACHE.add(CONTINUE, CONTINUE_ORDINAL),
+		PROCESSING_BYTES=CACHE.add(PROCESSING, PROCESSING_ORDINAL),
+		TE_BYTES=CACHE.add(TE,TE_ORDINAL),
+		BYTES_BYTES=CACHE.add(BYTES,BYTES_ORDINAL),
+		NO_CACHE_BYTES=CACHE.add(NO_CACHE,NO_CACHE_ORDINAL),
+		UPGRADE_BYTES=CACHE.add(UPGRADE,UPGRADE_ORDINAL);
 		
 
 	public static boolean hasKnownValues(int httpHeaderOrdinal)
--- a/src/org/eclipse/jetty/http/HttpParser.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/http/HttpParser.java	Mon Oct 31 22:24:41 2016 -0600
@@ -438,7 +438,7 @@
 								{
 									Buffer header=_cached!=null?_cached:HttpHeaders.CACHE.lookup(_tok0);
 									_cached=null;
-									Buffer value=_multiLineValue == null ? _tok1 : new ByteArrayBuffer(_multiLineValue);
+									String value = _multiLineValue == null ? _tok1.toString() : _multiLineValue;
 
 									int ho=HttpHeaders.CACHE.getOrdinal(header);
 									if (ho >= 0)
@@ -465,17 +465,16 @@
 												break;
 
 											case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
-												value=HttpHeaderValues.CACHE.lookup(value);
-												vo=HttpHeaderValues.CACHE.getOrdinal(value);
+//												value=HttpHeaderValues.CACHE.lookup(value);
+												vo = HttpHeaderValues.CACHE.getOrdinal(value);
 												if (HttpHeaderValues.CHUNKED_ORDINAL == vo)
 													_contentLength=HttpTokens.CHUNKED_CONTENT;
 												else
 												{
-													String c=value.toString(StringUtil.__ISO_8859_1);
-													if (c.endsWith(HttpHeaderValues.CHUNKED))
+													if (value.endsWith(HttpHeaderValues.CHUNKED))
 														_contentLength=HttpTokens.CHUNKED_CONTENT;
 
-													else if (c.indexOf(HttpHeaderValues.CHUNKED) >= 0)
+													else if (value.indexOf(HttpHeaderValues.CHUNKED) >= 0)
 														throw new HttpException(400,null);
 												}
 												break;
@@ -493,7 +492,7 @@
 
 													case -1: // No match, may be multi valued
 													{
-														for (String v : value.toString().split(","))
+														for (String v : value.split(","))
 														{
 															switch(HttpHeaderValues.CACHE.getOrdinal(v.trim()))
 															{
@@ -1143,7 +1142,7 @@
 		/**
 		 * This is the method called by parser when a HTTP Header name and value is found
 		 */
-		public void parsedHeader(Buffer name, Buffer value) throws IOException;
+		public void parsedHeader(Buffer name, String value) throws IOException;
 
 		/**
 		 * This is the method called by parser when the HTTP request line is parsed
--- a/src/org/eclipse/jetty/http/MimeTypes.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/http/MimeTypes.java	Mon Oct 31 22:24:41 2016 -0600
@@ -39,338 +39,338 @@
  */
 public class MimeTypes
 {
-    private static final Logger LOG = LoggerFactory.getLogger(MimeTypes.class);
+	private static final Logger LOG = LoggerFactory.getLogger(MimeTypes.class);
 
-    public final static String
-      FORM_ENCODED="application/x-www-form-urlencoded",
-      MESSAGE_HTTP="message/http",
-      MULTIPART_BYTERANGES="multipart/byteranges",
-      
-      TEXT_HTML="text/html",
-      TEXT_PLAIN="text/plain",
-      TEXT_XML="text/xml",
-      TEXT_JSON="text/json",
-      
-      TEXT_HTML_8859_1="text/html;charset=ISO-8859-1",
-      TEXT_PLAIN_8859_1="text/plain;charset=ISO-8859-1",
-      TEXT_XML_8859_1="text/xml;charset=ISO-8859-1",
-      
-      TEXT_HTML_UTF_8="text/html;charset=UTF-8",
-      TEXT_PLAIN_UTF_8="text/plain;charset=UTF-8",
-      TEXT_XML_UTF_8="text/xml;charset=UTF-8",
-      TEXT_JSON_UTF_8="text/json;charset=UTF-8";
+	public final static String
+	  FORM_ENCODED="application/x-www-form-urlencoded",
+	  MESSAGE_HTTP="message/http",
+	  MULTIPART_BYTERANGES="multipart/byteranges",
+	  
+	  TEXT_HTML="text/html",
+	  TEXT_PLAIN="text/plain",
+	  TEXT_XML="text/xml",
+	  TEXT_JSON="text/json",
+	  
+	  TEXT_HTML_8859_1="text/html;charset=ISO-8859-1",
+	  TEXT_PLAIN_8859_1="text/plain;charset=ISO-8859-1",
+	  TEXT_XML_8859_1="text/xml;charset=ISO-8859-1",
+	  
+	  TEXT_HTML_UTF_8="text/html;charset=UTF-8",
+	  TEXT_PLAIN_UTF_8="text/plain;charset=UTF-8",
+	  TEXT_XML_UTF_8="text/xml;charset=UTF-8",
+	  TEXT_JSON_UTF_8="text/json;charset=UTF-8";
 
-    private final static String
-      TEXT_HTML__8859_1="text/html; charset=ISO-8859-1",
-      TEXT_PLAIN__8859_1="text/plain; charset=ISO-8859-1",
-      TEXT_XML__8859_1="text/xml; charset=ISO-8859-1",
-      TEXT_HTML__UTF_8="text/html; charset=UTF-8",
-      TEXT_PLAIN__UTF_8="text/plain; charset=UTF-8",
-      TEXT_XML__UTF_8="text/xml; charset=UTF-8",
-      TEXT_JSON__UTF_8="text/json; charset=UTF-8";
+	private final static String
+	  TEXT_HTML__8859_1="text/html; charset=ISO-8859-1",
+	  TEXT_PLAIN__8859_1="text/plain; charset=ISO-8859-1",
+	  TEXT_XML__8859_1="text/xml; charset=ISO-8859-1",
+	  TEXT_HTML__UTF_8="text/html; charset=UTF-8",
+	  TEXT_PLAIN__UTF_8="text/plain; charset=UTF-8",
+	  TEXT_XML__UTF_8="text/xml; charset=UTF-8",
+	  TEXT_JSON__UTF_8="text/json; charset=UTF-8";
 
-    private final static int
+	private final static int
 	FORM_ENCODED_ORDINAL=1,
-    	MESSAGE_HTTP_ORDINAL=2,
-    	MULTIPART_BYTERANGES_ORDINAL=3,
-    	
-    	TEXT_HTML_ORDINAL=4,
+		MESSAGE_HTTP_ORDINAL=2,
+		MULTIPART_BYTERANGES_ORDINAL=3,
+		
+		TEXT_HTML_ORDINAL=4,
 	TEXT_PLAIN_ORDINAL=5,
 	TEXT_XML_ORDINAL=6,
-        TEXT_JSON_ORDINAL=7,
+		TEXT_JSON_ORDINAL=7,
 	
-        TEXT_HTML_8859_1_ORDINAL=8,
-        TEXT_PLAIN_8859_1_ORDINAL=9,
-        TEXT_XML_8859_1_ORDINAL=10,
-        
-        TEXT_HTML_UTF_8_ORDINAL=11,
-        TEXT_PLAIN_UTF_8_ORDINAL=12,
-        TEXT_XML_UTF_8_ORDINAL=13,
-        TEXT_JSON_UTF_8_ORDINAL=14;
-    
-    private static int __index=15;
-    
-    public final static BufferCache CACHE = new BufferCache(); 
+		TEXT_HTML_8859_1_ORDINAL=8,
+		TEXT_PLAIN_8859_1_ORDINAL=9,
+		TEXT_XML_8859_1_ORDINAL=10,
+		
+		TEXT_HTML_UTF_8_ORDINAL=11,
+		TEXT_PLAIN_UTF_8_ORDINAL=12,
+		TEXT_XML_UTF_8_ORDINAL=13,
+		TEXT_JSON_UTF_8_ORDINAL=14;
+	
+	private static int __index=15;
+	
+	public final static BufferCache CACHE = new BufferCache(); 
 
-    public final static CachedBuffer
-    	FORM_ENCODED_BUFFER=CACHE.add(FORM_ENCODED,FORM_ENCODED_ORDINAL),
-    	MESSAGE_HTTP_BUFFER=CACHE.add(MESSAGE_HTTP, MESSAGE_HTTP_ORDINAL),
-    	MULTIPART_BYTERANGES_BUFFER=CACHE.add(MULTIPART_BYTERANGES,MULTIPART_BYTERANGES_ORDINAL),
-        
-        TEXT_HTML_BUFFER=CACHE.add(TEXT_HTML,TEXT_HTML_ORDINAL),
-        TEXT_PLAIN_BUFFER=CACHE.add(TEXT_PLAIN,TEXT_PLAIN_ORDINAL),
-        TEXT_XML_BUFFER=CACHE.add(TEXT_XML,TEXT_XML_ORDINAL),
-        TEXT_JSON_BUFFER=CACHE.add(TEXT_JSON,TEXT_JSON_ORDINAL),
+	public final static CachedBuffer
+		FORM_ENCODED_BUFFER=CACHE.add(FORM_ENCODED,FORM_ENCODED_ORDINAL),
+		MESSAGE_HTTP_BUFFER=CACHE.add(MESSAGE_HTTP, MESSAGE_HTTP_ORDINAL),
+		MULTIPART_BYTERANGES_BUFFER=CACHE.add(MULTIPART_BYTERANGES,MULTIPART_BYTERANGES_ORDINAL),
+		
+		TEXT_HTML_BUFFER=CACHE.add(TEXT_HTML,TEXT_HTML_ORDINAL),
+		TEXT_PLAIN_BUFFER=CACHE.add(TEXT_PLAIN,TEXT_PLAIN_ORDINAL),
+		TEXT_XML_BUFFER=CACHE.add(TEXT_XML,TEXT_XML_ORDINAL),
+		TEXT_JSON_BUFFER=CACHE.add(TEXT_JSON,TEXT_JSON_ORDINAL),
 
-        TEXT_HTML_8859_1_BUFFER=CACHE.add(TEXT_HTML_8859_1,TEXT_HTML_8859_1_ORDINAL),
-        TEXT_PLAIN_8859_1_BUFFER=CACHE.add(TEXT_PLAIN_8859_1,TEXT_PLAIN_8859_1_ORDINAL),
-        TEXT_XML_8859_1_BUFFER=CACHE.add(TEXT_XML_8859_1,TEXT_XML_8859_1_ORDINAL),
-        
-        TEXT_HTML_UTF_8_BUFFER=CACHE.add(TEXT_HTML_UTF_8,TEXT_HTML_UTF_8_ORDINAL),
-        TEXT_PLAIN_UTF_8_BUFFER=CACHE.add(TEXT_PLAIN_UTF_8,TEXT_PLAIN_UTF_8_ORDINAL),
-        TEXT_XML_UTF_8_BUFFER=CACHE.add(TEXT_XML_UTF_8,TEXT_XML_UTF_8_ORDINAL),
-        TEXT_JSON_UTF_8_BUFFER=CACHE.add(TEXT_JSON_UTF_8,TEXT_JSON_UTF_8_ORDINAL),
+		TEXT_HTML_8859_1_BUFFER=CACHE.add(TEXT_HTML_8859_1,TEXT_HTML_8859_1_ORDINAL),
+		TEXT_PLAIN_8859_1_BUFFER=CACHE.add(TEXT_PLAIN_8859_1,TEXT_PLAIN_8859_1_ORDINAL),
+		TEXT_XML_8859_1_BUFFER=CACHE.add(TEXT_XML_8859_1,TEXT_XML_8859_1_ORDINAL),
+		
+		TEXT_HTML_UTF_8_BUFFER=CACHE.add(TEXT_HTML_UTF_8,TEXT_HTML_UTF_8_ORDINAL),
+		TEXT_PLAIN_UTF_8_BUFFER=CACHE.add(TEXT_PLAIN_UTF_8,TEXT_PLAIN_UTF_8_ORDINAL),
+		TEXT_XML_UTF_8_BUFFER=CACHE.add(TEXT_XML_UTF_8,TEXT_XML_UTF_8_ORDINAL),
+		TEXT_JSON_UTF_8_BUFFER=CACHE.add(TEXT_JSON_UTF_8,TEXT_JSON_UTF_8_ORDINAL),
 
-        TEXT_HTML__8859_1_BUFFER=CACHE.add(TEXT_HTML__8859_1,TEXT_HTML_8859_1_ORDINAL),
-        TEXT_PLAIN__8859_1_BUFFER=CACHE.add(TEXT_PLAIN__8859_1,TEXT_PLAIN_8859_1_ORDINAL),
-        TEXT_XML__8859_1_BUFFER=CACHE.add(TEXT_XML__8859_1,TEXT_XML_8859_1_ORDINAL),
-        
-        TEXT_HTML__UTF_8_BUFFER=CACHE.add(TEXT_HTML__UTF_8,TEXT_HTML_UTF_8_ORDINAL),
-        TEXT_PLAIN__UTF_8_BUFFER=CACHE.add(TEXT_PLAIN__UTF_8,TEXT_PLAIN_UTF_8_ORDINAL),
-        TEXT_XML__UTF_8_BUFFER=CACHE.add(TEXT_XML__UTF_8,TEXT_XML_UTF_8_ORDINAL),
-        TEXT_JSON__UTF_8_BUFFER=CACHE.add(TEXT_JSON__UTF_8,TEXT_JSON_UTF_8_ORDINAL);
+		TEXT_HTML__8859_1_BUFFER=CACHE.add(TEXT_HTML__8859_1,TEXT_HTML_8859_1_ORDINAL),
+		TEXT_PLAIN__8859_1_BUFFER=CACHE.add(TEXT_PLAIN__8859_1,TEXT_PLAIN_8859_1_ORDINAL),
+		TEXT_XML__8859_1_BUFFER=CACHE.add(TEXT_XML__8859_1,TEXT_XML_8859_1_ORDINAL),
+		
+		TEXT_HTML__UTF_8_BUFFER=CACHE.add(TEXT_HTML__UTF_8,TEXT_HTML_UTF_8_ORDINAL),
+		TEXT_PLAIN__UTF_8_BUFFER=CACHE.add(TEXT_PLAIN__UTF_8,TEXT_PLAIN_UTF_8_ORDINAL),
+		TEXT_XML__UTF_8_BUFFER=CACHE.add(TEXT_XML__UTF_8,TEXT_XML_UTF_8_ORDINAL),
+		TEXT_JSON__UTF_8_BUFFER=CACHE.add(TEXT_JSON__UTF_8,TEXT_JSON_UTF_8_ORDINAL);
 
-    
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    private final static Map __dftMimeMap = new HashMap();
-    private final static Map __encodings = new HashMap();
-    static
-    {
-        try
-        {
-            ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime");
-            Enumeration i = mime.getKeys();
-            while(i.hasMoreElements())
-            {
-                String ext = (String)i.nextElement();
-                String m = mime.getString(ext);
-                __dftMimeMap.put(StringUtil.asciiToLowerCase(ext),normalizeMimeType(m));
-            }
-        }
-        catch(MissingResourceException e)
-        {
-            LOG.warn(e.toString());
-            LOG.debug("",e);
-        }
+	
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	private final static Map __dftMimeMap = new HashMap();
+	private final static Map __encodings = new HashMap();
+	static
+	{
+		try
+		{
+			ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime");
+			Enumeration i = mime.getKeys();
+			while(i.hasMoreElements())
+			{
+				String ext = (String)i.nextElement();
+				String m = mime.getString(ext);
+				__dftMimeMap.put(StringUtil.asciiToLowerCase(ext),normalizeMimeType(m));
+			}
+		}
+		catch(MissingResourceException e)
+		{
+			LOG.warn(e.toString());
+			LOG.debug("",e);
+		}
 
-        try
-        {
-            ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding");
-            Enumeration i = encoding.getKeys();
-            while(i.hasMoreElements())
-            {
-                Buffer type = normalizeMimeType((String)i.nextElement());
-                __encodings.put(type,encoding.getString(type.toString()));
-            }
-        }
-        catch(MissingResourceException e)
-        {
-            LOG.warn(e.toString());
-            LOG.debug("",e);
-        }
+		try
+		{
+			ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding");
+			Enumeration i = encoding.getKeys();
+			while(i.hasMoreElements())
+			{
+				Buffer type = normalizeMimeType((String)i.nextElement());
+				__encodings.put(type,encoding.getString(type.toString()));
+			}
+		}
+		catch(MissingResourceException e)
+		{
+			LOG.warn(e.toString());
+			LOG.debug("",e);
+		}
 
-        
-        TEXT_HTML_BUFFER.setAssociate("ISO-8859-1",TEXT_HTML_8859_1_BUFFER);
-        TEXT_HTML_BUFFER.setAssociate("ISO_8859_1",TEXT_HTML_8859_1_BUFFER);
-        TEXT_HTML_BUFFER.setAssociate("iso-8859-1",TEXT_HTML_8859_1_BUFFER);
-        TEXT_PLAIN_BUFFER.setAssociate("ISO-8859-1",TEXT_PLAIN_8859_1_BUFFER);
-        TEXT_PLAIN_BUFFER.setAssociate("ISO_8859_1",TEXT_PLAIN_8859_1_BUFFER);
-        TEXT_PLAIN_BUFFER.setAssociate("iso-8859-1",TEXT_PLAIN_8859_1_BUFFER);
-        TEXT_XML_BUFFER.setAssociate("ISO-8859-1",TEXT_XML_8859_1_BUFFER);
-        TEXT_XML_BUFFER.setAssociate("ISO_8859_1",TEXT_XML_8859_1_BUFFER);
-        TEXT_XML_BUFFER.setAssociate("iso-8859-1",TEXT_XML_8859_1_BUFFER);
+		
+		TEXT_HTML_BUFFER.setAssociate("ISO-8859-1",TEXT_HTML_8859_1_BUFFER);
+		TEXT_HTML_BUFFER.setAssociate("ISO_8859_1",TEXT_HTML_8859_1_BUFFER);
+		TEXT_HTML_BUFFER.setAssociate("iso-8859-1",TEXT_HTML_8859_1_BUFFER);
+		TEXT_PLAIN_BUFFER.setAssociate("ISO-8859-1",TEXT_PLAIN_8859_1_BUFFER);
+		TEXT_PLAIN_BUFFER.setAssociate("ISO_8859_1",TEXT_PLAIN_8859_1_BUFFER);
+		TEXT_PLAIN_BUFFER.setAssociate("iso-8859-1",TEXT_PLAIN_8859_1_BUFFER);
+		TEXT_XML_BUFFER.setAssociate("ISO-8859-1",TEXT_XML_8859_1_BUFFER);
+		TEXT_XML_BUFFER.setAssociate("ISO_8859_1",TEXT_XML_8859_1_BUFFER);
+		TEXT_XML_BUFFER.setAssociate("iso-8859-1",TEXT_XML_8859_1_BUFFER);
 
-        TEXT_HTML_BUFFER.setAssociate("UTF-8",TEXT_HTML_UTF_8_BUFFER);
-        TEXT_HTML_BUFFER.setAssociate("UTF8",TEXT_HTML_UTF_8_BUFFER);
-        TEXT_HTML_BUFFER.setAssociate("utf8",TEXT_HTML_UTF_8_BUFFER);
-        TEXT_HTML_BUFFER.setAssociate("utf-8",TEXT_HTML_UTF_8_BUFFER);
-        TEXT_PLAIN_BUFFER.setAssociate("UTF-8",TEXT_PLAIN_UTF_8_BUFFER);
-        TEXT_PLAIN_BUFFER.setAssociate("UTF8",TEXT_PLAIN_UTF_8_BUFFER);
-        TEXT_PLAIN_BUFFER.setAssociate("utf8",TEXT_PLAIN_UTF_8_BUFFER);
-        TEXT_PLAIN_BUFFER.setAssociate("utf-8",TEXT_PLAIN_UTF_8_BUFFER);
-        TEXT_XML_BUFFER.setAssociate("UTF-8",TEXT_XML_UTF_8_BUFFER);
-        TEXT_XML_BUFFER.setAssociate("UTF8",TEXT_XML_UTF_8_BUFFER);
-        TEXT_XML_BUFFER.setAssociate("utf8",TEXT_XML_UTF_8_BUFFER);
-        TEXT_XML_BUFFER.setAssociate("utf-8",TEXT_XML_UTF_8_BUFFER);
-        TEXT_JSON_BUFFER.setAssociate("UTF-8",TEXT_JSON_UTF_8_BUFFER);
-        TEXT_JSON_BUFFER.setAssociate("UTF8",TEXT_JSON_UTF_8_BUFFER);
-        TEXT_JSON_BUFFER.setAssociate("utf8",TEXT_JSON_UTF_8_BUFFER);
-        TEXT_JSON_BUFFER.setAssociate("utf-8",TEXT_JSON_UTF_8_BUFFER);
-    }
+		TEXT_HTML_BUFFER.setAssociate("UTF-8",TEXT_HTML_UTF_8_BUFFER);
+		TEXT_HTML_BUFFER.setAssociate("UTF8",TEXT_HTML_UTF_8_BUFFER);
+		TEXT_HTML_BUFFER.setAssociate("utf8",TEXT_HTML_UTF_8_BUFFER);
+		TEXT_HTML_BUFFER.setAssociate("utf-8",TEXT_HTML_UTF_8_BUFFER);
+		TEXT_PLAIN_BUFFER.setAssociate("UTF-8",TEXT_PLAIN_UTF_8_BUFFER);
+		TEXT_PLAIN_BUFFER.setAssociate("UTF8",TEXT_PLAIN_UTF_8_BUFFER);
+		TEXT_PLAIN_BUFFER.setAssociate("utf8",TEXT_PLAIN_UTF_8_BUFFER);
+		TEXT_PLAIN_BUFFER.setAssociate("utf-8",TEXT_PLAIN_UTF_8_BUFFER);
+		TEXT_XML_BUFFER.setAssociate("UTF-8",TEXT_XML_UTF_8_BUFFER);
+		TEXT_XML_BUFFER.setAssociate("UTF8",TEXT_XML_UTF_8_BUFFER);
+		TEXT_XML_BUFFER.setAssociate("utf8",TEXT_XML_UTF_8_BUFFER);
+		TEXT_XML_BUFFER.setAssociate("utf-8",TEXT_XML_UTF_8_BUFFER);
+		TEXT_JSON_BUFFER.setAssociate("UTF-8",TEXT_JSON_UTF_8_BUFFER);
+		TEXT_JSON_BUFFER.setAssociate("UTF8",TEXT_JSON_UTF_8_BUFFER);
+		TEXT_JSON_BUFFER.setAssociate("utf8",TEXT_JSON_UTF_8_BUFFER);
+		TEXT_JSON_BUFFER.setAssociate("utf-8",TEXT_JSON_UTF_8_BUFFER);
+	}
 
 
-    /* ------------------------------------------------------------ */
-    private Map _mimeMap;
-    
-    /* ------------------------------------------------------------ */
-    /** Constructor.
-     */
-    public MimeTypes()
-    {
-    }
+	/* ------------------------------------------------------------ */
+	private Map _mimeMap;
+	
+	/* ------------------------------------------------------------ */
+	/** Constructor.
+	 */
+	public MimeTypes()
+	{
+	}
 
-    /* ------------------------------------------------------------ */
-    public synchronized Map getMimeMap()
-    {
-        return _mimeMap;
-    }
+	/* ------------------------------------------------------------ */
+	public synchronized Map getMimeMap()
+	{
+		return _mimeMap;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param mimeMap A Map of file extension to mime-type.
-     */
-    public void setMimeMap(Map mimeMap)
-    {
-        if (mimeMap==null)
-        {
-            _mimeMap=null;
-            return;
-        }
-        
-        Map m=new HashMap();
-        Iterator i=mimeMap.entrySet().iterator();
-        while (i.hasNext())
-        {
-            Map.Entry entry = (Map.Entry)i.next();
-            m.put(entry.getKey(),normalizeMimeType(entry.getValue().toString()));
-        }
-        _mimeMap=m;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param mimeMap A Map of file extension to mime-type.
+	 */
+	public void setMimeMap(Map mimeMap)
+	{
+		if (mimeMap==null)
+		{
+			_mimeMap=null;
+			return;
+		}
+		
+		Map m=new HashMap();
+		Iterator i=mimeMap.entrySet().iterator();
+		while (i.hasNext())
+		{
+			Map.Entry entry = (Map.Entry)i.next();
+			m.put(entry.getKey(),normalizeMimeType(entry.getValue().toString()));
+		}
+		_mimeMap=m;
+	}
 
-    /* ------------------------------------------------------------ */
-    /** Get the MIME type by filename extension.
-     * @param filename A file name
-     * @return MIME type matching the longest dot extension of the
-     * file name.
-     */
-    public Buffer getMimeByExtension(String filename)
-    {
-        Buffer type=null;
+	/* ------------------------------------------------------------ */
+	/** Get the MIME type by filename extension.
+	 * @param filename A file name
+	 * @return MIME type matching the longest dot extension of the
+	 * file name.
+	 */
+	public Buffer getMimeByExtension(String filename)
+	{
+		Buffer type=null;
 
-        if (filename!=null)
-        {
-            int i=-1;
-            while(type==null)
-            {
-                i=filename.indexOf(".",i+1);
+		if (filename!=null)
+		{
+			int i=-1;
+			while(type==null)
+			{
+				i=filename.indexOf(".",i+1);
 
-                if (i<0 || i>=filename.length())
-                    break;
+				if (i<0 || i>=filename.length())
+					break;
 
-                String ext=StringUtil.asciiToLowerCase(filename.substring(i+1));
-                if (_mimeMap!=null)
-                    type = (Buffer)_mimeMap.get(ext);
-                if (type==null)
-                    type=(Buffer)__dftMimeMap.get(ext);
-            }
-        }
+				String ext=StringUtil.asciiToLowerCase(filename.substring(i+1));
+				if (_mimeMap!=null)
+					type = (Buffer)_mimeMap.get(ext);
+				if (type==null)
+					type=(Buffer)__dftMimeMap.get(ext);
+			}
+		}
 
-        if (type==null)
-        {
-            if (_mimeMap!=null)
-                type=(Buffer)_mimeMap.get("*");
-             if (type==null)
-                 type=(Buffer)__dftMimeMap.get("*");
-        }
+		if (type==null)
+		{
+			if (_mimeMap!=null)
+				type=(Buffer)_mimeMap.get("*");
+			 if (type==null)
+				 type=(Buffer)__dftMimeMap.get("*");
+		}
 
-        return type;
-    }
+		return type;
+	}
 
-    /* ------------------------------------------------------------ */
-    /** Set a mime mapping
-     * @param extension
-     * @param type
-     */
-    public void addMimeMapping(String extension,String type)
-    {
-        if (_mimeMap==null)
-            _mimeMap=new HashMap();
-        
-        _mimeMap.put(StringUtil.asciiToLowerCase(extension),normalizeMimeType(type));
-    }
+	/* ------------------------------------------------------------ */
+	/** Set a mime mapping
+	 * @param extension
+	 * @param type
+	 */
+	public void addMimeMapping(String extension,String type)
+	{
+		if (_mimeMap==null)
+			_mimeMap=new HashMap();
+		
+		_mimeMap.put(StringUtil.asciiToLowerCase(extension),normalizeMimeType(type));
+	}
 
-    /* ------------------------------------------------------------ */
-    private static synchronized Buffer normalizeMimeType(String type)
-    {
-        Buffer b =CACHE.get(type);
-        if (b==null)
-            b=CACHE.add(type,__index++);
-        return b;
-    }
+	/* ------------------------------------------------------------ */
+	private static synchronized Buffer normalizeMimeType(String type)
+	{
+		Buffer b =CACHE.get(type);
+		if (b==null)
+			b=CACHE.add(type,__index++);
+		return b;
+	}
 
-    /* ------------------------------------------------------------ */
-    public static String getCharsetFromContentType(Buffer value)
-    {
-        if (value instanceof CachedBuffer)
-        {
-            switch(((CachedBuffer)value).getOrdinal())
-            {
-                case TEXT_HTML_8859_1_ORDINAL:
-                case TEXT_PLAIN_8859_1_ORDINAL:
-                case TEXT_XML_8859_1_ORDINAL:
-                    return StringUtil.__ISO_8859_1;
+	/* ------------------------------------------------------------ */
+	public static String getCharsetFromContentType(Buffer value)
+	{
+		if (value instanceof CachedBuffer)
+		{
+			switch(((CachedBuffer)value).getOrdinal())
+			{
+				case TEXT_HTML_8859_1_ORDINAL:
+				case TEXT_PLAIN_8859_1_ORDINAL:
+				case TEXT_XML_8859_1_ORDINAL:
+					return StringUtil.__ISO_8859_1;
 
-                case TEXT_HTML_UTF_8_ORDINAL:
-                case TEXT_PLAIN_UTF_8_ORDINAL:
-                case TEXT_XML_UTF_8_ORDINAL:
-                case TEXT_JSON_UTF_8_ORDINAL:
-                    return StringUtil.__UTF8;
-            }
-        }
-        
-        int i=value.getIndex();
-        int end=value.putIndex();
-        int state=0;
-        int start=0;
-        boolean quote=false;
-        for (;i<end;i++)
-        {
-            byte b = value.peek(i);
-            
-            if (quote && state!=10)
-            {
-                if ('"'==b)
-                    quote=false;
-                continue;
-            }
-                
-            switch(state)
-            {
-                case 0:
-                    if ('"'==b)
-                    {
-                        quote=true;
-                        break;
-                    }
-                    if (';'==b)
-                        state=1;
-                    break;
+				case TEXT_HTML_UTF_8_ORDINAL:
+				case TEXT_PLAIN_UTF_8_ORDINAL:
+				case TEXT_XML_UTF_8_ORDINAL:
+				case TEXT_JSON_UTF_8_ORDINAL:
+					return StringUtil.__UTF8;
+			}
+		}
+		
+		int i=value.getIndex();
+		int end=value.putIndex();
+		int state=0;
+		int start=0;
+		boolean quote=false;
+		for (;i<end;i++)
+		{
+			byte b = value.peek(i);
+			
+			if (quote && state!=10)
+			{
+				if ('"'==b)
+					quote=false;
+				continue;
+			}
+				
+			switch(state)
+			{
+				case 0:
+					if ('"'==b)
+					{
+						quote=true;
+						break;
+					}
+					if (';'==b)
+						state=1;
+					break;
 
-                case 1: if ('c'==b) state=2; else if (' '!=b) state=0; break;
-                case 2: if ('h'==b) state=3; else state=0;break;
-                case 3: if ('a'==b) state=4; else state=0;break;
-                case 4: if ('r'==b) state=5; else state=0;break;
-                case 5: if ('s'==b) state=6; else state=0;break;
-                case 6: if ('e'==b) state=7; else state=0;break;
-                case 7: if ('t'==b) state=8; else state=0;break;
+				case 1: if ('c'==b) state=2; else if (' '!=b) state=0; break;
+				case 2: if ('h'==b) state=3; else state=0;break;
+				case 3: if ('a'==b) state=4; else state=0;break;
+				case 4: if ('r'==b) state=5; else state=0;break;
+				case 5: if ('s'==b) state=6; else state=0;break;
+				case 6: if ('e'==b) state=7; else state=0;break;
+				case 7: if ('t'==b) state=8; else state=0;break;
 
-                case 8: if ('='==b) state=9; else if (' '!=b) state=0; break;
-                
-                case 9: 
-                    if (' '==b) 
-                        break;
-                    if ('"'==b) 
-                    {
-                        quote=true;
-                        start=i+1;
-                        state=10;
-                        break;
-                    }
-                    start=i;
-                    state=10;
-                    break;
-                    
-                case 10:
-                    if (!quote && (';'==b || ' '==b )||
-                        (quote && '"'==b ))
-                        return CACHE.lookup(value.peek(start,i-start)).toString(StringUtil.__UTF8);
-            }
-        }    
-        
-        if (state==10)
-            return CACHE.lookup(value.peek(start,i-start)).toString(StringUtil.__UTF8);
-        
-        return (String)__encodings.get(value);
-    }
+				case 8: if ('='==b) state=9; else if (' '!=b) state=0; break;
+				
+				case 9: 
+					if (' '==b) 
+						break;
+					if ('"'==b) 
+					{
+						quote=true;
+						start=i+1;
+						state=10;
+						break;
+					}
+					start=i;
+					state=10;
+					break;
+					
+				case 10:
+					if (!quote && (';'==b || ' '==b )||
+						(quote && '"'==b ))
+						return CACHE.lookup(value.peek(start,i-start)).toString(StringUtil.__UTF8);
+			}
+		}    
+		
+		if (state==10)
+			return CACHE.lookup(value.peek(start,i-start)).toString(StringUtil.__UTF8);
+		
+		return (String)__encodings.get(value);
+	}
 }
--- a/src/org/eclipse/jetty/io/AbstractBuffer.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/io/AbstractBuffer.java	Mon Oct 31 22:24:41 2016 -0600
@@ -597,6 +597,7 @@
 	@Override
 	public String toString()
 	{
+/*
 		if (isImmutable())
 		{
 			if (_string == null) 
@@ -604,6 +605,8 @@
 			return _string;
 		}
 		return new String(asArray(), 0, length());
+*/
+		return toString("ISO-8859-1");
 	}
 
 	@Override
--- a/src/org/eclipse/jetty/io/BufferUtil.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/io/BufferUtil.java	Mon Oct 31 22:24:41 2016 -0600
@@ -72,31 +72,29 @@
 	}
 	
 	/**
-	 * Convert buffer to an long.
+	 * Convert string to an long.
 	 * Parses up to the first non-numeric character. If no number is found an
 	 * IllegalArgumentException is thrown
-	 * @param buffer A buffer containing an integer. The position is not changed.
-	 * @return an int 
 	 */
-	public static long toLong(Buffer buffer)
+	public static long toLong(String s)
 	{
-		long val= 0;
+		long val = 0;
 		boolean started= false;
 		boolean minus= false;
-		for (int i= buffer.getIndex(); i < buffer.putIndex(); i++)
+		for (int i = 0; i < s.length(); i++)
 		{
-			byte b= buffer.peek(i);
-			if (b <= SPACE)
+			char c = s.charAt(i);
+			if (c <= ' ')
 			{
 				if (started)
 					break;
 			}
-			else if (b >= '0' && b <= '9')
+			else if (c >= '0' && c <= '9')
 			{
-				val= val * 10L + (b - '0');
+				val= val * 10L + (c - '0');
 				started= true;
 			}
-			else if (b == MINUS && !started)
+			else if (c == '-' && !started)
 			{
 				minus= true;
 			}
@@ -106,7 +104,7 @@
 
 		if (started)
 			return minus ? (-val) : val;
-		throw new NumberFormatException(buffer.toString());
+		throw new NumberFormatException(s);
 	}
 
 	public static void putHexInt(Buffer buffer, int n)
@@ -235,13 +233,6 @@
 		}
 	}
 	
-	public static Buffer toBuffer(long value)
-	{
-		ByteArrayBuffer buf = new ByteArrayBuffer(32);
-		putDecLong(buf, value);
-		return buf;
-	}
-
 	private final static int[] hexDivisors=
 	{
 		0x10000000,
@@ -283,7 +274,7 @@
 		buffer.put((byte)13);
 		buffer.put((byte)10);
 	}
-	
+/*
 	public static boolean isPrefix(Buffer prefix,Buffer buffer)
 	{
 		if (prefix.length()>buffer.length())
@@ -294,7 +285,7 @@
 				return false;
 		return true;
 	}
-
+*/
 	public static String to8859_1_String(Buffer buffer)
 	{
 		if (buffer instanceof CachedBuffer)
--- a/src/org/eclipse/jetty/io/StringCache.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/io/StringCache.java	Mon Oct 31 22:24:41 2016 -0600
@@ -7,7 +7,7 @@
 import org.eclipse.jetty.util.StringUtil;
 
 
-public class StringCache {
+public final class StringCache {
 	private final Map<String,Integer> stringToOrdinal = new HashMap<String,Integer>();
 //	private final Map<Integer,String> ordinalToString = new HashMap<Integer,String>();
 
--- a/src/org/eclipse/jetty/server/AbstractHttpConnection.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/server/AbstractHttpConnection.java	Mon Oct 31 22:24:41 2016 -0600
@@ -503,7 +503,7 @@
 		}
 	}
 
-	private void parsedHeader(Buffer name, Buffer value) throws IOException
+	private void parsedHeader(Buffer name, String value) throws IOException
 	{
 		int ho = HttpHeaders.CACHE.getOrdinal(name);
 		switch (ho)
@@ -516,7 +516,7 @@
 			case HttpHeaders.EXPECT_ORDINAL:
 				if (_version>=HttpVersions.HTTP_1_1_ORDINAL)
 				{
-					value = HttpHeaderValues.CACHE.lookup(value);
+//					value = HttpHeaderValues.CACHE.lookup(value);
 					switch(HttpHeaderValues.CACHE.getOrdinal(value))
 					{
 						case HttpHeaderValues.CONTINUE_ORDINAL:
@@ -527,12 +527,12 @@
 							String[] values = value.toString().split(",");
 							for  (int i=0;values!=null && i<values.length;i++)
 							{
-								CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
-								if (cb==null)
+								int cb = HttpHeaderValues.CACHE.getOrdinal(values[i].trim());
+								if (cb == -1)
 									_expect = true;
 								else
 								{
-									switch(cb.getOrdinal())
+									switch(cb)
 									{
 										case HttpHeaderValues.CONTINUE_ORDINAL:
 											_expect100Continue = true;
@@ -548,12 +548,12 @@
 
 			case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
 			case HttpHeaders.USER_AGENT_ORDINAL:
-				value = HttpHeaderValues.CACHE.lookup(value);
+//				value = HttpHeaderValues.CACHE.lookup(value);
 				break;
 
 			case HttpHeaders.CONTENT_TYPE_ORDINAL:
-				value = MimeTypes.CACHE.lookup(value);
-				_charset=MimeTypes.getCharsetFromContentType(value);
+//				value = MimeTypes.CACHE.lookup(value);
+				_charset=MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(value));
 				break;
 		}
 
@@ -578,7 +578,7 @@
 				_generator.setHead(_head);
 				if (_parser.isPersistent())
 				{
-					_responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
+					_responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE);
 					_generator.setPersistent(true);
 				}
 				else if (HttpMethods.CONNECT.equals(_request.getMethod()))
@@ -593,7 +593,7 @@
 
 				if (!_parser.isPersistent())
 				{
-					_responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
+					_responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE);
 					_generator.setPersistent(false);
 				}
 
@@ -601,7 +601,7 @@
 				{
 					LOG.debug("!host {}",this);
 					_generator.setResponse(HttpStatus.BAD_REQUEST_400, null);
-					_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
+					_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE);
 					_generator.completeHeader(_responseFields, true);
 					_generator.complete();
 					return;
@@ -611,7 +611,7 @@
 				{
 					LOG.debug("!expectation {}",this);
 					_generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
-					_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
+					_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE);
 					_generator.completeHeader(_responseFields, true);
 					_generator.complete();
 					return;
@@ -664,7 +664,7 @@
 		}
 
 		@Override
-		public void parsedHeader(Buffer name, Buffer value) throws IOException
+		public void parsedHeader(Buffer name, String value) throws IOException
 		{
 			AbstractHttpConnection.this.parsedHeader(name, value);
 		}
--- a/src/org/eclipse/jetty/server/Request.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/server/Request.java	Mon Oct 31 22:24:41 2016 -0600
@@ -676,22 +676,22 @@
 			return _serverName;
 
 		// Return host from header field
-		Buffer hostPort = _connection._requestFields.get(HttpHeaders.HOST_BUFFER);
+		String hostPort = _connection._requestFields.getStringField(HttpHeaders.HOST_BUFFER);
 		if (hostPort != null)
 		{
-			loop: for (int i = hostPort.putIndex(); i-- > hostPort.getIndex();)
+			loop: for (int i = hostPort.length(); i-- > 0;)
 			{
-				char ch = (char)(0xff & hostPort.peek(i));
+				char ch = hostPort.charAt(i);
 				switch (ch)
 				{
 					case ']':
 						break loop;
 
 					case ':':
-						_serverName = BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(),i - hostPort.getIndex()));
+						_serverName = hostPort.substring(0,i);
 						try
 						{
-							_port = BufferUtil.toInt(hostPort.peek(i + 1,hostPort.putIndex() - i - 1));
+							_port = Integer.parseInt(hostPort.substring(i + 1));
 						}
 						catch (NumberFormatException e)
 						{
@@ -709,7 +709,7 @@
 			}
 			if (_serverName == null || _port < 0)
 			{
-				_serverName = BufferUtil.to8859_1_String(hostPort);
+				_serverName = hostPort;
 				_port = 0;
 			}
 
--- a/src/org/eclipse/jetty/server/Response.java	Mon Oct 31 03:33:42 2016 -0600
+++ b/src/org/eclipse/jetty/server/Response.java	Mon Oct 31 22:24:41 2016 -0600
@@ -771,14 +771,14 @@
 			String[] values = connection.split(",");
 			for  (int i=0;values!=null && i<values.length;i++)
 			{
-				CachedBuffer cb = HttpHeaderValues.CACHE.get(values[0].trim());
+				int cb = HttpHeaderValues.CACHE.getOrdinal(values[0].trim());
 
-				if (cb!=null)
+				if (cb != -1)
 				{
-					switch(cb.getOrdinal())
+					switch(cb)
 					{
 						case HttpHeaderValues.CLOSE_ORDINAL:
-							response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
+							response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE);
 							break;
 
 						case HttpHeaderValues.KEEP_ALIVE_ORDINAL: