jetty-9 used enums instead of cached strings. Refactor of parser in progress to IO independent style. passes 1 test

This commit is contained in:
Greg Wilkins 2012-02-09 01:37:03 +11:00
parent 7ba514e250
commit 60bb4a415e
34 changed files with 1233 additions and 2106 deletions

View File

@ -15,12 +15,9 @@ package org.eclipse.jetty.http;
import java.io.IOException; import java.io.IOException;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers; import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.View;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;

View File

@ -44,14 +44,14 @@ public class EncodedHttpURI extends HttpURI
_raw[_scheme+1]=='t' && _raw[_scheme+1]=='t' &&
_raw[_scheme+2]=='t' && _raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' ) _raw[_scheme+3]=='p' )
return HttpSchemes.HTTP; return HttpSchemes.HTTP.toString();
if (l==6 && if (l==6 &&
_raw[_scheme]=='h' && _raw[_scheme]=='h' &&
_raw[_scheme+1]=='t' && _raw[_scheme+1]=='t' &&
_raw[_scheme+2]=='t' && _raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' && _raw[_scheme+3]=='p' &&
_raw[_scheme+4]=='s' ) _raw[_scheme+4]=='s' )
return HttpSchemes.HTTPS; return HttpSchemes.HTTPS.toString();
return StringUtil.toString(_raw,_scheme,_authority-_scheme-1,_encoding); return StringUtil.toString(_raw,_scheme,_authority-_scheme-1,_encoding);
} }

View File

@ -30,10 +30,10 @@ public class HttpBuffersImpl extends AbstractLifeCycle implements HttpBuffers
private int _responseHeaderSize=6*1024; private int _responseHeaderSize=6*1024;
private int _maxBuffers=1024; private int _maxBuffers=1024;
private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY; private Buffers.Type _requestBufferType=Buffers.Type.INDIRECT;
private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY; private Buffers.Type _requestHeaderType=Buffers.Type.INDIRECT;
private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY; private Buffers.Type _responseBufferType=Buffers.Type.INDIRECT;
private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY; private Buffers.Type _responseHeaderType=Buffers.Type.INDIRECT;
private Buffers _requestBuffers; private Buffers _requestBuffers;
private Buffers _responseBuffers; private Buffers _responseBuffers;

View File

@ -15,6 +15,7 @@ package org.eclipse.jetty.http;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
@ -34,16 +35,13 @@ import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.BufferDateCache; import org.eclipse.jetty.io.BufferDateCache;
import org.eclipse.jetty.io.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringMap; import org.eclipse.jetty.util.StringMap;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -289,12 +287,12 @@ public class HttpFields
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
public final static String __01Jan1970=formatDate(0); public final static String __01Jan1970=formatDate(0);
public final static Buffer __01Jan1970_BUFFER=new ByteArrayBuffer(__01Jan1970); public final static ByteBuffer __01Jan1970_BUFFER=BufferUtil.toBuffer(__01Jan1970);
public final static String __01Jan1970_COOKIE = formatCookieDate(0).trim(); public final static String __01Jan1970_COOKIE = formatCookieDate(0).trim();
private final static byte[] __colon_space = new byte[] {':',' '};
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
private final ArrayList<Field> _fields = new ArrayList<Field>(20); private final ArrayList<Field> _fields = new ArrayList<Field>(20);
private final HashMap<Buffer,Field> _names = new HashMap<Buffer,Field>(32); private final StringMap<Field> _names = new StringMap<Field>(true);
private final int _maxCookieVersion; private final int _maxCookieVersion;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -316,38 +314,6 @@ public class 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;
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
* Get Collection of header names. * Get Collection of header names.
@ -355,11 +321,10 @@ public class HttpFields
public Collection<String> getFieldNamesCollection() public Collection<String> getFieldNamesCollection()
{ {
final List<String> list = new ArrayList<String>(_fields.size()); final List<String> list = new ArrayList<String>(_fields.size());
for (Field f : _fields) for (Field f : _fields)
{ {
if (f!=null) if (f!=null)
list.add(BufferUtil.to8859_1_String(f._name)); list.add(f._name);
} }
return list; return list;
} }
@ -404,29 +369,29 @@ public class HttpFields
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private Field getField(String name) public Field getField(HttpHeaders header)
{ {
return _names.get(HttpHeaders.CACHE.lookup(name)); return _names.get(header.toString());
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private Field getField(Buffer name) public Field getField(String name)
{ {
return _names.get(HttpHeaders.CACHE.lookup(name)); return _names.get(name);
}
/* ------------------------------------------------------------ */
public boolean containsKey(Buffer name)
{
return _names.containsKey(HttpHeaders.CACHE.lookup(name));
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public boolean containsKey(String name) public boolean containsKey(String name)
{ {
return _names.containsKey(HttpHeaders.CACHE.lookup(name)); return _names.containsKey(name);
} }
/* -------------------------------------------------------------- */
public String getStringField(HttpHeaders header)
{
return getStringField(header.toString());
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
* @return the value of a field, or null if not found. For multiple fields of the same name, * @return the value of a field, or null if not found. For multiple fields of the same name,
@ -439,30 +404,6 @@ public class HttpFields
return field==null?null:field.getValue(); return field==null?null:field.getValue();
} }
/* -------------------------------------------------------------- */
/**
* @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 String getStringField(Buffer name)
{
Field field = getField(name);
return field==null?null:field.getValue();
}
/* -------------------------------------------------------------- */
/**
* @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;
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
@ -522,41 +463,6 @@ public class HttpFields
}; };
} }
/* -------------------------------------------------------------- */
/**
* Get multi headers
*
* @return Enumeration of the value Strings
* @param name the case-insensitive field name
*/
public Enumeration<String> getValues(Buffer name)
{
final Field field = getField(name);
if (field == null)
{
List<String> empty=Collections.emptyList();
return Collections.enumeration(empty);
}
return new Enumeration<String>()
{
Field f = field;
public boolean hasMoreElements()
{
return f != null;
}
public String nextElement() throws NoSuchElementException
{
if (f == null) throw new NoSuchElementException();
Field n = f;
f = f._next;
return n.getValue();
}
};
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
* Get multi field values with separator. The multiple values can be represented as separate * Get multi field values with separator. The multiple values can be represented as separate
@ -599,7 +505,7 @@ public class HttpFields
}; };
} }
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
* Set a field. * Set a field.
@ -608,49 +514,11 @@ public class HttpFields
* @param value the value of the field. If null the field is cleared. * @param value the value of the field. If null the field is cleared.
*/ */
public void put(String name, String value) public void put(String name, String value)
{
if (value==null)
remove(name);
else
{
Buffer n = HttpHeaders.CACHE.lookup(name);
Buffer v = convertValue(value);
put(n, v);
}
}
/* -------------------------------------------------------------- */
/**
* Set a field.
*
* @param name the name of the field
* @param value the value of the field. If null the field is cleared.
*/
public void put(Buffer name, String value)
{
Buffer n = HttpHeaders.CACHE.lookup(name);
Buffer v = convertValue(value);
put(n, v);
}
/* -------------------------------------------------------------- */
/**
* Set a field.
*
* @param name the name of the field
* @param value the value of the field. If null the field is cleared.
*/
public void put(Buffer name, Buffer value)
{ {
remove(name); remove(name);
if (value == null) if (value == null)
return; return;
if (!(name instanceof BufferCache.CachedBuffer))
name = HttpHeaders.CACHE.lookup(name);
if (!(value instanceof CachedBuffer))
value= HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer();
// new value; // new value;
Field field = new Field(name, value); Field field = new Field(name, value);
_fields.add(field); _fields.add(field);
@ -664,31 +532,12 @@ public class HttpFields
* @param name the name of the field * @param name the name of the field
* @param list the List value of the field. If null the field is cleared. * @param list the List value of the field. If null the field is cleared.
*/ */
public void put(String name, List<?> list) public void put(String name, List<String> list)
{ {
if (list == null || list.size() == 0) remove(name);
{ for (String v : list)
remove(name); if (v!=null)
return; add(name,v);
}
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()));
}
}
} }
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
@ -702,35 +551,8 @@ public class HttpFields
* value. * value.
*/ */
public void add(String name, String value) throws IllegalArgumentException public void add(String name, String value) throws IllegalArgumentException
{
if (value==null)
return;
Buffer n = HttpHeaders.CACHE.lookup(name);
Buffer v = convertValue(value);
add(n, v);
}
/* -------------------------------------------------------------- */
/**
* Add to or set a field. If the field is allowed to have multiple values, add will add multiple
* headers of the same name.
*
* @param name the name of the field
* @param value the value of the field.
* @exception IllegalArgumentException If the name is a single valued field and already has a
* value.
*/
public void add(Buffer name, Buffer value) throws IllegalArgumentException
{ {
if (value == null) throw new IllegalArgumentException("null value"); 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 field = _names.get(name);
Field last = null; Field last = null;
@ -751,6 +573,7 @@ public class HttpFields
_names.put(name, field); _names.put(name, field);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Remove a field. * Remove a field.
@ -759,19 +582,6 @@ public class HttpFields
*/ */
public void remove(String name) public void remove(String name)
{ {
remove(HttpHeaders.CACHE.lookup(name));
}
/* ------------------------------------------------------------ */
/**
* Remove a field.
*
* @param name
*/
public void remove(Buffer name)
{
if (!(name instanceof BufferCache.CachedBuffer))
name = HttpHeaders.CACHE.lookup(name);
Field field = _names.remove(name); Field field = _names.remove(name);
while (field != null) while (field != null)
{ {
@ -794,20 +604,6 @@ public class HttpFields
return field==null?-1L:field.getLongValue(); return field==null?-1L:field.getLongValue();
} }
/* -------------------------------------------------------------- */
/**
* Get a header as an long value. Returns the value of an integer field or -1 if not found. The
* case of the field name is ignored.
*
* @param name the case-insensitive field name
* @exception NumberFormatException If bad long found
*/
public long getLongField(Buffer name) throws NumberFormatException
{
Field field = getField(name);
return field==null?-1L:field.getLongValue();
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
* Get a header as a date value. Returns the value of a date field, or -1 if not found. The case * Get a header as a date value. Returns the value of a date field, or -1 if not found. The case
@ -821,7 +617,7 @@ public class HttpFields
if (field == null) if (field == null)
return -1; return -1;
String val = valueParameters(BufferUtil.to8859_1_String(field._value), null); String val = valueParameters(field._value, null);
if (val == null) if (val == null)
return -1; return -1;
@ -831,18 +627,6 @@ public class HttpFields
return date; return date;
} }
/* -------------------------------------------------------------- */
/**
* Sets the value of an long field.
*
* @param name the field name
* @param value the field long value
*/
public void putLongField(Buffer name, long value)
{
Buffer v = BufferUtil.toBuffer(value);
put(name, v);
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
@ -853,52 +637,11 @@ public class HttpFields
*/ */
public void putLongField(String name, long value) public void putLongField(String name, long value)
{ {
Buffer n = HttpHeaders.CACHE.lookup(name); String v = Long.toString(value);
Buffer v = BufferUtil.toBuffer(value);
put(n, v);
}
/* -------------------------------------------------------------- */
/**
* Sets the value of an long field.
*
* @param name the field name
* @param value the field long value
*/
public void addLongField(String name, long value)
{
Buffer n = HttpHeaders.CACHE.lookup(name);
Buffer v = BufferUtil.toBuffer(value);
add(n, v);
}
/* -------------------------------------------------------------- */
/**
* Sets the value of an long field.
*
* @param name the field name
* @param value the field long value
*/
public void addLongField(Buffer name, long value)
{
Buffer v = BufferUtil.toBuffer(value);
add(name, v);
}
/* -------------------------------------------------------------- */
/**
* Sets the value of a date field.
*
* @param name the field name
* @param date the field date value
*/
public void putDateField(Buffer name, long date)
{
String d=formatDate(date);
Buffer v = new ByteArrayBuffer(d);
put(name, v); put(name, v);
} }
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/** /**
* Sets the value of a date field. * Sets the value of a date field.
@ -908,8 +651,8 @@ public class HttpFields
*/ */
public void putDateField(String name, long date) public void putDateField(String name, long date)
{ {
Buffer n = HttpHeaders.CACHE.lookup(name); String d=formatDate(date);
putDateField(n,date); put(name, d);
} }
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
@ -922,9 +665,7 @@ public class HttpFields
public void addDateField(String name, long date) public void addDateField(String name, long date)
{ {
String d=formatDate(date); String d=formatDate(date);
Buffer n = HttpHeaders.CACHE.lookup(name); add(name,d);
Buffer v = new ByteArrayBuffer(d);
add(n, v);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -1053,7 +794,7 @@ public class HttpFields
{ {
_fields.remove(field); _fields.remove(field);
if (last==null) if (last==null)
_names.put(HttpHeaders.SET_COOKIE_BUFFER,field._next); _names.put(HttpHeaders.SET_COOKIE.toString(),field._next);
else else
last._next=field._next; last._next=field._next;
break; break;
@ -1062,14 +803,14 @@ public class HttpFields
field=field._next; field=field._next;
} }
add(HttpHeaders.SET_COOKIE_BUFFER, new ByteArrayBuffer(name_value_params)); add(HttpHeaders.SET_COOKIE.toString(), name_value_params);
// Expire responses with set-cookie headers so they do not get cached. // Expire responses with set-cookie headers so they do not get cached.
put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER); put(HttpHeaders.EXPIRES.toString(), __01Jan1970);
} }
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
public void putTo(Buffer buffer) throws IOException public void putTo(ByteBuffer buffer) throws IOException
{ {
for (int i = 0; i < _fields.size(); i++) for (int i = 0; i < _fields.size(); i++)
{ {
@ -1130,11 +871,11 @@ public class HttpFields
{ {
if (fields == null) return; if (fields == null) return;
Enumeration e = fields.getFieldNames(); Enumeration<String> e = fields.getFieldNames();
while (e.hasMoreElements()) while (e.hasMoreElements())
{ {
String name = (String) e.nextElement(); String name = (String) e.nextElement();
Enumeration values = fields.getValues(name); Enumeration<String> values = fields.getValues(name);
while (values.hasMoreElements()) while (values.hasMoreElements())
add(name, (String) values.nextElement()); add(name, (String) values.nextElement());
} }
@ -1183,7 +924,7 @@ public class HttpFields
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private static final Float __one = new Float("1.0"); private static final Float __one = new Float("1.0");
private static final Float __zero = new Float("0.0"); private static final Float __zero = new Float("0.0");
private static final StringMap __qualities = new StringMap(); private static final StringMap<Float> __qualities = new StringMap<>();
static static
{ {
__qualities.put(null, __one); __qualities.put(null, __one);
@ -1215,11 +956,12 @@ public class HttpFields
if (value.charAt(qe++) == 'q') if (value.charAt(qe++) == 'q')
{ {
qe++; qe++;
Map.Entry entry = __qualities.getEntry(value, qe, value.length() - qe); Map.Entry<String,Float> entry = __qualities.getEntry(value, qe, value.length() - qe);
if (entry != null) return (Float) entry.getValue(); if (entry != null)
return (Float) entry.getValue();
} }
HashMap params = new HashMap(3); Map<String,String> params = new HashMap<String,String>(4);
valueParameters(value, params); valueParameters(value, params);
String qs = (String) params.get("q"); String qs = (String) params.get("q");
Float q = (Float) __qualities.get(qs); Float q = (Float) __qualities.get(qs);
@ -1244,9 +986,10 @@ public class HttpFields
* @param e Enumeration of values with quality parameters * @param e Enumeration of values with quality parameters
* @return values in quality order. * @return values in quality order.
*/ */
public static List qualityList(Enumeration e) public static List<String> qualityList(Enumeration<String> e)
{ {
if (e == null || !e.hasMoreElements()) return Collections.EMPTY_LIST; if (e == null || !e.hasMoreElements())
return Collections.emptyList();
Object list = null; Object list = null;
Object qual = null; Object qual = null;
@ -1296,65 +1039,57 @@ public class HttpFields
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static final class Field public static final class Field
{ {
private Buffer _name; private final String _name;
private Buffer _value; private final String _value;
private Field _next; private Field _next;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private Field(Buffer name, Buffer value) private Field(String name, String value)
{ {
_name = name; _name = name;
_value = value; _value = value;
_next = null; _next = null;
} }
/* ------------------------------------------------------------ */ private byte[] toSanitisedBytes(String s)
public void putTo(Buffer buffer) throws IOException
{ {
int o=(_name instanceof CachedBuffer)?((CachedBuffer)_name).getOrdinal():-1; byte[] bytes = s.getBytes(StringUtil.__ISO_8859_1_CHARSET);
if (o>=0) for (int i=bytes.length;i-->0;)
buffer.put(_name);
else
{ {
int s=_name.getIndex(); switch(bytes[i])
int e=_name.putIndex();
while (s<e)
{ {
byte b=_name.peek(s++); case '\r':
switch(b) case '\n':
{ case ':' :
case '\r': bytes[i]=(byte)'?';
case '\n': }
case ':' : }
continue; return bytes;
default: }
buffer.put(b);
} /* ------------------------------------------------------------ */
public void putTo(ByteBuffer buffer) throws IOException
{
HttpHeaders header = HttpHeaders.CACHE.get(_name);
if (header!=null)
{
buffer.put(header.toBuffer());
buffer.put(__colon_space);
if (HttpHeaderValues.hasKnownValues(header))
{
HttpHeaderValues value=HttpHeaderValues.CACHE.get(_value);
if (value!=null)
buffer.put(value.toBuffer());
else
buffer.put(toSanitisedBytes(_value));
} }
} }
buffer.put((byte) ':');
buffer.put((byte) ' ');
o=(_value instanceof CachedBuffer)?((CachedBuffer)_value).getOrdinal():-1;
if (o>=0)
buffer.put(_value);
else else
{ {
int s=_value.getIndex(); buffer.put(toSanitisedBytes(_name));
int e=_value.putIndex(); buffer.put(__colon_space);
while (s<e) buffer.put(toSanitisedBytes(_value));
{
byte b=_value.peek(s++);
switch(b)
{
case '\r':
case '\n':
continue;
default:
buffer.put(b);
}
}
} }
BufferUtil.putCRLF(buffer); BufferUtil.putCRLF(buffer);
@ -1362,51 +1097,28 @@ public class HttpFields
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String getName() public String getName()
{
return BufferUtil.to8859_1_String(_name);
}
/* ------------------------------------------------------------ */
Buffer getNameBuffer()
{ {
return _name; return _name;
} }
/* ------------------------------------------------------------ */
public int getNameOrdinal()
{
return HttpHeaders.CACHE.getOrdinal(_name);
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String getValue() public String getValue()
{
return BufferUtil.to8859_1_String(_value);
}
/* ------------------------------------------------------------ */
public Buffer getValueBuffer()
{ {
return _value; return _value;
} }
/* ------------------------------------------------------------ */
public int getValueOrdinal()
{
return HttpHeaderValues.CACHE.getOrdinal(_value);
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public int getIntValue() public int getIntValue()
{ {
return (int) getLongValue(); return StringUtil.toInt(_value);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public long getLongValue() public long getLongValue()
{ {
return BufferUtil.toLong(_value); return StringUtil.toLong(_value);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String toString() public String toString()

View File

@ -18,11 +18,11 @@ import java.io.InterruptedIOException;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache.CachedBuffer; import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.Buffers; import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;

View File

@ -13,71 +13,73 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.io.BufferCache; import java.util.EnumMap;
import org.eclipse.jetty.io.ByteArrayBuffer; import java.util.EnumSet;
import java.util.Map;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
/** /**
* 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 enum HttpHeaderValues
{ {
public final static String CLOSE("close"),
CLOSE="close", CHUNKED("chunked"),
CHUNKED="chunked", GZIP("gzip"),
GZIP="gzip", IDENTITY("identity"),
IDENTITY="identity", KEEP_ALIVE("keep-alive"),
KEEP_ALIVE="keep-alive", CONTINUE("100-continue"),
CONTINUE="100-continue", PROCESSING("102-processing"),
PROCESSING="102-processing", TE("TE"),
TE="TE", BYTES("bytes"),
BYTES="bytes", NO_CACHE("no-cache"),
NO_CACHE="no-cache", UPGRADE("Upgrade");
UPGRADE="Upgrade";
public final static int /* ------------------------------------------------------------ */
CLOSE_ORDINAL=1, public final static StringMap<HttpHeaderValues> CACHE= new StringMap<HttpHeaderValues>(true);
CHUNKED_ORDINAL=2, static
GZIP_ORDINAL=3,
IDENTITY_ORDINAL=4,
KEEP_ALIVE_ORDINAL=5,
CONTINUE_ORDINAL=6,
PROCESSING_ORDINAL=7,
TE_ORDINAL=8,
BYTES_ORDINAL=9,
NO_CACHE_ORDINAL=10,
UPGRADE_ORDINAL=11;
public final static HttpHeaderValues CACHE= new HttpHeaderValues();
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 static boolean hasKnownValues(int httpHeaderOrdinal)
{ {
switch(httpHeaderOrdinal) for (HttpHeaderValues value : HttpHeaderValues.values())
{ CACHE.put(value.toString(),value);
case HttpHeaders.CONNECTION_ORDINAL: }
case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
case HttpHeaders.CONTENT_ENCODING_ORDINAL: private final String _string;
return true; private final ByteBuffer _buffer;
}
return false; /* ------------------------------------------------------------ */
HttpHeaderValues(String s)
{
_string=s;
_buffer=BufferUtil.toBuffer(s);
}
/* ------------------------------------------------------------ */
public ByteBuffer toBuffer()
{
return _buffer.asReadOnlyBuffer();
}
/* ------------------------------------------------------------ */
public String toString()
{
return _string;
}
/* ------------------------------------------------------------ */
private static EnumSet<HttpHeaders> __known =
EnumSet.of(HttpHeaders.CONNECTION,
HttpHeaders.TRANSFER_ENCODING,
HttpHeaders.CONTENT_ENCODING);
/* ------------------------------------------------------------ */
public static boolean hasKnownValues(HttpHeaders header)
{
if (header==null)
return false;
return __known.contains(header);
} }
} }

View File

@ -13,224 +13,125 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.io.BufferCache;
/* ------------------------------------------------------------------------------- */ import org.eclipse.jetty.util.BufferUtil;
/** import org.eclipse.jetty.util.StringMap;
*/
public class HttpHeaders extends BufferCache
public enum HttpHeaders
{ {
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** General Fields. /** General Fields.
*/ */
public final static String CONNECTION("Connection"),
CONNECTION= "Connection", CACHE_CONTROL("Cache-Control"),
CACHE_CONTROL= "Cache-Control", DATE("Date"),
DATE= "Date", PRAGMA("Pragma"),
PRAGMA= "Pragma", PROXY_CONNECTION ("Proxy-Connection"),
PROXY_CONNECTION = "Proxy-Connection", TRAILER("Trailer"),
TRAILER= "Trailer", TRANSFER_ENCODING("Transfer-Encoding"),
TRANSFER_ENCODING= "Transfer-Encoding", UPGRADE("Upgrade"),
UPGRADE= "Upgrade", VIA("Via"),
VIA= "Via", WARNING("Warning"),
WARNING= "Warning", NEGOTIATE("Negotiate"),
NEGOTIATE= "Negotiate";
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Entity Fields. /** Entity Fields.
*/ */
public final static String ALLOW= "Allow", ALLOW("Allow"),
CONTENT_ENCODING= "Content-Encoding", CONTENT_ENCODING("Content-Encoding"),
CONTENT_LANGUAGE= "Content-Language", CONTENT_LANGUAGE("Content-Language"),
CONTENT_LENGTH= "Content-Length", CONTENT_LENGTH("Content-Length"),
CONTENT_LOCATION= "Content-Location", CONTENT_LOCATION("Content-Location"),
CONTENT_MD5= "Content-MD5", CONTENT_MD5("Content-MD5"),
CONTENT_RANGE= "Content-Range", CONTENT_RANGE("Content-Range"),
CONTENT_TYPE= "Content-Type", CONTENT_TYPE("Content-Type"),
EXPIRES= "Expires", EXPIRES("Expires"),
LAST_MODIFIED= "Last-Modified"; LAST_MODIFIED("Last-Modified"),
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Request Fields. /** Request Fields.
*/ */
public final static String ACCEPT= "Accept", ACCEPT("Accept"),
ACCEPT_CHARSET= "Accept-Charset", ACCEPT_CHARSET("Accept-Charset"),
ACCEPT_ENCODING= "Accept-Encoding", ACCEPT_ENCODING("Accept-Encoding"),
ACCEPT_LANGUAGE= "Accept-Language", ACCEPT_LANGUAGE("Accept-Language"),
AUTHORIZATION= "Authorization", AUTHORIZATION("Authorization"),
EXPECT= "Expect", EXPECT("Expect"),
FORWARDED= "Forwarded", FORWARDED("Forwarded"),
FROM= "From", FROM("From"),
HOST= "Host", HOST("Host"),
IF_MATCH= "If-Match", IF_MATCH("If-Match"),
IF_MODIFIED_SINCE= "If-Modified-Since", IF_MODIFIED_SINCE("If-Modified-Since"),
IF_NONE_MATCH= "If-None-Match", IF_NONE_MATCH("If-None-Match"),
IF_RANGE= "If-Range", IF_RANGE("If-Range"),
IF_UNMODIFIED_SINCE= "If-Unmodified-Since", IF_UNMODIFIED_SINCE("If-Unmodified-Since"),
KEEP_ALIVE= "Keep-Alive", KEEP_ALIVE("Keep-Alive"),
MAX_FORWARDS= "Max-Forwards", MAX_FORWARDS("Max-Forwards"),
PROXY_AUTHORIZATION= "Proxy-Authorization", PROXY_AUTHORIZATION("Proxy-Authorization"),
RANGE= "Range", RANGE("Range"),
REQUEST_RANGE= "Request-Range", REQUEST_RANGE("Request-Range"),
REFERER= "Referer", REFERER("Referer"),
TE= "TE", TE("TE"),
USER_AGENT= "User-Agent", USER_AGENT("User-Agent"),
X_FORWARDED_FOR= "X-Forwarded-For", X_FORWARDED_FOR("X-Forwarded-For"),
X_FORWARDED_PROTO= "X-Forwarded-Proto", X_FORWARDED_PROTO("X-Forwarded-Proto"),
X_FORWARDED_SERVER= "X-Forwarded-Server", X_FORWARDED_SERVER("X-Forwarded-Server"),
X_FORWARDED_HOST= "X-Forwarded-Host"; X_FORWARDED_HOST("X-Forwarded-Host"),
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Response Fields. /** Response Fields.
*/ */
public final static String ACCEPT_RANGES= "Accept-Ranges", ACCEPT_RANGES("Accept-Ranges"),
AGE= "Age", AGE("Age"),
ETAG= "ETag", ETAG("ETag"),
LOCATION= "Location", LOCATION("Location"),
PROXY_AUTHENTICATE= "Proxy-Authenticate", PROXY_AUTHENTICATE("Proxy-Authenticate"),
RETRY_AFTER= "Retry-After", RETRY_AFTER("Retry-After"),
SERVER= "Server", SERVER("Server"),
SERVLET_ENGINE= "Servlet-Engine", SERVLET_ENGINE("Servlet-Engine"),
VARY= "Vary", VARY("Vary"),
WWW_AUTHENTICATE= "WWW-Authenticate"; WWW_AUTHENTICATE("WWW-Authenticate"),
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Other Fields. /** Other Fields.
*/ */
public final static String COOKIE= "Cookie", COOKIE("Cookie"),
SET_COOKIE= "Set-Cookie", SET_COOKIE("Set-Cookie"),
SET_COOKIE2= "Set-Cookie2", SET_COOKIE2("Set-Cookie2"),
MIME_VERSION= "MIME-Version", MIME_VERSION("MIME-Version"),
IDENTITY= "identity"; IDENTITY("identity");
public final static int CONNECTION_ORDINAL= 1,
DATE_ORDINAL= 2,
PRAGMA_ORDINAL= 3,
TRAILER_ORDINAL= 4,
TRANSFER_ENCODING_ORDINAL= 5,
UPGRADE_ORDINAL= 6,
VIA_ORDINAL= 7,
WARNING_ORDINAL= 8,
ALLOW_ORDINAL= 9,
CONTENT_ENCODING_ORDINAL= 10,
CONTENT_LANGUAGE_ORDINAL= 11,
CONTENT_LENGTH_ORDINAL= 12,
CONTENT_LOCATION_ORDINAL= 13,
CONTENT_MD5_ORDINAL= 14,
CONTENT_RANGE_ORDINAL= 15,
CONTENT_TYPE_ORDINAL= 16,
EXPIRES_ORDINAL= 17,
LAST_MODIFIED_ORDINAL= 18,
ACCEPT_ORDINAL= 19,
ACCEPT_CHARSET_ORDINAL= 20,
ACCEPT_ENCODING_ORDINAL= 21,
ACCEPT_LANGUAGE_ORDINAL= 22,
AUTHORIZATION_ORDINAL= 23,
EXPECT_ORDINAL= 24,
FORWARDED_ORDINAL= 25,
FROM_ORDINAL= 26,
HOST_ORDINAL= 27,
IF_MATCH_ORDINAL= 28,
IF_MODIFIED_SINCE_ORDINAL= 29,
IF_NONE_MATCH_ORDINAL= 30,
IF_RANGE_ORDINAL= 31,
IF_UNMODIFIED_SINCE_ORDINAL= 32,
KEEP_ALIVE_ORDINAL= 33,
MAX_FORWARDS_ORDINAL= 34,
PROXY_AUTHORIZATION_ORDINAL= 35,
RANGE_ORDINAL= 36,
REQUEST_RANGE_ORDINAL= 37,
REFERER_ORDINAL= 38,
TE_ORDINAL= 39,
USER_AGENT_ORDINAL= 40,
X_FORWARDED_FOR_ORDINAL= 41,
ACCEPT_RANGES_ORDINAL= 42,
AGE_ORDINAL= 43,
ETAG_ORDINAL= 44,
LOCATION_ORDINAL= 45,
PROXY_AUTHENTICATE_ORDINAL= 46,
RETRY_AFTER_ORDINAL= 47,
SERVER_ORDINAL= 48,
SERVLET_ENGINE_ORDINAL= 49,
VARY_ORDINAL= 50,
WWW_AUTHENTICATE_ORDINAL= 51,
COOKIE_ORDINAL= 52,
SET_COOKIE_ORDINAL= 53,
SET_COOKIE2_ORDINAL= 54,
MIME_VERSION_ORDINAL= 55,
IDENTITY_ORDINAL= 56,
CACHE_CONTROL_ORDINAL=57,
PROXY_CONNECTION_ORDINAL=58,
X_FORWARDED_PROTO_ORDINAL=59,
X_FORWARDED_SERVER_ORDINAL=60,
X_FORWARDED_HOST_ORDINAL=61;
public final static HttpHeaders CACHE= new HttpHeaders(); /* ------------------------------------------------------------ */
public final static StringMap<HttpHeaders> CACHE= new StringMap<HttpHeaders>(true);
public final static Buffer static
HOST_BUFFER=CACHE.add(HOST,HOST_ORDINAL), {
ACCEPT_BUFFER=CACHE.add(ACCEPT,ACCEPT_ORDINAL), for (HttpHeaders header : HttpHeaders.values())
ACCEPT_CHARSET_BUFFER=CACHE.add(ACCEPT_CHARSET,ACCEPT_CHARSET_ORDINAL), CACHE.put(header.toString(),header);
ACCEPT_ENCODING_BUFFER=CACHE.add(ACCEPT_ENCODING,ACCEPT_ENCODING_ORDINAL), }
ACCEPT_LANGUAGE_BUFFER=CACHE.add(ACCEPT_LANGUAGE,ACCEPT_LANGUAGE_ORDINAL),
CONTENT_LENGTH_BUFFER=CACHE.add(CONTENT_LENGTH,CONTENT_LENGTH_ORDINAL),
CONNECTION_BUFFER=CACHE.add(CONNECTION,CONNECTION_ORDINAL),
CACHE_CONTROL_BUFFER=CACHE.add(CACHE_CONTROL,CACHE_CONTROL_ORDINAL),
DATE_BUFFER=CACHE.add(DATE,DATE_ORDINAL),
PRAGMA_BUFFER=CACHE.add(PRAGMA,PRAGMA_ORDINAL),
TRAILER_BUFFER=CACHE.add(TRAILER,TRAILER_ORDINAL),
TRANSFER_ENCODING_BUFFER=CACHE.add(TRANSFER_ENCODING,TRANSFER_ENCODING_ORDINAL),
UPGRADE_BUFFER=CACHE.add(UPGRADE,UPGRADE_ORDINAL),
VIA_BUFFER=CACHE.add(VIA,VIA_ORDINAL),
WARNING_BUFFER=CACHE.add(WARNING,WARNING_ORDINAL),
ALLOW_BUFFER=CACHE.add(ALLOW,ALLOW_ORDINAL),
CONTENT_ENCODING_BUFFER=CACHE.add(CONTENT_ENCODING,CONTENT_ENCODING_ORDINAL),
CONTENT_LANGUAGE_BUFFER=CACHE.add(CONTENT_LANGUAGE,CONTENT_LANGUAGE_ORDINAL),
CONTENT_LOCATION_BUFFER=CACHE.add(CONTENT_LOCATION,CONTENT_LOCATION_ORDINAL),
CONTENT_MD5_BUFFER=CACHE.add(CONTENT_MD5,CONTENT_MD5_ORDINAL),
CONTENT_RANGE_BUFFER=CACHE.add(CONTENT_RANGE,CONTENT_RANGE_ORDINAL),
CONTENT_TYPE_BUFFER=CACHE.add(CONTENT_TYPE,CONTENT_TYPE_ORDINAL),
EXPIRES_BUFFER=CACHE.add(EXPIRES,EXPIRES_ORDINAL),
LAST_MODIFIED_BUFFER=CACHE.add(LAST_MODIFIED,LAST_MODIFIED_ORDINAL),
AUTHORIZATION_BUFFER=CACHE.add(AUTHORIZATION,AUTHORIZATION_ORDINAL),
EXPECT_BUFFER=CACHE.add(EXPECT,EXPECT_ORDINAL),
FORWARDED_BUFFER=CACHE.add(FORWARDED,FORWARDED_ORDINAL),
FROM_BUFFER=CACHE.add(FROM,FROM_ORDINAL),
IF_MATCH_BUFFER=CACHE.add(IF_MATCH,IF_MATCH_ORDINAL),
IF_MODIFIED_SINCE_BUFFER=CACHE.add(IF_MODIFIED_SINCE,IF_MODIFIED_SINCE_ORDINAL),
IF_NONE_MATCH_BUFFER=CACHE.add(IF_NONE_MATCH,IF_NONE_MATCH_ORDINAL),
IF_RANGE_BUFFER=CACHE.add(IF_RANGE,IF_RANGE_ORDINAL),
IF_UNMODIFIED_SINCE_BUFFER=CACHE.add(IF_UNMODIFIED_SINCE,IF_UNMODIFIED_SINCE_ORDINAL),
KEEP_ALIVE_BUFFER=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL),
MAX_FORWARDS_BUFFER=CACHE.add(MAX_FORWARDS,MAX_FORWARDS_ORDINAL),
PROXY_AUTHORIZATION_BUFFER=CACHE.add(PROXY_AUTHORIZATION,PROXY_AUTHORIZATION_ORDINAL),
RANGE_BUFFER=CACHE.add(RANGE,RANGE_ORDINAL),
REQUEST_RANGE_BUFFER=CACHE.add(REQUEST_RANGE,REQUEST_RANGE_ORDINAL),
REFERER_BUFFER=CACHE.add(REFERER,REFERER_ORDINAL),
TE_BUFFER=CACHE.add(TE,TE_ORDINAL),
USER_AGENT_BUFFER=CACHE.add(USER_AGENT,USER_AGENT_ORDINAL),
X_FORWARDED_FOR_BUFFER=CACHE.add(X_FORWARDED_FOR,X_FORWARDED_FOR_ORDINAL),
X_FORWARDED_PROTO_BUFFER=CACHE.add(X_FORWARDED_PROTO,X_FORWARDED_PROTO_ORDINAL),
X_FORWARDED_SERVER_BUFFER=CACHE.add(X_FORWARDED_SERVER,X_FORWARDED_SERVER_ORDINAL),
X_FORWARDED_HOST_BUFFER=CACHE.add(X_FORWARDED_HOST,X_FORWARDED_HOST_ORDINAL),
ACCEPT_RANGES_BUFFER=CACHE.add(ACCEPT_RANGES,ACCEPT_RANGES_ORDINAL),
AGE_BUFFER=CACHE.add(AGE,AGE_ORDINAL),
ETAG_BUFFER=CACHE.add(ETAG,ETAG_ORDINAL),
LOCATION_BUFFER=CACHE.add(LOCATION,LOCATION_ORDINAL),
PROXY_AUTHENTICATE_BUFFER=CACHE.add(PROXY_AUTHENTICATE,PROXY_AUTHENTICATE_ORDINAL),
RETRY_AFTER_BUFFER=CACHE.add(RETRY_AFTER,RETRY_AFTER_ORDINAL),
SERVER_BUFFER=CACHE.add(SERVER,SERVER_ORDINAL),
SERVLET_ENGINE_BUFFER=CACHE.add(SERVLET_ENGINE,SERVLET_ENGINE_ORDINAL),
VARY_BUFFER=CACHE.add(VARY,VARY_ORDINAL),
WWW_AUTHENTICATE_BUFFER=CACHE.add(WWW_AUTHENTICATE,WWW_AUTHENTICATE_ORDINAL),
COOKIE_BUFFER=CACHE.add(COOKIE,COOKIE_ORDINAL),
SET_COOKIE_BUFFER=CACHE.add(SET_COOKIE,SET_COOKIE_ORDINAL),
SET_COOKIE2_BUFFER=CACHE.add(SET_COOKIE2,SET_COOKIE2_ORDINAL),
MIME_VERSION_BUFFER=CACHE.add(MIME_VERSION,MIME_VERSION_ORDINAL),
IDENTITY_BUFFER=CACHE.add(IDENTITY,IDENTITY_ORDINAL),
PROXY_CONNECTION_BUFFER=CACHE.add(PROXY_CONNECTION,PROXY_CONNECTION_ORDINAL);
private final String _string;
private final ByteBuffer _buffer;
/* ------------------------------------------------------------ */
HttpHeaders(String s)
{
_string=s;
_buffer=BufferUtil.toBuffer(s);
}
/* ------------------------------------------------------------ */
public ByteBuffer toBuffer()
{
return _buffer.asReadOnlyBuffer();
}
/* ------------------------------------------------------------ */
public String toString()
{
return _string;
}
} }

View File

@ -13,47 +13,47 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.io.BufferCache;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/** /**
*
*
*/ */
public class HttpMethods public enum HttpMethods
{ {
public final static String GET= "GET", GET,
POST= "POST", POST,
HEAD= "HEAD", HEAD,
PUT= "PUT", PUT,
OPTIONS= "OPTIONS", OPTIONS,
DELETE= "DELETE", DELETE,
TRACE= "TRACE", TRACE,
CONNECT= "CONNECT", CONNECT,
MOVE= "MOVE"; MOVE;
public final static int GET_ORDINAL= 1, /* ------------------------------------------------------------ */
POST_ORDINAL= 2, public final static StringMap<HttpMethods> CACHE= new StringMap<HttpMethods>(true);
HEAD_ORDINAL= 3, static
PUT_ORDINAL= 4, {
OPTIONS_ORDINAL= 5, for (HttpMethods method : HttpMethods.values())
DELETE_ORDINAL= 6, CACHE.put(method.toString(),method);
TRACE_ORDINAL= 7, }
CONNECT_ORDINAL= 8,
MOVE_ORDINAL= 9;
public final static BufferCache CACHE= new BufferCache(); /* ------------------------------------------------------------ */
private final ByteBuffer _buffer;
public final static Buffer /* ------------------------------------------------------------ */
GET_BUFFER= CACHE.add(GET, GET_ORDINAL), HttpMethods()
POST_BUFFER= CACHE.add(POST, POST_ORDINAL), {
HEAD_BUFFER= CACHE.add(HEAD, HEAD_ORDINAL), _buffer=BufferUtil.toBuffer(toString());
PUT_BUFFER= CACHE.add(PUT, PUT_ORDINAL), }
OPTIONS_BUFFER= CACHE.add(OPTIONS, OPTIONS_ORDINAL),
DELETE_BUFFER= CACHE.add(DELETE, DELETE_ORDINAL),
TRACE_BUFFER= CACHE.add(TRACE, TRACE_ORDINAL),
CONNECT_BUFFER= CACHE.add(CONNECT, CONNECT_ORDINAL),
MOVE_BUFFER= CACHE.add(MOVE, MOVE_ORDINAL);
/* ------------------------------------------------------------ */
public ByteBuffer toBuffer()
{
return _buffer.asReadOnlyBuffer();
}
} }

View File

@ -13,21 +13,48 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/** /**
*
*
*/ */
public class HttpSchemes public enum HttpSchemes
{ {
public final static String HTTP("http"),
HTTP ="http", HTTPS("https"),
HTTPS="https"; WS("ws"),
WSS("wss");
public final static Buffer
HTTP_BUFFER = new ByteArrayBuffer(HTTP), /* ------------------------------------------------------------ */
HTTPS_BUFFER = new ByteArrayBuffer(HTTPS); public final static StringMap<HttpSchemes> CACHE= new StringMap<HttpSchemes>(true);
static
{
for (HttpSchemes version : HttpSchemes.values())
CACHE.put(version.toString(),version);
}
private final String _string;
private final ByteBuffer _buffer;
/* ------------------------------------------------------------ */
HttpSchemes(String s)
{
_string=s;
_buffer=BufferUtil.toBuffer(s);
}
/* ------------------------------------------------------------ */
public ByteBuffer toBuffer()
{
return _buffer.asReadOnlyBuffer();
}
/* ------------------------------------------------------------ */
public String toString()
{
return _string;
}
} }

View File

@ -502,14 +502,14 @@ public class HttpURI
_raw[_scheme+1]=='t' && _raw[_scheme+1]=='t' &&
_raw[_scheme+2]=='t' && _raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' ) _raw[_scheme+3]=='p' )
return HttpSchemes.HTTP; return HttpSchemes.HTTP.toString();
if (l==6 && if (l==6 &&
_raw[_scheme]=='h' && _raw[_scheme]=='h' &&
_raw[_scheme+1]=='t' && _raw[_scheme+1]=='t' &&
_raw[_scheme+2]=='t' && _raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' && _raw[_scheme+3]=='p' &&
_raw[_scheme+4]=='s' ) _raw[_scheme+4]=='s' )
return HttpSchemes.HTTPS; return HttpSchemes.HTTPS.toString();
return toUtf8String(_scheme,_authority-_scheme-1); return toUtf8String(_scheme,_authority-_scheme-1);
} }

View File

@ -13,30 +13,54 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.io.BufferCache;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/** public enum HttpVersions
*
*
*/
public class HttpVersions
{ {
public final static String HTTP_0_9("HTTP/0.9",9),
HTTP_0_9 = "", HTTP_1_0("HTTP/1.0",10),
HTTP_1_0 = "HTTP/1.0", HTTP_1_1("HTTP/1.1",11);
HTTP_1_1 = "HTTP/1.1";
/* ------------------------------------------------------------ */
public final static int public final static StringMap<HttpVersions> CACHE= new StringMap<HttpVersions>(true);
HTTP_0_9_ORDINAL=9, static
HTTP_1_0_ORDINAL=10, {
HTTP_1_1_ORDINAL=11; for (HttpVersions version : HttpVersions.values())
CACHE.put(version.toString(),version);
public final static BufferCache CACHE = new BufferCache(); }
public final static Buffer private final String _string;
HTTP_0_9_BUFFER=CACHE.add(HTTP_0_9,HTTP_0_9_ORDINAL), private final ByteBuffer _buffer;
HTTP_1_0_BUFFER=CACHE.add(HTTP_1_0,HTTP_1_0_ORDINAL), private final int _version;
HTTP_1_1_BUFFER=CACHE.add(HTTP_1_1,HTTP_1_1_ORDINAL);
/* ------------------------------------------------------------ */
HttpVersions(String s,int version)
{
_string=s;
_buffer=BufferUtil.toBuffer(s);
_version=version;
}
/* ------------------------------------------------------------ */
public ByteBuffer toBuffer()
{
return _buffer.asReadOnlyBuffer();
}
/* ------------------------------------------------------------ */
public int getVerion()
{
return _version;
}
/* ------------------------------------------------------------ */
public String toString()
{
return _string;
}
} }

View File

@ -13,16 +13,15 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import java.nio.ByteBuffer;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.io.BufferCache; import org.eclipse.jetty.util.StringMap;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -34,94 +33,73 @@ import org.eclipse.jetty.util.log.Logger;
*/ */
public class MimeTypes public class MimeTypes
{ {
public enum Type
{
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 String _string;
private final ByteBuffer _buffer;
/* ------------------------------------------------------------ */
Type(String s)
{
_string=s;
_buffer=BufferUtil.toBuffer(s);
}
/* ------------------------------------------------------------ */
public ByteBuffer toBuffer()
{
return _buffer.asReadOnlyBuffer();
}
/* ------------------------------------------------------------ */
public String toString()
{
return _string;
}
}
/* ------------------------------------------------------------ */
private static final Logger LOG = Log.getLogger(MimeTypes.class); private static final Logger LOG = Log.getLogger(MimeTypes.class);
private final static StringMap<MimeTypes.Type> CACHE= new StringMap<MimeTypes.Type>(true);
public final static String private final static StringMap<ByteBuffer> TYPES= new StringMap<ByteBuffer>(true);
FORM_ENCODED="application/x-www-form-urlencoded", private final static Map<String,ByteBuffer> __dftMimeMap = new HashMap<String,ByteBuffer>();
MESSAGE_HTTP="message/http", private final static Map<String,String> __encodings = new HashMap<String,String>();
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 int
FORM_ENCODED_ORDINAL=1,
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_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),
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 static
{ {
for (MimeTypes.Type type : MimeTypes.Type.values())
{
CACHE.put(type.toString(),type);
TYPES.put(type.toString(),type.toBuffer());
int charset=type.toString().indexOf(";charset=");
if (charset>0)
{
CACHE.put(type.toString().replace(";charset=","; charset="),type);
TYPES.put(type.toString().replace(";charset=","; charset="),type.toBuffer());
}
}
try try
{ {
ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime"); ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime");
@ -142,11 +120,11 @@ public class MimeTypes
try try
{ {
ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding"); ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding");
Enumeration i = encoding.getKeys(); Enumeration<String> i = encoding.getKeys();
while(i.hasMoreElements()) while(i.hasMoreElements())
{ {
Buffer type = normalizeMimeType((String)i.nextElement()); String type = i.nextElement();
__encodings.put(type,encoding.getString(type.toString())); __encodings.put(type,encoding.getString(type));
} }
} }
catch(MissingResourceException e) catch(MissingResourceException e)
@ -156,37 +134,11 @@ public class MimeTypes
} }
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);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private Map _mimeMap; private final Map<String,ByteBuffer> _mimeMap=new HashMap<String,ByteBuffer>();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Constructor. /** Constructor.
@ -196,7 +148,7 @@ public class MimeTypes
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public synchronized Map getMimeMap() public synchronized Map<String,ByteBuffer> getMimeMap()
{ {
return _mimeMap; return _mimeMap;
} }
@ -205,22 +157,14 @@ public class MimeTypes
/** /**
* @param mimeMap A Map of file extension to mime-type. * @param mimeMap A Map of file extension to mime-type.
*/ */
public void setMimeMap(Map mimeMap) public void setMimeMap(Map<String,String> mimeMap)
{ {
if (mimeMap==null) _mimeMap.clear();
if (mimeMap!=null)
{ {
_mimeMap=null; for (String ext : mimeMap.keySet())
return; _mimeMap.put(StringUtil.asciiToLowerCase(ext),normalizeMimeType(mimeMap.get(ext)));
} }
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;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -229,9 +173,9 @@ public class MimeTypes
* @return MIME type matching the longest dot extension of the * @return MIME type matching the longest dot extension of the
* file name. * file name.
*/ */
public Buffer getMimeByExtension(String filename) public ByteBuffer getMimeByExtension(String filename)
{ {
Buffer type=null; ByteBuffer type=null;
if (filename!=null) if (filename!=null)
{ {
@ -245,18 +189,18 @@ public class MimeTypes
String ext=StringUtil.asciiToLowerCase(filename.substring(i+1)); String ext=StringUtil.asciiToLowerCase(filename.substring(i+1));
if (_mimeMap!=null) if (_mimeMap!=null)
type = (Buffer)_mimeMap.get(ext); type=_mimeMap.get(ext);
if (type==null) if (type==null)
type=(Buffer)__dftMimeMap.get(ext); type=__dftMimeMap.get(ext);
} }
} }
if (type==null) if (type==null)
{ {
if (_mimeMap!=null) if (_mimeMap!=null)
type=(Buffer)_mimeMap.get("*"); type=_mimeMap.get("*");
if (type==null) if (type==null)
type=(Buffer)__dftMimeMap.get("*"); type=__dftMimeMap.get("*");
} }
return type; return type;
@ -269,49 +213,30 @@ public class MimeTypes
*/ */
public void addMimeMapping(String extension,String type) public void addMimeMapping(String extension,String type)
{ {
if (_mimeMap==null)
_mimeMap=new HashMap();
_mimeMap.put(StringUtil.asciiToLowerCase(extension),normalizeMimeType(type)); _mimeMap.put(StringUtil.asciiToLowerCase(extension),normalizeMimeType(type));
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private static synchronized Buffer normalizeMimeType(String type) private static ByteBuffer normalizeMimeType(String type)
{ {
Buffer b =CACHE.get(type); MimeTypes.Type t =CACHE.get(type);
if (b==null) if (t!=null)
b=CACHE.add(type,__index++); return t.toBuffer();
return b;
return BufferUtil.toBuffer(StringUtil.asciiToLowerCase(type));
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static String getCharsetFromContentType(Buffer value) public static String getCharsetFromContentType(ByteBuffer value)
{ {
if (value instanceof CachedBuffer) int i=value.position();
{ int end=value.limit();
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 state=0;
int start=0; int start=0;
boolean quote=false; boolean quote=false;
for (;i<end;i++) for (;i<end;i++)
{ {
byte b = value.peek(i); byte b = value.get(i);
if (quote && state!=10) if (quote && state!=10)
{ {
@ -359,12 +284,12 @@ public class MimeTypes
case 10: case 10:
if (!quote && (';'==b || ' '==b )|| if (!quote && (';'==b || ' '==b )||
(quote && '"'==b )) (quote && '"'==b ))
return CACHE.lookup(value.peek(start,i-start)).toString(); return StringUtil.normalizeCharset(value,start,i-start);
} }
} }
if (state==10) if (state==10)
return CACHE.lookup(value.peek(start,i-start)).toString(); return StringUtil.normalizeCharset(value,start,i-start);
return (String)__encodings.get(value); return (String)__encodings.get(value);
} }

View File

@ -14,13 +14,13 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer;
/** /**
* Abstract interface for a connection Parser for use by Jetty. * Abstract interface for a connection Parser for use by Jetty.
*/ */
public interface Parser public interface Parser
{ {
void returnBuffers();
void reset(); void reset();
boolean isComplete(); boolean isComplete();
@ -29,10 +29,10 @@ public interface Parser
* @return True if progress made * @return True if progress made
* @throws IOException * @throws IOException
*/ */
boolean parseAvailable() throws IOException; boolean parseAvailable(ByteBuffer buffer) throws IOException;
boolean isMoreInBuffer() throws IOException;
boolean onEOF()throws IOException;
boolean isIdle(); boolean isIdle();
boolean isPersistent(); boolean isPersistent();

View File

@ -1,180 +1,180 @@
ai = application/postscript ai=application/postscript
aif = audio/x-aiff aif=audio/x-aiff
aifc = audio/x-aiff aifc=audio/x-aiff
aiff = audio/x-aiff aiff=audio/x-aiff
apk = application/vnd.android.package-archive apk=application/vnd.android.package-archive
asc = text/plain asc=text/plain
asf = video/x.ms.asf asf=video/x.ms.asf
asx = video/x.ms.asx asx=video/x.ms.asx
au = audio/basic au=audio/basic
avi = video/x-msvideo avi=video/x-msvideo
bcpio = application/x-bcpio bcpio=application/x-bcpio
bin = application/octet-stream bin=application/octet-stream
cab = application/x-cabinet cab=application/x-cabinet
cdf = application/x-netcdf cdf=application/x-netcdf
class = application/java-vm class=application/java-vm
cpio = application/x-cpio cpio=application/x-cpio
cpt = application/mac-compactpro cpt=application/mac-compactpro
crt = application/x-x509-ca-cert crt=application/x-x509-ca-cert
csh = application/x-csh csh=application/x-csh
css = text/css css=text/css
csv = text/comma-separated-values csv=text/comma-separated-values
dcr = application/x-director dcr=application/x-director
dir = application/x-director dir=application/x-director
dll = application/x-msdownload dll=application/x-msdownload
dms = application/octet-stream dms=application/octet-stream
doc = application/msword doc=application/msword
dtd = application/xml-dtd dtd=application/xml-dtd
dvi = application/x-dvi dvi=application/x-dvi
dxr = application/x-director dxr=application/x-director
eps = application/postscript eps=application/postscript
etx = text/x-setext etx=text/x-setext
exe = application/octet-stream exe=application/octet-stream
ez = application/andrew-inset ez=application/andrew-inset
gif = image/gif gif=image/gif
gtar = application/x-gtar gtar=application/x-gtar
gz = application/gzip gz=application/gzip
gzip = application/gzip gzip=application/gzip
hdf = application/x-hdf hdf=application/x-hdf
hqx = application/mac-binhex40 hqx=application/mac-binhex40
htc = text/x-component htc=text/x-component
htm = text/html htm=text/html
html = text/html html=text/html
ice = x-conference/x-cooltalk ice=x-conference/x-cooltalk
ico = image/x-icon ico=image/x-icon
ief = image/ief ief=image/ief
iges = model/iges iges=model/iges
igs = model/iges igs=model/iges
jad = text/vnd.sun.j2me.app-descriptor jad=text/vnd.sun.j2me.app-descriptor
jar = application/java-archive jar=application/java-archive
java = text/plain java=text/plain
jnlp = application/x-java-jnlp-file jnlp=application/x-java-jnlp-file
jpe = image/jpeg jpe=image/jpeg
jpeg = image/jpeg jpeg=image/jpeg
jpg = image/jpeg jpg=image/jpeg
js = application/x-javascript js=application/x-javascript
jsp = text/html jsp=text/html
kar = audio/midi kar=audio/midi
latex = application/x-latex latex=application/x-latex
lha = application/octet-stream lha=application/octet-stream
lzh = application/octet-stream lzh=application/octet-stream
man = application/x-troff-man man=application/x-troff-man
mathml = application/mathml+xml mathml=application/mathml+xml
me = application/x-troff-me me=application/x-troff-me
mesh = model/mesh mesh=model/mesh
mid = audio/midi mid=audio/midi
midi = audio/midi midi=audio/midi
mif = application/vnd.mif mif=application/vnd.mif
mol = chemical/x-mdl-molfile mol=chemical/x-mdl-molfile
mov = video/quicktime mov=video/quicktime
movie = video/x-sgi-movie movie=video/x-sgi-movie
mp2 = audio/mpeg mp2=audio/mpeg
mp3 = audio/mpeg mp3=audio/mpeg
mpe = video/mpeg mpe=video/mpeg
mpeg = video/mpeg mpeg=video/mpeg
mpg = video/mpeg mpg=video/mpeg
mpga = audio/mpeg mpga=audio/mpeg
ms = application/x-troff-ms ms=application/x-troff-ms
msh = model/mesh msh=model/mesh
msi = application/octet-stream msi=application/octet-stream
nc = application/x-netcdf nc=application/x-netcdf
oda = application/oda oda=application/oda
odb = application/vnd.oasis.opendocument.database odb=application/vnd.oasis.opendocument.database
odc = application/vnd.oasis.opendocument.chart odc=application/vnd.oasis.opendocument.chart
odf = application/vnd.oasis.opendocument.formula odf=application/vnd.oasis.opendocument.formula
odg = application/vnd.oasis.opendocument.graphics odg=application/vnd.oasis.opendocument.graphics
odi = application/vnd.oasis.opendocument.image odi=application/vnd.oasis.opendocument.image
odm = application/vnd.oasis.opendocument.text-master odm=application/vnd.oasis.opendocument.text-master
odp = application/vnd.oasis.opendocument.presentation odp=application/vnd.oasis.opendocument.presentation
ods = application/vnd.oasis.opendocument.spreadsheet ods=application/vnd.oasis.opendocument.spreadsheet
odt = application/vnd.oasis.opendocument.text odt=application/vnd.oasis.opendocument.text
ogg = application/ogg ogg=application/ogg
otc = application/vnd.oasis.opendocument.chart-template otc=application/vnd.oasis.opendocument.chart-template
otf = application/vnd.oasis.opendocument.formula-template otf=application/vnd.oasis.opendocument.formula-template
otg = application/vnd.oasis.opendocument.graphics-template otg=application/vnd.oasis.opendocument.graphics-template
oth = application/vnd.oasis.opendocument.text-web oth=application/vnd.oasis.opendocument.text-web
oti = application/vnd.oasis.opendocument.image-template oti=application/vnd.oasis.opendocument.image-template
otp = application/vnd.oasis.opendocument.presentation-template otp=application/vnd.oasis.opendocument.presentation-template
ots = application/vnd.oasis.opendocument.spreadsheet-template ots=application/vnd.oasis.opendocument.spreadsheet-template
ott = application/vnd.oasis.opendocument.text-template ott=application/vnd.oasis.opendocument.text-template
pbm = image/x-portable-bitmap pbm=image/x-portable-bitmap
pdb = chemical/x-pdb pdb=chemical/x-pdb
pdf = application/pdf pdf=application/pdf
pgm = image/x-portable-graymap pgm=image/x-portable-graymap
pgn = application/x-chess-pgn pgn=application/x-chess-pgn
png = image/png png=image/png
pnm = image/x-portable-anymap pnm=image/x-portable-anymap
ppm = image/x-portable-pixmap ppm=image/x-portable-pixmap
pps = application/vnd.ms-powerpoint pps=application/vnd.ms-powerpoint
ppt = application/vnd.ms-powerpoint ppt=application/vnd.ms-powerpoint
ps = application/postscript ps=application/postscript
qt = video/quicktime qt=video/quicktime
ra = audio/x-pn-realaudio ra=audio/x-pn-realaudio
ram = audio/x-pn-realaudio ram=audio/x-pn-realaudio
ras = image/x-cmu-raster ras=image/x-cmu-raster
rdf = application/rdf+xml rdf=application/rdf+xml
rgb = image/x-rgb rgb=image/x-rgb
rm = audio/x-pn-realaudio rm=audio/x-pn-realaudio
roff = application/x-troff roff=application/x-troff
rpm = application/x-rpm rpm=application/x-rpm
rtf = application/rtf rtf=application/rtf
rtx = text/richtext rtx=text/richtext
rv = video/vnd.rn-realvideo rv=video/vnd.rn-realvideo
ser = application/java-serialized-object ser=application/java-serialized-object
sgm = text/sgml sgm=text/sgml
sgml = text/sgml sgml=text/sgml
sh = application/x-sh sh=application/x-sh
shar = application/x-shar shar=application/x-shar
silo = model/mesh silo=model/mesh
sit = application/x-stuffit sit=application/x-stuffit
skd = application/x-koan skd=application/x-koan
skm = application/x-koan skm=application/x-koan
skp = application/x-koan skp=application/x-koan
skt = application/x-koan skt=application/x-koan
smi = application/smil smi=application/smil
smil = application/smil smil=application/smil
snd = audio/basic snd=audio/basic
spl = application/x-futuresplash spl=application/x-futuresplash
src = application/x-wais-source src=application/x-wais-source
sv4cpio = application/x-sv4cpio sv4cpio=application/x-sv4cpio
sv4crc = application/x-sv4crc sv4crc=application/x-sv4crc
svg = image/svg+xml svg=image/svg+xml
swf = application/x-shockwave-flash swf=application/x-shockwave-flash
t = application/x-troff t=application/x-troff
tar = application/x-tar tar=application/x-tar
tar.gz = application/x-gtar tar.gz=application/x-gtar
tcl = application/x-tcl tcl=application/x-tcl
tex = application/x-tex tex=application/x-tex
texi = application/x-texinfo texi=application/x-texinfo
texinfo = application/x-texinfo texinfo=application/x-texinfo
tgz = application/x-gtar tgz=application/x-gtar
tif = image/tiff tif=image/tiff
tiff = image/tiff tiff=image/tiff
tr = application/x-troff tr=application/x-troff
tsv = text/tab-separated-values tsv=text/tab-separated-values
txt = text/plain txt=text/plain
ustar = application/x-ustar ustar=application/x-ustar
vcd = application/x-cdlink vcd=application/x-cdlink
vrml = model/vrml vrml=model/vrml
vxml = application/voicexml+xml vxml=application/voicexml+xml
wav = audio/x-wav wav=audio/x-wav
wbmp = image/vnd.wap.wbmp wbmp=image/vnd.wap.wbmp
wml = text/vnd.wap.wml wml=text/vnd.wap.wml
wmlc = application/vnd.wap.wmlc wmlc=application/vnd.wap.wmlc
wmls = text/vnd.wap.wmlscript wmls=text/vnd.wap.wmlscript
wmlsc = application/vnd.wap.wmlscriptc wmlsc=application/vnd.wap.wmlscriptc
wrl = model/vrml wrl=model/vrml
wtls-ca-certificate = application/vnd.wap.wtls-ca-certificate wtls-ca-certificate=application/vnd.wap.wtls-ca-certificate
xbm = image/x-xbitmap xbm=image/x-xbitmap
xht = application/xhtml+xml xht=application/xhtml+xml
xhtml = application/xhtml+xml xhtml=application/xhtml+xml
xls = application/vnd.ms-excel xls=application/vnd.ms-excel
xml = application/xml xml=application/xml
xpm = image/x-xpixmap xpm=image/x-xpixmap
xsl = application/xml xsl=application/xml
xslt = application/xslt+xml xslt=application/xslt+xml
xul = application/vnd.mozilla.xul+xml xul=application/vnd.mozilla.xul+xml
xwd = image/x-xwindowdump xwd=image/x-xwindowdump
xyz = chemical/x-xyz xyz=chemical/x-xyz
z = application/compress z=application/compress
zip = application/zip zip=application/zip

View File

@ -18,15 +18,16 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.io.BufferCache.CachedBuffer; import org.junit.Assert;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.View;
import org.junit.Test; import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
/** /**
* *
@ -46,7 +47,7 @@ public class HttpFieldsTest
assertNull(header.getStringField("name2")); assertNull(header.getStringField("name2"));
int matches=0; int matches=0;
Enumeration e = header.getFieldNames(); Enumeration<String> e = header.getFieldNames();
while (e.hasMoreElements()) while (e.hasMoreElements())
{ {
Object o=e.nextElement(); Object o=e.nextElement();
@ -69,7 +70,7 @@ public class HttpFieldsTest
HttpFields header = new HttpFields(); HttpFields header = new HttpFields();
header.put("name0", "value0"); header.put("name0", "value0");
header.put(new ByteArrayBuffer("name1"), new ByteArrayBuffer("value1")); header.put("name1", "value1");
assertEquals("value0",header.getStringField("name0")); assertEquals("value0",header.getStringField("name0"));
assertEquals("value0",header.getStringField("Name0")); assertEquals("value0",header.getStringField("Name0"));
@ -86,11 +87,14 @@ public class HttpFieldsTest
header.put("name\r\n1", "value1"); header.put("name\r\n1", "value1");
header.put("name:2", "value:\r\n2"); header.put("name:2", "value:\r\n2");
ByteArrayBuffer buffer = new ByteArrayBuffer(1024); ByteBuffer buffer = BufferUtil.allocate(1024);
buffer.clear();
header.putTo(buffer); header.putTo(buffer);
assertTrue(buffer.toString().contains("name0: value0")); buffer.flip();
assertTrue(buffer.toString().contains("name1: value1")); String out = BufferUtil.toString(buffer);
assertTrue(buffer.toString().contains("name2: value:2")); assertTrue(out.contains("name0: value??0"));
assertTrue(out.contains("name??1: value1"));
assertTrue(out.contains("name?2: value???2"));
} }
@Test @Test
@ -98,20 +102,22 @@ public class HttpFieldsTest
{ {
HttpFields header = new HttpFields(); HttpFields header = new HttpFields();
header.put("Connection", "keep-alive"); header.put("Connection", "Keep-Alive");
assertEquals(HttpHeaderValues.KEEP_ALIVE, header.getStringField(HttpHeaders.CONNECTION)); header.put("tRansfer-EncOding", "CHUNKED");
header.put("CONTENT-ENCODING", "gZIP");
int matches=0; ByteBuffer buffer = BufferUtil.allocate(1024);
Enumeration e = header.getFieldNames(); buffer.clear();
while (e.hasMoreElements()) header.putTo(buffer);
{ buffer.flip();
Object o=e.nextElement(); String out = BufferUtil.toString(buffer);
if (o==HttpHeaders.CONTENT_TYPE)
matches++; Assert.assertThat(out,JUnitMatchers.containsString(HttpHeaders.CONNECTION+": "+HttpHeaderValues.KEEP_ALIVE));
if (o==HttpHeaders.CONNECTION) Assert.assertThat(out,JUnitMatchers.containsString(HttpHeaders.TRANSFER_ENCODING+": "+HttpHeaderValues.CHUNKED));
matches++; Assert.assertThat(out,JUnitMatchers.containsString(HttpHeaders.CONTENT_ENCODING+": "+HttpHeaderValues.GZIP));
}
assertEquals(1, matches);
} }
@Test @Test
@ -175,7 +181,7 @@ public class HttpFieldsTest
assertNull(header.getStringField("name3")); assertNull(header.getStringField("name3"));
int matches=0; int matches=0;
Enumeration e = header.getFieldNames(); Enumeration<String> e = header.getFieldNames();
while (e.hasMoreElements()) while (e.hasMoreElements())
{ {
Object o=e.nextElement(); Object o=e.nextElement();
@ -213,7 +219,7 @@ public class HttpFieldsTest
assertNull(fields.getStringField("name3")); assertNull(fields.getStringField("name3"));
int matches=0; int matches=0;
Enumeration e = fields.getFieldNames(); Enumeration<String> e = fields.getFieldNames();
while (e.hasMoreElements()) while (e.hasMoreElements())
{ {
Object o=e.nextElement(); Object o=e.nextElement();
@ -234,122 +240,7 @@ public class HttpFieldsTest
assertEquals(false, e.hasMoreElements()); assertEquals(false, e.hasMoreElements());
} }
@Test
public void testReuse() throws Exception
{
HttpFields header = new HttpFields();
Buffer n1=new ByteArrayBuffer("name1");
Buffer va=new ByteArrayBuffer("value1");
Buffer vb=new ByteArrayBuffer(10);
vb.put((byte)'v');
vb.put((byte)'a');
vb.put((byte)'l');
vb.put((byte)'u');
vb.put((byte)'e');
vb.put((byte)'1');
header.put("name0", "value0");
header.put(n1,va);
header.put("name2", "value2");
assertEquals("value0",header.getStringField("name0"));
assertEquals("value1",header.getStringField("name1"));
assertEquals("value2",header.getStringField("name2"));
assertNull(header.getStringField("name3"));
header.remove(n1);
assertNull(header.getStringField("name1"));
header.put(n1,vb);
assertEquals("value1",header.getStringField("name1"));
int matches=0;
Enumeration e = header.getFieldNames();
while (e.hasMoreElements())
{
Object o=e.nextElement();
if ("name0".equals(o))
matches++;
if ("name1".equals(o))
matches++;
if ("name2".equals(o))
matches++;
}
assertEquals(3, matches);
e = header.getValues("name1");
assertEquals(true, e.hasMoreElements());
assertEquals(e.nextElement(), "value1");
assertEquals(false, e.hasMoreElements());
}
@Test
public void testCase() throws Exception
{
HttpFields fields= new HttpFields();
Set s;
// 0123456789012345678901234567890
byte[] b ="Message-IDmessage-idvalueVALUE".getBytes();
ByteArrayBuffer buf= new ByteArrayBuffer(512);
buf.put(b);
View headUC= new View.CaseInsensitive(buf);
View headLC= new View.CaseInsensitive(buf);
View valUC = new View(buf);
View valLC = new View(buf);
headUC.update(0,10);
headLC.update(10,20);
valUC.update(20,25);
valLC.update(25,30);
fields.add("header","value");
fields.add(headUC,valLC);
fields.add("other","data");
s=enum2set(fields.getFieldNames());
assertEquals(3,s.size());
assertTrue(s.contains("message-id"));
assertEquals("value",fields.getStringField("message-id").toLowerCase());
assertEquals("value",fields.getStringField("Message-ID").toLowerCase());
fields.clear();
fields.add("header","value");
fields.add(headLC,valLC);
fields.add("other","data");
s=enum2set(fields.getFieldNames());
assertEquals(3,s.size());
assertTrue(s.contains("message-id"));
assertEquals("value",fields.getStringField("Message-ID").toLowerCase());
assertEquals("value",fields.getStringField("message-id").toLowerCase());
fields.clear();
fields.add("header","value");
fields.add(headUC,valUC);
fields.add("other","data");
s=enum2set(fields.getFieldNames());
assertEquals(3,s.size());
assertTrue(s.contains("message-id"));
assertEquals("value",fields.getStringField("message-id").toLowerCase());
assertEquals("value",fields.getStringField("Message-ID").toLowerCase());
fields.clear();
fields.add("header","value");
fields.add(headLC,valUC);
fields.add("other","data");
s=enum2set(fields.getFieldNames());
assertEquals(3,s.size());
assertTrue(s.contains("message-id"));
assertEquals("value",fields.getStringField("Message-ID").toLowerCase());
assertEquals("value",fields.getStringField("message-id").toLowerCase());
}
@Test
public void testHttpHeaderValues() throws Exception
{
assertTrue(((CachedBuffer)HttpHeaderValues.CACHE.lookup("unknown value")).getOrdinal()<0);
assertTrue(((CachedBuffer)HttpHeaderValues.CACHE.lookup("close")).getOrdinal()>=0);
}
@Test @Test
public void testSetCookie() throws Exception public void testSetCookie() throws Exception
@ -524,17 +415,4 @@ public class HttpFieldsTest
} }
@Test
public void testToString() throws Exception
{
HttpFields header = new HttpFields();
header.put(new ByteArrayBuffer("name0"), new View(new ByteArrayBuffer("value0")));
header.put(new ByteArrayBuffer("name1"), new View(new ByteArrayBuffer("value1".getBytes())));
String s1=header.toString();
String s2=header.toString();
//System.err.println(s1);
//System.err.println(s2);
assertEquals(s1,s2);
}
} }

View File

@ -17,11 +17,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.SimpleBuffers; import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.io.bio.StringEndPoint; import org.eclipse.jetty.io.bio.StringEndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.junit.Test; import org.junit.Test;
@ -33,14 +33,11 @@ public class HttpParserTest
@Test @Test
public void testLineParse0() throws Exception public void testLineParse0() throws Exception
{ {
StringEndPoint io=new StringEndPoint(); ByteBuffer buffer= BufferUtil.toBuffer("POST /foo HTTP/1.0\015\012" + "\015\012");
io.setInput("POST /foo HTTP/1.0\015\012" + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
HttpParser parser= new HttpParser(buffers,io, handler); HttpParser parser= new HttpParser((HttpParser.RequestHandler)handler);
parser.parse(); parser.parse(buffer);
assertEquals("POST", f0); assertEquals("POST", f0);
assertEquals("/foo", f1); assertEquals("/foo", f1);
assertEquals("HTTP/1.0", f2); assertEquals("HTTP/1.0", f2);
@ -52,7 +49,7 @@ public class HttpParserTest
{ {
StringEndPoint io=new StringEndPoint(); StringEndPoint io=new StringEndPoint();
io.setInput("GET /999\015\012"); io.setInput("GET /999\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
f2= null; f2= null;
@ -70,7 +67,7 @@ public class HttpParserTest
{ {
StringEndPoint io=new StringEndPoint(); StringEndPoint io=new StringEndPoint();
io.setInput("POST /222 \015\012"); io.setInput("POST /222 \015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
f2= null; f2= null;
@ -88,7 +85,7 @@ public class HttpParserTest
{ {
StringEndPoint io=new StringEndPoint(); StringEndPoint io=new StringEndPoint();
io.setInput("POST /fo\u0690 HTTP/1.0\015\012" + "\015\012"); io.setInput("POST /fo\u0690 HTTP/1.0\015\012" + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -105,7 +102,7 @@ public class HttpParserTest
{ {
StringEndPoint io=new StringEndPoint(); StringEndPoint io=new StringEndPoint();
io.setInput("POST /foo?param=\u0690 HTTP/1.0\015\012" + "\015\012"); io.setInput("POST /foo?param=\u0690 HTTP/1.0\015\012" + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -122,7 +119,7 @@ public class HttpParserTest
{ {
StringEndPoint io=new StringEndPoint(); StringEndPoint io=new StringEndPoint();
io.setInput("CONNECT 192.168.1.2:80 HTTP/1.1\015\012" + "\015\012"); io.setInput("CONNECT 192.168.1.2:80 HTTP/1.1\015\012" + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -150,7 +147,7 @@ public class HttpParserTest
+ " value4\015\012" + " value4\015\012"
+ "Server5: notServer\015\012" + "Server5: notServer\015\012"
+ "\015\012"); + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -188,8 +185,8 @@ public class HttpParserTest
+ "1a\015\012" + "1a\015\012"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012"
+ "0\015\012"); + "0\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
ByteArrayBuffer content=new ByteArrayBuffer(8192); ByteBuffer content=BufferUtil.allocate(8192);
SimpleBuffers buffers=new SimpleBuffers(buffer,content); SimpleBuffers buffers=new SimpleBuffers(buffer,content);
Handler handler = new Handler(); Handler handler = new Handler();
@ -231,8 +228,8 @@ public class HttpParserTest
+ "\015\012" + "\015\012"
+ "0123456789\015\012"); + "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
ByteArrayBuffer content=new ByteArrayBuffer(8192); ByteBuffer content=BufferUtil.allocate(8192);
SimpleBuffers buffers=new SimpleBuffers(buffer,content); SimpleBuffers buffers=new SimpleBuffers(buffer,content);
Handler handler = new Handler(); Handler handler = new Handler();
@ -314,8 +311,8 @@ public class HttpParserTest
{ {
f0=f1=f2=null; f0=f1=f2=null;
h=0; h=0;
ByteArrayBuffer buffer= new ByteArrayBuffer(tests[t]); ByteBuffer buffer= BufferUtil.allocate(tests[t]);
ByteArrayBuffer content=new ByteArrayBuffer(8192); ByteBuffer content=BufferUtil.allocate(8192);
SimpleBuffers buffers=new SimpleBuffers(buffer,content); SimpleBuffers buffers=new SimpleBuffers(buffer,content);
Handler handler = new Handler(); Handler handler = new Handler();
@ -370,7 +367,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012" + "Content-Type: text/plain\015\012"
+ "\015\012" + "\015\012"
+ "0123456789\015\012"); + "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -392,7 +389,7 @@ public class HttpParserTest
"HTTP/1.1 304 Not-Modified\015\012" "HTTP/1.1 304 Not-Modified\015\012"
+ "Connection: close\015\012" + "Connection: close\015\012"
+ "\015\012"); + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -418,7 +415,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012" + "Content-Type: text/plain\015\012"
+ "\015\012" + "\015\012"
+ "0123456789\015\012"); + "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -450,7 +447,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012" + "Content-Type: text/plain\015\012"
+ "\015\012" + "\015\012"
+ "0123456789\015\012"); + "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -474,7 +471,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012" + "Content-Type: text/plain\015\012"
+ "\015\012" + "\015\012"
+ "0123456789\015\012"); + "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -496,7 +493,7 @@ public class HttpParserTest
"HTTP/1.1 304 found\015\012" "HTTP/1.1 304 found\015\012"
+ "Content-Length: 10\015\012" + "Content-Length: 10\015\012"
+ "\015\012"); + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -523,7 +520,7 @@ public class HttpParserTest
+ "HTTP/1.1 400 OK\015\012"); // extra data causes close + "HTTP/1.1 400 OK\015\012"); // extra data causes close
ByteArrayBuffer buffer= new ByteArrayBuffer(4096); ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null); SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler(); Handler handler = new Handler();
@ -551,48 +548,37 @@ public class HttpParserTest
private boolean headerCompleted; private boolean headerCompleted;
private boolean messageCompleted; private boolean messageCompleted;
private class Handler extends HttpParser.EventHandler private class Handler implements HttpParser.RequestHandler, HttpParser.ResponseHandler
{ {
private HttpFields fields; private HttpFields fields;
private boolean request; private boolean request;
public void content(Buffer ref) public void content(ByteBuffer ref)
{ {
if (_content==null) if (_content==null)
_content=""; _content="";
_content= _content + ref; _content= _content + ref;
} }
public void startRequest(Buffer tok0, Buffer tok1, Buffer tok2) public void startRequest(String tok0, String tok1, String tok2)
{ {
try request=true;
{ h= -1;
request=true; hdr= new String[9];
h= -1; val= new String[9];
hdr= new String[9]; f0= tok0;
val= new String[9]; f1= tok1;
f0= tok0.toString(); f2= tok2;
f1=new String(tok1.array(),tok1.getIndex(),tok1.length(),StringUtil.__UTF8);
if (tok2!=null)
f2= tok2.toString();
else
f2=null;
fields=new HttpFields();
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
fields=new HttpFields();
messageCompleted = false; messageCompleted = false;
headerCompleted = false; headerCompleted = false;
} }
public void parsedHeader(Buffer name, Buffer value) public void parsedHeader(String name, String value)
{ {
hdr[++h]= name.toString(StringUtil.__ISO_8859_1); hdr[++h]= name;
val[h]= value.toString(StringUtil.__ISO_8859_1); val[h]= value;
} }
public void headerComplete() public void headerComplete()
@ -615,7 +601,7 @@ public class HttpParserTest
messageCompleted = true; messageCompleted = true;
} }
public void startResponse(Buffer version, int status, Buffer reason) public void startResponse(String version, int status, String reason)
{ {
request=false; request=false;
f0 = version.toString(); f0 = version.toString();
@ -629,5 +615,10 @@ public class HttpParserTest
messageCompleted = false; messageCompleted = false;
headerCompleted = false; headerCompleted = false;
} }
@Override
public void earlyEOF()
{
}
} }
} }

View File

@ -28,6 +28,6 @@ public class HttpStatusCodeTest
public void testHttpMethod() public void testHttpMethod()
{ {
assertEquals("GET",HttpMethods.GET_BUFFER.toString()); assertEquals("GET",HttpMethods.GET.toString());
} }
} }

View File

@ -1,6 +1,8 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -42,9 +44,9 @@ public class MimeTypesTest
private void assertMimeTypeByExtension(String expectedMimeType, String filename) private void assertMimeTypeByExtension(String expectedMimeType, String filename)
{ {
MimeTypes mimetypes = new MimeTypes(); MimeTypes mimetypes = new MimeTypes();
Buffer contentType = mimetypes.getMimeByExtension(filename); ByteBuffer contentType = mimetypes.getMimeByExtension(filename);
String prefix = "MimeTypes.getMimeByExtension(" + filename + ")"; String prefix = "MimeTypes.getMimeByExtension(" + filename + ")";
Assert.assertNotNull(prefix,contentType); Assert.assertNotNull(prefix,contentType);
Assert.assertEquals(prefix,expectedMimeType,contentType.toString()); Assert.assertEquals(prefix,expectedMimeType,BufferUtil.toString(contentType));
} }
} }

View File

@ -2,6 +2,8 @@ package org.eclipse.jetty.io;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
public abstract class AbstractBuffers implements Buffers public abstract class AbstractBuffers implements Buffers
{ {

View File

@ -1,201 +0,0 @@
// ========================================================================
// Copyright (c) 2004-2009 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.io;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.jetty.util.StringMap;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------------------------- */
/**
* Stores a collection of {@link ByteBuffer} objects.
* Buffers are stored in an ordered collection and can retreived by index or value
*
*/
public class BufferCache
{
private final StringMap _stringMap=new StringMap(StringMap.CASE_INSENSTIVE);
private final ArrayList<CachedBuffer> _index= new ArrayList<CachedBuffer>();
/* ------------------------------------------------------------------------------- */
/** Add a buffer to the cache at the specified index.
* @param value The content of the buffer.
*/
public CachedBuffer add(String value, int ordinal)
{
CachedBuffer buffer= new CachedBuffer(value, ordinal);
_stringMap.put(value, buffer);
if (ordinal>=0)
{
while ((ordinal - _index.size()) >= 0)
_index.add(null);
_index.set(ordinal,buffer);
}
return buffer;
}
public CachedBuffer get(int ordinal)
{
if (ordinal < 0 || ordinal >= _index.size())
return null;
return (CachedBuffer)_index.get(ordinal);
}
public ByteBuffer getBuffer(ByteBuffer buffer)
{
CachedBuffer cached=get(buffer);
if (cached!=null)
return cached.getBuffer();
return buffer;
}
public String getString(ByteBuffer buffer)
{
CachedBuffer cached=get(buffer);
if (cached!=null)
return cached.toString();
return BufferUtil.toString(buffer);
}
public CachedBuffer get(ByteBuffer buffer)
{
byte[] array=buffer.isReadOnly()?null:buffer.array();
Map.Entry<String,Object> entry=_stringMap.getBestEntry(buffer);
if (entry!=null)
return (CachedBuffer)entry.getValue();
return null;
}
public CachedBuffer get(String value)
{
return (CachedBuffer)_stringMap.get(value);
}
@Deprecated
public ByteBuffer lookup(ByteBuffer buffer)
{
CachedBuffer cached=get(buffer);
if (cached!=null)
return cached.getBuffer();
return buffer;
}
public CachedBuffer getBest(byte[] value, int offset, int maxLength)
{
Entry entry = _stringMap.getBestEntry(value, offset, maxLength);
if (entry!=null)
return (CachedBuffer)entry.getValue();
return null;
}
public ByteBuffer lookup(String value)
{
CachedBuffer b= get(value);
if (b == null)
return ByteBuffer.wrap(value.getBytes(StringUtil.__ISO_8859_1_CHARSET));
return b.getBuffer();
}
public String toString(ByteBuffer buffer)
{
CachedBuffer cached = get(buffer);
if (cached!=null)
return cached.toString();
byte[] array=buffer.array();
if (array!=null)
return new String(array,buffer.position(),buffer.remaining(),StringUtil.__ISO_8859_1_CHARSET);
array=new byte[buffer.remaining()];
buffer.asReadOnlyBuffer().get(array);
return new String(array,0,buffer.remaining(),StringUtil.__ISO_8859_1_CHARSET);
}
public int getOrdinal(String value)
{
CachedBuffer buffer = (CachedBuffer)_stringMap.get(value);
return buffer==null?-1:buffer.getOrdinal();
}
public int getOrdinal(ByteBuffer buffer)
{
CachedBuffer cached = get(buffer);
if (cached!=null)
return cached.getOrdinal();
return -1;
}
public static class CachedBuffer
{
private final int _ordinal;
private final String _string;
private final ByteBuffer _buffer;
private HashMap _associateMap=null;
public CachedBuffer(String value, int ordinal)
{
_string=value;
_buffer=ByteBuffer.wrap(value.getBytes(StringUtil.__ISO_8859_1_CHARSET)).asReadOnlyBuffer();
_ordinal= ordinal;
}
public int getOrdinal()
{
return _ordinal;
}
public ByteBuffer getBuffer()
{
return _buffer;
}
public String toString()
{
return _string;
}
public CachedBuffer getAssociate(Object key)
{
if (_associateMap==null)
return null;
return (CachedBuffer)_associateMap.get(key);
}
// TODO Replace Associate with a mime encoding specific solution
public void setAssociate(Object key, CachedBuffer associate)
{
if (_associateMap==null)
_associateMap=new HashMap();
_associateMap.put(key,associate);
}
}
@Override
public String toString()
{
return "CACHE["+
",stringMap="+_stringMap+
",index="+_index+
"]";
}
}

View File

@ -17,6 +17,7 @@ import java.nio.ByteBuffer;
import java.text.DateFormatSymbols; import java.text.DateFormatSymbols;
import java.util.Locale; import java.util.Locale;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.DateCache; import org.eclipse.jetty.util.DateCache;
public class BufferDateCache extends DateCache public class BufferDateCache extends DateCache

View File

@ -16,6 +16,8 @@ package org.eclipse.jetty.io;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -18,9 +18,9 @@ import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.ByteArrayEndPoint; import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
/** /**

View File

@ -23,8 +23,8 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.SelectableChannel; import java.nio.channels.SelectableChannel;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;

View File

@ -24,9 +24,9 @@ import javax.net.ssl.SSLSession;
import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.AsyncEndPoint; import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Timeout.Task; import org.eclipse.jetty.util.thread.Timeout.Task;

View File

@ -19,6 +19,7 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import org.eclipse.jetty.io.BufferCache.CachedBuffer; import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.Test; import org.junit.Test;
public abstract class EndPointTest<T extends EndPoint> public abstract class EndPointTest<T extends EndPoint>

View File

@ -23,9 +23,9 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.AsyncEndPoint; import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.ConnectedEndPoint; import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.QueuedThreadPool;

View File

@ -11,12 +11,11 @@
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.io; package org.eclipse.jetty.util;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/** /**
@ -72,13 +71,13 @@ public class BufferUtil
public static byte[] toArray(ByteBuffer buffer) public static byte[] toArray(ByteBuffer buffer)
{ {
byte[] to = new byte[buffer.remaining()]; byte[] to = new byte[buffer.remaining()];
if (buffer.isDirect()) if (buffer.hasArray())
buffer.slice().get(to);
else
{ {
byte[] array = buffer.array(); byte[] array = buffer.array();
System.arraycopy(array,buffer.position(),to,0,to.length); System.arraycopy(array,buffer.arrayOffset()+buffer.position(),to,0,to.length);
} }
else
buffer.slice().get(to);
return to; return to;
} }
@ -117,18 +116,18 @@ public class BufferUtil
to.put(from); to.put(from);
put=remaining; put=remaining;
} }
else if (to.isDirect()) else if (from.hasArray())
{ {
put=to.remaining(); put=to.remaining();
ByteBuffer slice=from.slice(); to.put(from.array(),from.arrayOffset()+from.position(),put);
slice.limit(put);
to.put(slice);
from.position(from.position()+put); from.position(from.position()+put);
} }
else else
{ {
put=to.remaining(); put=to.remaining();
to.put(from.array(),from.arrayOffset()+from.position(),put); ByteBuffer slice=from.slice();
slice.limit(put);
to.put(slice);
from.position(from.position()+put); from.position(from.position()+put);
} }
} }
@ -151,25 +150,46 @@ public class BufferUtil
return toString(buffer,StringUtil.__ISO_8859_1_CHARSET); return toString(buffer,StringUtil.__ISO_8859_1_CHARSET);
} }
/* ------------------------------------------------------------ */
public static String toUTF8String(ByteBuffer buffer) public static String toUTF8String(ByteBuffer buffer)
{ {
return toString(buffer,StringUtil.__UTF8_CHARSET); return toString(buffer,StringUtil.__UTF8_CHARSET);
} }
/* ------------------------------------------------------------ */
public static String toString(ByteBuffer buffer, Charset charset) public static String toString(ByteBuffer buffer, Charset charset)
{ {
if (buffer == null) if (buffer == null)
return null; return null;
byte[] array = buffer.isReadOnly()?null:buffer.array(); byte[] array = buffer.hasArray()?buffer.array():null;
if (array == null) if (array == null)
{ {
byte[] to = new byte[buffer.remaining()]; byte[] to = new byte[buffer.remaining()];
buffer.slice().get(to); buffer.slice().get(to);
return new String(to,0,to.length,charset); return new String(to,0,to.length,charset);
} }
return new String(array,buffer.position(),buffer.remaining(),charset); return new String(array,buffer.arrayOffset()+buffer.position(),buffer.remaining(),charset);
} }
/* ------------------------------------------------------------ */
public static String toString(ByteBuffer buffer, int position, int length, Charset charset)
{
if (buffer == null)
return null;
byte[] array = buffer.hasArray()?buffer.array():null;
if (array == null)
{
ByteBuffer slice=buffer.slice();
slice.position(position);
slice.limit(position+length);
byte[] to = new byte[length];
slice.get(to);
return new String(to,0,to.length,charset);
}
return new String(array,buffer.arrayOffset()+position,length,charset);
}
/* ------------------------------------------------------------ */
/** /**
* Convert buffer to an integer. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown * Convert buffer to an integer. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown
* *

View File

@ -243,6 +243,15 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
return entry.getValue(); return entry.getValue();
} }
/* ------------------------------------------------------------ */
public O get(ByteBuffer buffer, int position, int length)
{
Map.Entry<String,O> entry = getEntry(buffer,position,length);
if (entry==null)
return null;
return entry.getValue();
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get a map entry by substring key. /** Get a map entry by substring key.
* @param key String containing the key * @param key String containing the key
@ -360,11 +369,11 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
* A simple 8859-1 byte to char mapping is assumed. * A simple 8859-1 byte to char mapping is assumed.
* @param key byte array containing the key * @param key byte array containing the key
* @param offset Offset of the key within the array. * @param offset Offset of the key within the array.
* @param maxLength The length of the key * @param length The length of the key
* @return The Map.Entry for the key or null if the key is not in * @return The Map.Entry for the key or null if the key is not in
* the map. * the map.
*/ */
public Map.Entry<String,O> getBestEntry(byte[] key,int offset, int maxLength) public Map.Entry<String,O> getEntry(byte[] key,int offset, int length)
{ {
if (key==null) if (key==null)
return _nullEntry; return _nullEntry;
@ -374,7 +383,7 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
// look for best match // look for best match
charLoop: charLoop:
for (int i=0;i<maxLength;i++) for (int i=0;i<length;i++)
{ {
char c=(char)key[offset+i]; char c=(char)key[offset+i];
@ -382,12 +391,7 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
if (ni==-1) if (ni==-1)
{ {
ni=0; ni=0;
node=(node._children==null)?null:node._children[c%_width];
Node<O> child = (node._children==null)?null:node._children[c%_width];
if (child==null && i>0)
return node; // This is the best match
node=child;
} }
// While we have a node to try // While we have a node to try
@ -424,24 +428,31 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
* @return The Map.Entry for the key or null if the key is not in * @return The Map.Entry for the key or null if the key is not in
* the map. * the map.
*/ */
public Map.Entry<String,O> getBestEntry(ByteBuffer key) public Map.Entry<String,O> getEntry(ByteBuffer key)
{
return getEntry(key,key.position(),key.remaining());
}
/* ------------------------------------------------------------ */
/** Get a map entry by ByteBuffer key, using as much of the passed key as needed for a match.
* A simple 8859-1 byte to char mapping is assumed.
* @param key ByteBuffer containing the key
* @return The Map.Entry for the key or null if the key is not in
* the map.
*/
public Map.Entry<String,O> getEntry(ByteBuffer key,int position,int length)
{ {
if (key==null) if (key==null)
return _nullEntry; return _nullEntry;
if (!key.isReadOnly() && !key.isDirect()) if (!key.isReadOnly() && !key.isDirect())
return getBestEntry(key.array(),key.position(),key.remaining()); return getEntry(key.array(),key.position(),key.remaining());
Node<O> node = _root; Node<O> node = _root;
int ni=-1; int ni=-1;
// look for best match
int position=key.position();
int remaining=key.remaining();
charLoop: charLoop:
for (int i=0;i<remaining;i++) for (int i=0;i<length;i++)
{ {
char c=(char)key.get(position+i); char c=(char)key.get(position+i);
@ -449,12 +460,7 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
if (ni==-1) if (ni==-1)
{ {
ni=0; ni=0;
node=(node._children==null)?null:node._children[c%_width];
Node<O> child = (node._children==null)?null:node._children[c%_width];
if (child==null && i>0)
return node; // This is the best match
node=child;
} }
// While we have a node to try // While we have a node to try

View File

@ -14,7 +14,10 @@
package org.eclipse.jetty.util; package org.eclipse.jetty.util;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Map;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -33,6 +36,9 @@ public class StringUtil
{ {
private static final Logger LOG = Log.getLogger(StringUtil.class); private static final Logger LOG = Log.getLogger(StringUtil.class);
private final static StringMap<String> CHARSETS= new StringMap<String>(true);
public static final String ALL_INTERFACES="0.0.0.0"; public static final String ALL_INTERFACES="0.0.0.0";
public static final String CRLF="\015\012"; public static final String CRLF="\015\012";
public static final String __LINE_SEPARATOR= public static final String __LINE_SEPARATOR=
@ -40,7 +46,6 @@ public class StringUtil
public static final String __ISO_8859_1="ISO-8859-1"; public static final String __ISO_8859_1="ISO-8859-1";
public final static String __UTF8="UTF-8"; public final static String __UTF8="UTF-8";
public final static String __UTF8Alt="UTF8";
public final static String __UTF16="UTF-16"; public final static String __UTF16="UTF-16";
public final static Charset __UTF8_CHARSET; public final static Charset __UTF8_CHARSET;
@ -50,8 +55,52 @@ public class StringUtil
{ {
__UTF8_CHARSET=Charset.forName(__UTF8); __UTF8_CHARSET=Charset.forName(__UTF8);
__ISO_8859_1_CHARSET=Charset.forName(__ISO_8859_1); __ISO_8859_1_CHARSET=Charset.forName(__ISO_8859_1);
CHARSETS.put("UTF-8",__UTF8);
CHARSETS.put("UTF8",__UTF8);
CHARSETS.put("UTF-16",__UTF16);
CHARSETS.put("UTF16",__UTF16);
CHARSETS.put("ISO-8859-1",__ISO_8859_1);
CHARSETS.put("ISO_8859_1",__ISO_8859_1);
} }
/* ------------------------------------------------------------ */
/** Convert alternate charset names (eg utf8) to normalized
* name (eg UTF-8).
*/
public static String normalizeCharset(String s)
{
String n=CHARSETS.get(s);
return (n==null)?s:n;
}
/* ------------------------------------------------------------ */
/** Convert alternate charset names (eg utf8) to normalized
* name (eg UTF-8).
*/
public static String normalizeCharset(String s,int offset,int length)
{
Map.Entry<String,String> n=CHARSETS.getEntry(s,offset,length);
return (n==null)?s.substring(offset,offset+length):n.getValue();
}
/* ------------------------------------------------------------ */
/** Convert alternate charset names (eg utf8) to normalized
* name (eg UTF-8).
*/
public static String normalizeCharset(ByteBuffer b,int position,int length)
{
Map.Entry<String,String> n=CHARSETS.getEntry(b,position,length);
if (n!=null)
return n.getValue();
ByteBuffer slice = b.slice();
slice.position(position);
slice.limit(position+length);
return BufferUtil.toString(slice);
}
private static char[] lowercases = { private static char[] lowercases = {
'\000','\001','\002','\003','\004','\005','\006','\007', '\000','\001','\002','\003','\004','\005','\006','\007',
'\010','\011','\012','\013','\014','\015','\016','\017', '\010','\011','\012','\013','\014','\015','\016','\017',
@ -330,7 +379,7 @@ public class StringUtil
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static boolean isUTF8(String charset) public static boolean isUTF8(String charset)
{ {
return __UTF8.equalsIgnoreCase(charset)||__UTF8Alt.equalsIgnoreCase(charset); return __UTF8.equalsIgnoreCase(charset)||__UTF8.equalsIgnoreCase(normalizeCharset(charset));
} }
@ -497,4 +546,83 @@ public class StringUtil
return sidBytes; return sidBytes;
} }
/**
* Convert String to an integer. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown
*
* @param string
* A String containing an integer.
* @return an int
*/
public static int toInt(String string)
{
int val = 0;
boolean started = false;
boolean minus = false;
for (int i = 0; i < string.length(); i++)
{
char b = string.charAt(i);
if (b <= ' ')
{
if (started)
break;
}
else if (b >= '0' && b <= '9')
{
val = val * 10 + (b - '0');
started = true;
}
else if (b == '-' && !started)
{
minus = true;
}
else
break;
}
if (started)
return minus?(-val):val;
throw new NumberFormatException(string);
}
/**
* Convert String to an long. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown
*
* @param string
* A String containing an integer.
* @return an int
*/
public static long toLong(String string)
{
long val = 0;
boolean started = false;
boolean minus = false;
for (int i = 0; i < string.length(); i++)
{
char b = string.charAt(i);
if (b <= ' ')
{
if (started)
break;
}
else if (b >= '0' && b <= '9')
{
val = val * 10L + (b - '0');
started = true;
}
else if (b == '-' && !started)
{
minus = true;
}
else
break;
}
if (started)
return minus?(-val):val;
throw new NumberFormatException(string);
}
} }

View File

@ -11,13 +11,14 @@
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.io; package org.eclipse.jetty.util;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.Test; import org.junit.Test;
/** /**

View File

@ -149,11 +149,6 @@ public class StringMapTest
assertEquals("abc",entry.getKey()); assertEquals("abc",entry.getKey());
assertEquals("2",entry.getValue()); assertEquals("2",entry.getValue());
entry=m5.getBestEntry("xabcyz".getBytes(),1,5);
assertTrue(entry!=null);
assertEquals("abc",entry.getKey());
assertEquals("2",entry.getValue());
entry=m5.getEntry("xaBcyz",1,3); entry=m5.getEntry("xaBcyz",1,3);
assertTrue(entry==null); assertTrue(entry==null);