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 org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EndPoint;
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.Logger;

View File

@ -44,14 +44,14 @@ public class EncodedHttpURI extends HttpURI
_raw[_scheme+1]=='t' &&
_raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' )
return HttpSchemes.HTTP;
return HttpSchemes.HTTP.toString();
if (l==6 &&
_raw[_scheme]=='h' &&
_raw[_scheme+1]=='t' &&
_raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' &&
_raw[_scheme+4]=='s' )
return HttpSchemes.HTTPS;
return HttpSchemes.HTTPS.toString();
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 _maxBuffers=1024;
private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _requestBufferType=Buffers.Type.INDIRECT;
private Buffers.Type _requestHeaderType=Buffers.Type.INDIRECT;
private Buffers.Type _responseBufferType=Buffers.Type.INDIRECT;
private Buffers.Type _responseHeaderType=Buffers.Type.INDIRECT;
private Buffers _requestBuffers;
private Buffers _responseBuffers;

View File

@ -15,6 +15,7 @@ package org.eclipse.jetty.http;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@ -34,16 +35,13 @@ import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
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.BufferUtil;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringMap;
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.Logger;
@ -289,12 +287,12 @@ public class HttpFields
/* -------------------------------------------------------------- */
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();
private final static byte[] __colon_space = new byte[] {':',' '};
/* -------------------------------------------------------------- */
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;
/* ------------------------------------------------------------ */
@ -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.
@ -355,11 +321,10 @@ public class HttpFields
public Collection<String> getFieldNamesCollection()
{
final List<String> list = new ArrayList<String>(_fields.size());
for (Field f : _fields)
{
if (f!=null)
list.add(BufferUtil.to8859_1_String(f._name));
list.add(f._name);
}
return list;
}
@ -404,27 +369,27 @@ 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));
}
/* ------------------------------------------------------------ */
public boolean containsKey(Buffer name)
{
return _names.containsKey(HttpHeaders.CACHE.lookup(name));
return _names.get(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());
}
/* -------------------------------------------------------------- */
@ -439,30 +404,6 @@ public class HttpFields
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
@ -608,49 +514,11 @@ public class HttpFields
* @param value the value of the field. If null the field is cleared.
*/
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);
if (value == null)
return;
if (!(name instanceof BufferCache.CachedBuffer))
name = HttpHeaders.CACHE.lookup(name);
if (!(value instanceof CachedBuffer))
value= HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer();
// new value;
Field field = new Field(name, value);
_fields.add(field);
@ -664,31 +532,12 @@ public class HttpFields
* @param name the name of the field
* @param list the List value of the field. If null the field is cleared.
*/
public void put(String name, List<?> list)
{
if (list == null || list.size() == 0)
public void put(String name, List<String> list)
{
remove(name);
return;
}
Buffer n = HttpHeaders.CACHE.lookup(name);
Object v = list.get(0);
for (String v : list)
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()));
}
}
add(name,v);
}
/* -------------------------------------------------------------- */
@ -702,36 +551,9 @@ public class HttpFields
* value.
*/
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 (!(name instanceof CachedBuffer))
name = HttpHeaders.CACHE.lookup(name);
name=name.asImmutableBuffer();
if (!(value instanceof CachedBuffer) && HttpHeaderValues.hasKnownValues(HttpHeaders.CACHE.getOrdinal(name)))
value= HttpHeaderValues.CACHE.lookup(value);
value=value.asImmutableBuffer();
Field field = _names.get(name);
Field last = null;
while (field != null)
@ -751,6 +573,7 @@ public class HttpFields
_names.put(name, field);
}
/* ------------------------------------------------------------ */
/**
* Remove a field.
@ -759,19 +582,6 @@ public class HttpFields
*/
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);
while (field != null)
{
@ -794,20 +604,6 @@ public class HttpFields
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
@ -821,7 +617,7 @@ public class HttpFields
if (field == null)
return -1;
String val = valueParameters(BufferUtil.to8859_1_String(field._value), null);
String val = valueParameters(field._value, null);
if (val == null)
return -1;
@ -831,18 +627,6 @@ public class HttpFields
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)
{
Buffer n = HttpHeaders.CACHE.lookup(name);
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);
String v = Long.toString(value);
put(name, v);
}
/* -------------------------------------------------------------- */
/**
* Sets the value of a date field.
@ -908,8 +651,8 @@ public class HttpFields
*/
public void putDateField(String name, long date)
{
Buffer n = HttpHeaders.CACHE.lookup(name);
putDateField(n,date);
String d=formatDate(date);
put(name, d);
}
/* -------------------------------------------------------------- */
@ -922,9 +665,7 @@ public class HttpFields
public void addDateField(String name, long date)
{
String d=formatDate(date);
Buffer n = HttpHeaders.CACHE.lookup(name);
Buffer v = new ByteArrayBuffer(d);
add(n, v);
add(name,d);
}
/* ------------------------------------------------------------ */
@ -1053,7 +794,7 @@ public class HttpFields
{
_fields.remove(field);
if (last==null)
_names.put(HttpHeaders.SET_COOKIE_BUFFER,field._next);
_names.put(HttpHeaders.SET_COOKIE.toString(),field._next);
else
last._next=field._next;
break;
@ -1062,14 +803,14 @@ public class HttpFields
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.
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++)
{
@ -1130,11 +871,11 @@ public class HttpFields
{
if (fields == null) return;
Enumeration e = fields.getFieldNames();
Enumeration<String> e = fields.getFieldNames();
while (e.hasMoreElements())
{
String name = (String) e.nextElement();
Enumeration values = fields.getValues(name);
Enumeration<String> values = fields.getValues(name);
while (values.hasMoreElements())
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 __zero = new Float("0.0");
private static final StringMap __qualities = new StringMap();
private static final StringMap<Float> __qualities = new StringMap<>();
static
{
__qualities.put(null, __one);
@ -1215,11 +956,12 @@ public class HttpFields
if (value.charAt(qe++) == 'q')
{
qe++;
Map.Entry entry = __qualities.getEntry(value, qe, value.length() - qe);
if (entry != null) return (Float) entry.getValue();
Map.Entry<String,Float> entry = __qualities.getEntry(value, qe, value.length() - qe);
if (entry != null)
return (Float) entry.getValue();
}
HashMap params = new HashMap(3);
Map<String,String> params = new HashMap<String,String>(4);
valueParameters(value, params);
String qs = (String) params.get("q");
Float q = (Float) __qualities.get(qs);
@ -1244,9 +986,10 @@ public class HttpFields
* @param e Enumeration of values with quality parameters
* @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 qual = null;
@ -1296,65 +1039,57 @@ public class HttpFields
/* ------------------------------------------------------------ */
public static final class Field
{
private Buffer _name;
private Buffer _value;
private final String _name;
private final String _value;
private Field _next;
/* ------------------------------------------------------------ */
private Field(Buffer name, Buffer value)
private Field(String name, String value)
{
_name = name;
_value = value;
_next = null;
}
/* ------------------------------------------------------------ */
public void putTo(Buffer buffer) throws IOException
private byte[] toSanitisedBytes(String s)
{
int o=(_name instanceof CachedBuffer)?((CachedBuffer)_name).getOrdinal():-1;
if (o>=0)
buffer.put(_name);
else
byte[] bytes = s.getBytes(StringUtil.__ISO_8859_1_CHARSET);
for (int i=bytes.length;i-->0;)
{
int s=_name.getIndex();
int e=_name.putIndex();
while (s<e)
{
byte b=_name.peek(s++);
switch(b)
switch(bytes[i])
{
case '\r':
case '\n':
case ':' :
continue;
default:
buffer.put(b);
bytes[i]=(byte)'?';
}
}
return bytes;
}
buffer.put((byte) ':');
buffer.put((byte) ' ');
/* ------------------------------------------------------------ */
public void putTo(ByteBuffer buffer) throws IOException
{
HttpHeaders header = HttpHeaders.CACHE.get(_name);
if (header!=null)
{
buffer.put(header.toBuffer());
buffer.put(__colon_space);
o=(_value instanceof CachedBuffer)?((CachedBuffer)_value).getOrdinal():-1;
if (o>=0)
buffer.put(_value);
if (HttpHeaderValues.hasKnownValues(header))
{
HttpHeaderValues value=HttpHeaderValues.CACHE.get(_value);
if (value!=null)
buffer.put(value.toBuffer());
else
buffer.put(toSanitisedBytes(_value));
}
}
else
{
int s=_value.getIndex();
int e=_value.putIndex();
while (s<e)
{
byte b=_value.peek(s++);
switch(b)
{
case '\r':
case '\n':
continue;
default:
buffer.put(b);
}
}
buffer.put(toSanitisedBytes(_name));
buffer.put(__colon_space);
buffer.put(toSanitisedBytes(_value));
}
BufferUtil.putCRLF(buffer);
@ -1362,52 +1097,29 @@ public class HttpFields
/* ------------------------------------------------------------ */
public String getName()
{
return BufferUtil.to8859_1_String(_name);
}
/* ------------------------------------------------------------ */
Buffer getNameBuffer()
{
return _name;
}
/* ------------------------------------------------------------ */
public int getNameOrdinal()
{
return HttpHeaders.CACHE.getOrdinal(_name);
}
/* ------------------------------------------------------------ */
public String getValue()
{
return BufferUtil.to8859_1_String(_value);
}
/* ------------------------------------------------------------ */
public Buffer getValueBuffer()
{
return _value;
}
/* ------------------------------------------------------------ */
public int getValueOrdinal()
{
return HttpHeaderValues.CACHE.getOrdinal(_value);
}
/* ------------------------------------------------------------ */
public int getIntValue()
{
return (int) getLongValue();
return StringUtil.toInt(_value);
}
/* ------------------------------------------------------------ */
public long getLongValue()
{
return BufferUtil.toLong(_value);
return StringUtil.toLong(_value);
}
/* ------------------------------------------------------------ */
public String toString()
{

View File

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

View File

@ -13,71 +13,73 @@
package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
import org.eclipse.jetty.io.ByteArrayBuffer;
import java.nio.ByteBuffer;
import java.util.EnumMap;
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",
CHUNKED="chunked",
GZIP="gzip",
IDENTITY="identity",
KEEP_ALIVE="keep-alive",
CONTINUE="100-continue",
PROCESSING="102-processing",
TE="TE",
BYTES="bytes",
NO_CACHE="no-cache",
UPGRADE="Upgrade";
CLOSE("close"),
CHUNKED("chunked"),
GZIP("gzip"),
IDENTITY("identity"),
KEEP_ALIVE("keep-alive"),
CONTINUE("100-continue"),
PROCESSING("102-processing"),
TE("TE"),
BYTES("bytes"),
NO_CACHE("no-cache"),
UPGRADE("Upgrade");
public final static int
CLOSE_ORDINAL=1,
CHUNKED_ORDINAL=2,
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)
/* ------------------------------------------------------------ */
public final static StringMap<HttpHeaderValues> CACHE= new StringMap<HttpHeaderValues>(true);
static
{
switch(httpHeaderOrdinal)
{
case HttpHeaders.CONNECTION_ORDINAL:
case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
case HttpHeaders.CONTENT_ENCODING_ORDINAL:
return true;
for (HttpHeaderValues value : HttpHeaderValues.values())
CACHE.put(value.toString(),value);
}
private final String _string;
private final ByteBuffer _buffer;
/* ------------------------------------------------------------ */
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;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
import java.nio.ByteBuffer;
/* ------------------------------------------------------------------------------- */
/**
*/
public class HttpHeaders extends BufferCache
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
public enum HttpHeaders
{
/* ------------------------------------------------------------ */
/** General Fields.
*/
public final static String
CONNECTION= "Connection",
CACHE_CONTROL= "Cache-Control",
DATE= "Date",
PRAGMA= "Pragma",
PROXY_CONNECTION = "Proxy-Connection",
TRAILER= "Trailer",
TRANSFER_ENCODING= "Transfer-Encoding",
UPGRADE= "Upgrade",
VIA= "Via",
WARNING= "Warning",
NEGOTIATE= "Negotiate";
CONNECTION("Connection"),
CACHE_CONTROL("Cache-Control"),
DATE("Date"),
PRAGMA("Pragma"),
PROXY_CONNECTION ("Proxy-Connection"),
TRAILER("Trailer"),
TRANSFER_ENCODING("Transfer-Encoding"),
UPGRADE("Upgrade"),
VIA("Via"),
WARNING("Warning"),
NEGOTIATE("Negotiate"),
/* ------------------------------------------------------------ */
/** Entity Fields.
*/
public final static String ALLOW= "Allow",
CONTENT_ENCODING= "Content-Encoding",
CONTENT_LANGUAGE= "Content-Language",
CONTENT_LENGTH= "Content-Length",
CONTENT_LOCATION= "Content-Location",
CONTENT_MD5= "Content-MD5",
CONTENT_RANGE= "Content-Range",
CONTENT_TYPE= "Content-Type",
EXPIRES= "Expires",
LAST_MODIFIED= "Last-Modified";
ALLOW("Allow"),
CONTENT_ENCODING("Content-Encoding"),
CONTENT_LANGUAGE("Content-Language"),
CONTENT_LENGTH("Content-Length"),
CONTENT_LOCATION("Content-Location"),
CONTENT_MD5("Content-MD5"),
CONTENT_RANGE("Content-Range"),
CONTENT_TYPE("Content-Type"),
EXPIRES("Expires"),
LAST_MODIFIED("Last-Modified"),
/* ------------------------------------------------------------ */
/** Request Fields.
*/
public final static String ACCEPT= "Accept",
ACCEPT_CHARSET= "Accept-Charset",
ACCEPT_ENCODING= "Accept-Encoding",
ACCEPT_LANGUAGE= "Accept-Language",
AUTHORIZATION= "Authorization",
EXPECT= "Expect",
FORWARDED= "Forwarded",
FROM= "From",
HOST= "Host",
IF_MATCH= "If-Match",
IF_MODIFIED_SINCE= "If-Modified-Since",
IF_NONE_MATCH= "If-None-Match",
IF_RANGE= "If-Range",
IF_UNMODIFIED_SINCE= "If-Unmodified-Since",
KEEP_ALIVE= "Keep-Alive",
MAX_FORWARDS= "Max-Forwards",
PROXY_AUTHORIZATION= "Proxy-Authorization",
RANGE= "Range",
REQUEST_RANGE= "Request-Range",
REFERER= "Referer",
TE= "TE",
USER_AGENT= "User-Agent",
X_FORWARDED_FOR= "X-Forwarded-For",
X_FORWARDED_PROTO= "X-Forwarded-Proto",
X_FORWARDED_SERVER= "X-Forwarded-Server",
X_FORWARDED_HOST= "X-Forwarded-Host";
ACCEPT("Accept"),
ACCEPT_CHARSET("Accept-Charset"),
ACCEPT_ENCODING("Accept-Encoding"),
ACCEPT_LANGUAGE("Accept-Language"),
AUTHORIZATION("Authorization"),
EXPECT("Expect"),
FORWARDED("Forwarded"),
FROM("From"),
HOST("Host"),
IF_MATCH("If-Match"),
IF_MODIFIED_SINCE("If-Modified-Since"),
IF_NONE_MATCH("If-None-Match"),
IF_RANGE("If-Range"),
IF_UNMODIFIED_SINCE("If-Unmodified-Since"),
KEEP_ALIVE("Keep-Alive"),
MAX_FORWARDS("Max-Forwards"),
PROXY_AUTHORIZATION("Proxy-Authorization"),
RANGE("Range"),
REQUEST_RANGE("Request-Range"),
REFERER("Referer"),
TE("TE"),
USER_AGENT("User-Agent"),
X_FORWARDED_FOR("X-Forwarded-For"),
X_FORWARDED_PROTO("X-Forwarded-Proto"),
X_FORWARDED_SERVER("X-Forwarded-Server"),
X_FORWARDED_HOST("X-Forwarded-Host"),
/* ------------------------------------------------------------ */
/** Response Fields.
*/
public final static String ACCEPT_RANGES= "Accept-Ranges",
AGE= "Age",
ETAG= "ETag",
LOCATION= "Location",
PROXY_AUTHENTICATE= "Proxy-Authenticate",
RETRY_AFTER= "Retry-After",
SERVER= "Server",
SERVLET_ENGINE= "Servlet-Engine",
VARY= "Vary",
WWW_AUTHENTICATE= "WWW-Authenticate";
ACCEPT_RANGES("Accept-Ranges"),
AGE("Age"),
ETAG("ETag"),
LOCATION("Location"),
PROXY_AUTHENTICATE("Proxy-Authenticate"),
RETRY_AFTER("Retry-After"),
SERVER("Server"),
SERVLET_ENGINE("Servlet-Engine"),
VARY("Vary"),
WWW_AUTHENTICATE("WWW-Authenticate"),
/* ------------------------------------------------------------ */
/** Other Fields.
*/
public final static String COOKIE= "Cookie",
SET_COOKIE= "Set-Cookie",
SET_COOKIE2= "Set-Cookie2",
MIME_VERSION= "MIME-Version",
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 Buffer
HOST_BUFFER=CACHE.add(HOST,HOST_ORDINAL),
ACCEPT_BUFFER=CACHE.add(ACCEPT,ACCEPT_ORDINAL),
ACCEPT_CHARSET_BUFFER=CACHE.add(ACCEPT_CHARSET,ACCEPT_CHARSET_ORDINAL),
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);
COOKIE("Cookie"),
SET_COOKIE("Set-Cookie"),
SET_COOKIE2("Set-Cookie2"),
MIME_VERSION("MIME-Version"),
IDENTITY("identity");
/* ------------------------------------------------------------ */
public final static StringMap<HttpHeaders> CACHE= new StringMap<HttpHeaders>(true);
static
{
for (HttpHeaders header : HttpHeaders.values())
CACHE.put(header.toString(),header);
}
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;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
/* ------------------------------------------------------------------------------- */
/**
*
*
*/
public class HttpMethods
public enum HttpMethods
{
public final static String GET= "GET",
POST= "POST",
HEAD= "HEAD",
PUT= "PUT",
OPTIONS= "OPTIONS",
DELETE= "DELETE",
TRACE= "TRACE",
CONNECT= "CONNECT",
MOVE= "MOVE";
public final static int GET_ORDINAL= 1,
POST_ORDINAL= 2,
HEAD_ORDINAL= 3,
PUT_ORDINAL= 4,
OPTIONS_ORDINAL= 5,
DELETE_ORDINAL= 6,
TRACE_ORDINAL= 7,
CONNECT_ORDINAL= 8,
MOVE_ORDINAL= 9;
public final static BufferCache CACHE= new BufferCache();
public final static Buffer
GET_BUFFER= CACHE.add(GET, GET_ORDINAL),
POST_BUFFER= CACHE.add(POST, POST_ORDINAL),
HEAD_BUFFER= CACHE.add(HEAD, HEAD_ORDINAL),
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);
GET,
POST,
HEAD,
PUT,
OPTIONS,
DELETE,
TRACE,
CONNECT,
MOVE;
/* ------------------------------------------------------------ */
public final static StringMap<HttpMethods> CACHE= new StringMap<HttpMethods>(true);
static
{
for (HttpMethods method : HttpMethods.values())
CACHE.put(method.toString(),method);
}
/* ------------------------------------------------------------ */
private final ByteBuffer _buffer;
/* ------------------------------------------------------------ */
HttpMethods()
{
_buffer=BufferUtil.toBuffer(toString());
}
/* ------------------------------------------------------------ */
public ByteBuffer toBuffer()
{
return _buffer.asReadOnlyBuffer();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -13,21 +13,48 @@
package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
/* ------------------------------------------------------------------------------- */
/**
*
*
*/
public class HttpSchemes
public enum HttpSchemes
{
public final static String
HTTP ="http",
HTTPS="https";
HTTP("http"),
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+2]=='t' &&
_raw[_scheme+3]=='p' )
return HttpSchemes.HTTP;
return HttpSchemes.HTTP.toString();
if (l==6 &&
_raw[_scheme]=='h' &&
_raw[_scheme+1]=='t' &&
_raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' &&
_raw[_scheme+4]=='s' )
return HttpSchemes.HTTPS;
return HttpSchemes.HTTPS.toString();
return toUtf8String(_scheme,_authority-_scheme-1);
}

View File

@ -13,30 +13,54 @@
package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
/* ------------------------------------------------------------------------------- */
/**
*
*
*/
public class HttpVersions
public enum HttpVersions
{
public final static String
HTTP_0_9 = "",
HTTP_1_0 = "HTTP/1.0",
HTTP_1_1 = "HTTP/1.1";
HTTP_0_9("HTTP/0.9",9),
HTTP_1_0("HTTP/1.0",10),
HTTP_1_1("HTTP/1.1",11);
public final static int
HTTP_0_9_ORDINAL=9,
HTTP_1_0_ORDINAL=10,
HTTP_1_1_ORDINAL=11;
public final static BufferCache CACHE = new BufferCache();
public final static Buffer
HTTP_0_9_BUFFER=CACHE.add(HTTP_0_9,HTTP_0_9_ORDINAL),
HTTP_1_0_BUFFER=CACHE.add(HTTP_1_0,HTTP_1_0_ORDINAL),
HTTP_1_1_BUFFER=CACHE.add(HTTP_1_1,HTTP_1_1_ORDINAL);
/* ------------------------------------------------------------ */
public final static StringMap<HttpVersions> CACHE= new StringMap<HttpVersions>(true);
static
{
for (HttpVersions version : HttpVersions.values())
CACHE.put(version.toString(),version);
}
private final String _string;
private final ByteBuffer _buffer;
private final int _version;
/* ------------------------------------------------------------ */
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;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringMap;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -34,94 +33,73 @@ import org.eclipse.jetty.util.log.Logger;
*/
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 final static StringMap<MimeTypes.Type> CACHE= new StringMap<MimeTypes.Type>(true);
private final static StringMap<ByteBuffer> TYPES= new StringMap<ByteBuffer>(true);
private final static Map<String,ByteBuffer> __dftMimeMap = new HashMap<String,ByteBuffer>();
private final static Map<String,String> __encodings = new HashMap<String,String>();
public final static String
FORM_ENCODED="application/x-www-form-urlencoded",
MESSAGE_HTTP="message/http",
MULTIPART_BYTERANGES="multipart/byteranges",
TEXT_HTML="text/html",
TEXT_PLAIN="text/plain",
TEXT_XML="text/xml",
TEXT_JSON="text/json",
TEXT_HTML_8859_1="text/html;charset=ISO-8859-1",
TEXT_PLAIN_8859_1="text/plain;charset=ISO-8859-1",
TEXT_XML_8859_1="text/xml;charset=ISO-8859-1",
TEXT_HTML_UTF_8="text/html;charset=UTF-8",
TEXT_PLAIN_UTF_8="text/plain;charset=UTF-8",
TEXT_XML_UTF_8="text/xml;charset=UTF-8",
TEXT_JSON_UTF_8="text/json;charset=UTF-8";
private final static String
TEXT_HTML__8859_1="text/html; charset=ISO-8859-1",
TEXT_PLAIN__8859_1="text/plain; charset=ISO-8859-1",
TEXT_XML__8859_1="text/xml; charset=ISO-8859-1",
TEXT_HTML__UTF_8="text/html; charset=UTF-8",
TEXT_PLAIN__UTF_8="text/plain; charset=UTF-8",
TEXT_XML__UTF_8="text/xml; charset=UTF-8",
TEXT_JSON__UTF_8="text/json; charset=UTF-8";
private final static 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
{
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
{
ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime");
@ -142,11 +120,11 @@ public class MimeTypes
try
{
ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding");
Enumeration i = encoding.getKeys();
Enumeration<String> i = encoding.getKeys();
while(i.hasMoreElements())
{
Buffer type = normalizeMimeType((String)i.nextElement());
__encodings.put(type,encoding.getString(type.toString()));
String type = i.nextElement();
__encodings.put(type,encoding.getString(type));
}
}
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.
@ -196,7 +148,7 @@ public class MimeTypes
}
/* ------------------------------------------------------------ */
public synchronized Map getMimeMap()
public synchronized Map<String,ByteBuffer> getMimeMap()
{
return _mimeMap;
}
@ -205,22 +157,14 @@ public class MimeTypes
/**
* @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;
return;
for (String ext : mimeMap.keySet())
_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
* file name.
*/
public Buffer getMimeByExtension(String filename)
public ByteBuffer getMimeByExtension(String filename)
{
Buffer type=null;
ByteBuffer type=null;
if (filename!=null)
{
@ -245,18 +189,18 @@ public class MimeTypes
String ext=StringUtil.asciiToLowerCase(filename.substring(i+1));
if (_mimeMap!=null)
type = (Buffer)_mimeMap.get(ext);
type=_mimeMap.get(ext);
if (type==null)
type=(Buffer)__dftMimeMap.get(ext);
type=__dftMimeMap.get(ext);
}
}
if (type==null)
{
if (_mimeMap!=null)
type=(Buffer)_mimeMap.get("*");
type=_mimeMap.get("*");
if (type==null)
type=(Buffer)__dftMimeMap.get("*");
type=__dftMimeMap.get("*");
}
return type;
@ -269,49 +213,30 @@ public class MimeTypes
*/
public void addMimeMapping(String extension,String type)
{
if (_mimeMap==null)
_mimeMap=new HashMap();
_mimeMap.put(StringUtil.asciiToLowerCase(extension),normalizeMimeType(type));
}
/* ------------------------------------------------------------ */
private static synchronized Buffer normalizeMimeType(String type)
private static ByteBuffer normalizeMimeType(String type)
{
Buffer b =CACHE.get(type);
if (b==null)
b=CACHE.add(type,__index++);
return b;
MimeTypes.Type t =CACHE.get(type);
if (t!=null)
return t.toBuffer();
return BufferUtil.toBuffer(StringUtil.asciiToLowerCase(type));
}
/* ------------------------------------------------------------ */
public static String getCharsetFromContentType(Buffer value)
public static String getCharsetFromContentType(ByteBuffer value)
{
if (value instanceof CachedBuffer)
{
switch(((CachedBuffer)value).getOrdinal())
{
case TEXT_HTML_8859_1_ORDINAL:
case TEXT_PLAIN_8859_1_ORDINAL:
case TEXT_XML_8859_1_ORDINAL:
return StringUtil.__ISO_8859_1;
case TEXT_HTML_UTF_8_ORDINAL:
case TEXT_PLAIN_UTF_8_ORDINAL:
case TEXT_XML_UTF_8_ORDINAL:
case TEXT_JSON_UTF_8_ORDINAL:
return StringUtil.__UTF8;
}
}
int i=value.getIndex();
int end=value.putIndex();
int i=value.position();
int end=value.limit();
int state=0;
int start=0;
boolean quote=false;
for (;i<end;i++)
{
byte b = value.peek(i);
byte b = value.get(i);
if (quote && state!=10)
{
@ -359,12 +284,12 @@ public class MimeTypes
case 10:
if (!quote && (';'==b || ' '==b )||
(quote && '"'==b ))
return CACHE.lookup(value.peek(start,i-start)).toString();
return StringUtil.normalizeCharset(value,start,i-start);
}
}
if (state==10)
return CACHE.lookup(value.peek(start,i-start)).toString();
return StringUtil.normalizeCharset(value,start,i-start);
return (String)__encodings.get(value);
}

View File

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

View File

@ -18,15 +18,16 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.View;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.Assert;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
/**
*
@ -46,7 +47,7 @@ public class HttpFieldsTest
assertNull(header.getStringField("name2"));
int matches=0;
Enumeration e = header.getFieldNames();
Enumeration<String> e = header.getFieldNames();
while (e.hasMoreElements())
{
Object o=e.nextElement();
@ -69,7 +70,7 @@ public class HttpFieldsTest
HttpFields header = new HttpFields();
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"));
@ -86,11 +87,14 @@ public class HttpFieldsTest
header.put("name\r\n1", "value1");
header.put("name:2", "value:\r\n2");
ByteArrayBuffer buffer = new ByteArrayBuffer(1024);
ByteBuffer buffer = BufferUtil.allocate(1024);
buffer.clear();
header.putTo(buffer);
assertTrue(buffer.toString().contains("name0: value0"));
assertTrue(buffer.toString().contains("name1: value1"));
assertTrue(buffer.toString().contains("name2: value:2"));
buffer.flip();
String out = BufferUtil.toString(buffer);
assertTrue(out.contains("name0: value??0"));
assertTrue(out.contains("name??1: value1"));
assertTrue(out.contains("name?2: value???2"));
}
@Test
@ -98,20 +102,22 @@ public class HttpFieldsTest
{
HttpFields header = new HttpFields();
header.put("Connection", "keep-alive");
assertEquals(HttpHeaderValues.KEEP_ALIVE, header.getStringField(HttpHeaders.CONNECTION));
header.put("Connection", "Keep-Alive");
header.put("tRansfer-EncOding", "CHUNKED");
header.put("CONTENT-ENCODING", "gZIP");
ByteBuffer buffer = BufferUtil.allocate(1024);
buffer.clear();
header.putTo(buffer);
buffer.flip();
String out = BufferUtil.toString(buffer);
Assert.assertThat(out,JUnitMatchers.containsString(HttpHeaders.CONNECTION+": "+HttpHeaderValues.KEEP_ALIVE));
Assert.assertThat(out,JUnitMatchers.containsString(HttpHeaders.TRANSFER_ENCODING+": "+HttpHeaderValues.CHUNKED));
Assert.assertThat(out,JUnitMatchers.containsString(HttpHeaders.CONTENT_ENCODING+": "+HttpHeaderValues.GZIP));
int matches=0;
Enumeration e = header.getFieldNames();
while (e.hasMoreElements())
{
Object o=e.nextElement();
if (o==HttpHeaders.CONTENT_TYPE)
matches++;
if (o==HttpHeaders.CONNECTION)
matches++;
}
assertEquals(1, matches);
}
@Test
@ -175,7 +181,7 @@ public class HttpFieldsTest
assertNull(header.getStringField("name3"));
int matches=0;
Enumeration e = header.getFieldNames();
Enumeration<String> e = header.getFieldNames();
while (e.hasMoreElements())
{
Object o=e.nextElement();
@ -213,7 +219,7 @@ public class HttpFieldsTest
assertNull(fields.getStringField("name3"));
int matches=0;
Enumeration e = fields.getFieldNames();
Enumeration<String> e = fields.getFieldNames();
while (e.hasMoreElements())
{
Object o=e.nextElement();
@ -234,122 +240,7 @@ public class HttpFieldsTest
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
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 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.bio.StringEndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.junit.Test;
@ -33,14 +33,11 @@ public class HttpParserTest
@Test
public void testLineParse0() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput("POST /foo HTTP/1.0\015\012" + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteBuffer buffer= BufferUtil.toBuffer("POST /foo HTTP/1.0\015\012" + "\015\012");
Handler handler = new Handler();
HttpParser parser= new HttpParser(buffers,io, handler);
parser.parse();
HttpParser parser= new HttpParser((HttpParser.RequestHandler)handler);
parser.parse(buffer);
assertEquals("POST", f0);
assertEquals("/foo", f1);
assertEquals("HTTP/1.0", f2);
@ -52,7 +49,7 @@ public class HttpParserTest
{
StringEndPoint io=new StringEndPoint();
io.setInput("GET /999\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
f2= null;
@ -70,7 +67,7 @@ public class HttpParserTest
{
StringEndPoint io=new StringEndPoint();
io.setInput("POST /222 \015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
f2= null;
@ -88,7 +85,7 @@ public class HttpParserTest
{
StringEndPoint io=new StringEndPoint();
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);
Handler handler = new Handler();
@ -105,7 +102,7 @@ public class HttpParserTest
{
StringEndPoint io=new StringEndPoint();
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);
Handler handler = new Handler();
@ -122,7 +119,7 @@ public class HttpParserTest
{
StringEndPoint io=new StringEndPoint();
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);
Handler handler = new Handler();
@ -150,7 +147,7 @@ public class HttpParserTest
+ " value4\015\012"
+ "Server5: notServer\015\012"
+ "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler();
@ -188,8 +185,8 @@ public class HttpParserTest
+ "1a\015\012"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012"
+ "0\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteArrayBuffer content=new ByteArrayBuffer(8192);
ByteBuffer buffer= BufferUtil.allocate(4096);
ByteBuffer content=BufferUtil.allocate(8192);
SimpleBuffers buffers=new SimpleBuffers(buffer,content);
Handler handler = new Handler();
@ -231,8 +228,8 @@ public class HttpParserTest
+ "\015\012"
+ "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteArrayBuffer content=new ByteArrayBuffer(8192);
ByteBuffer buffer= BufferUtil.allocate(4096);
ByteBuffer content=BufferUtil.allocate(8192);
SimpleBuffers buffers=new SimpleBuffers(buffer,content);
Handler handler = new Handler();
@ -314,8 +311,8 @@ public class HttpParserTest
{
f0=f1=f2=null;
h=0;
ByteArrayBuffer buffer= new ByteArrayBuffer(tests[t]);
ByteArrayBuffer content=new ByteArrayBuffer(8192);
ByteBuffer buffer= BufferUtil.allocate(tests[t]);
ByteBuffer content=BufferUtil.allocate(8192);
SimpleBuffers buffers=new SimpleBuffers(buffer,content);
Handler handler = new Handler();
@ -370,7 +367,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012"
+ "\015\012"
+ "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler();
@ -392,7 +389,7 @@ public class HttpParserTest
"HTTP/1.1 304 Not-Modified\015\012"
+ "Connection: close\015\012"
+ "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler();
@ -418,7 +415,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012"
+ "\015\012"
+ "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler();
@ -450,7 +447,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012"
+ "\015\012"
+ "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler();
@ -474,7 +471,7 @@ public class HttpParserTest
+ "Content-Type: text/plain\015\012"
+ "\015\012"
+ "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler();
@ -496,7 +493,7 @@ public class HttpParserTest
"HTTP/1.1 304 found\015\012"
+ "Content-Length: 10\015\012"
+ "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
ByteBuffer buffer= BufferUtil.allocate(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
Handler handler = new Handler();
@ -523,7 +520,7 @@ public class HttpParserTest
+ "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);
Handler handler = new Handler();
@ -551,48 +548,37 @@ public class HttpParserTest
private boolean headerCompleted;
private boolean messageCompleted;
private class Handler extends HttpParser.EventHandler
private class Handler implements HttpParser.RequestHandler, HttpParser.ResponseHandler
{
private HttpFields fields;
private boolean request;
public void content(Buffer ref)
public void content(ByteBuffer ref)
{
if (_content==null)
_content="";
_content= _content + ref;
}
public void startRequest(Buffer tok0, Buffer tok1, Buffer tok2)
{
try
public void startRequest(String tok0, String tok1, String tok2)
{
request=true;
h= -1;
hdr= new String[9];
val= new String[9];
f0= tok0.toString();
f1=new String(tok1.array(),tok1.getIndex(),tok1.length(),StringUtil.__UTF8);
if (tok2!=null)
f2= tok2.toString();
else
f2=null;
f0= tok0;
f1= tok1;
f2= tok2;
fields=new HttpFields();
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
messageCompleted = 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);
val[h]= value.toString(StringUtil.__ISO_8859_1);
hdr[++h]= name;
val[h]= value;
}
public void headerComplete()
@ -615,7 +601,7 @@ public class HttpParserTest
messageCompleted = true;
}
public void startResponse(Buffer version, int status, Buffer reason)
public void startResponse(String version, int status, String reason)
{
request=false;
f0 = version.toString();
@ -629,5 +615,10 @@ public class HttpParserTest
messageCompleted = false;
headerCompleted = false;
}
@Override
public void earlyEOF()
{
}
}
}

View File

@ -28,6 +28,6 @@ public class HttpStatusCodeTest
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;
import org.eclipse.jetty.io.Buffer;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.Assert;
import org.junit.Test;
@ -42,9 +44,9 @@ public class MimeTypesTest
private void assertMimeTypeByExtension(String expectedMimeType, String filename)
{
MimeTypes mimetypes = new MimeTypes();
Buffer contentType = mimetypes.getMimeByExtension(filename);
ByteBuffer contentType = mimetypes.getMimeByExtension(filename);
String prefix = "MimeTypes.getMimeByExtension(" + filename + ")";
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 org.eclipse.jetty.util.BufferUtil;
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.util.Locale;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.DateCache;
public class BufferDateCache extends DateCache

View File

@ -16,6 +16,8 @@ package org.eclipse.jetty.io;
import java.io.IOException;
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.charset.Charset;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
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.SocketChannel;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
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.AsyncEndPoint;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.Connection;
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.Logger;
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 org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.junit.Before;
import org.junit.Test;

View File

@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.Test;
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.AsyncEndPoint;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
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.
// ========================================================================
package org.eclipse.jetty.io;
package org.eclipse.jetty.util;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------------------------- */
/**
@ -72,13 +71,13 @@ public class BufferUtil
public static byte[] toArray(ByteBuffer buffer)
{
byte[] to = new byte[buffer.remaining()];
if (buffer.isDirect())
buffer.slice().get(to);
else
if (buffer.hasArray())
{
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;
}
@ -117,18 +116,18 @@ public class BufferUtil
to.put(from);
put=remaining;
}
else if (to.isDirect())
else if (from.hasArray())
{
put=to.remaining();
ByteBuffer slice=from.slice();
slice.limit(put);
to.put(slice);
to.put(from.array(),from.arrayOffset()+from.position(),put);
from.position(from.position()+put);
}
else
{
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);
}
}
@ -151,25 +150,46 @@ public class BufferUtil
return toString(buffer,StringUtil.__ISO_8859_1_CHARSET);
}
/* ------------------------------------------------------------ */
public static String toUTF8String(ByteBuffer buffer)
{
return toString(buffer,StringUtil.__UTF8_CHARSET);
}
/* ------------------------------------------------------------ */
public static String toString(ByteBuffer buffer, Charset charset)
{
if (buffer == null)
return null;
byte[] array = buffer.isReadOnly()?null:buffer.array();
byte[] array = buffer.hasArray()?buffer.array():null;
if (array == null)
{
byte[] to = new byte[buffer.remaining()];
buffer.slice().get(to);
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
*

View File

@ -243,6 +243,15 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
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.
* @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.
* @param key byte array containing the key
* @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
* 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)
return _nullEntry;
@ -374,7 +383,7 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
// look for best match
charLoop:
for (int i=0;i<maxLength;i++)
for (int i=0;i<length;i++)
{
char c=(char)key[offset+i];
@ -382,12 +391,7 @@ public class StringMap<O> extends AbstractMap<String,O> implements Externalizabl
if (ni==-1)
{
ni=0;
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;
node=(node._children==null)?null:node._children[c%_width];
}
// 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
* 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)
return _nullEntry;
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;
int ni=-1;
// look for best match
int position=key.position();
int remaining=key.remaining();
charLoop:
for (int i=0;i<remaining;i++)
for (int i=0;i<length;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)
{
ni=0;
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;
node=(node._children==null)?null:node._children[c%_width];
}
// While we have a node to try

View File

@ -14,7 +14,10 @@
package org.eclipse.jetty.util;
import java.io.UnsupportedEncodingException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Map;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -33,6 +36,9 @@ public class StringUtil
{
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 CRLF="\015\012";
public static final String __LINE_SEPARATOR=
@ -40,7 +46,6 @@ public class StringUtil
public static final String __ISO_8859_1="ISO-8859-1";
public final static String __UTF8="UTF-8";
public final static String __UTF8Alt="UTF8";
public final static String __UTF16="UTF-16";
public final static Charset __UTF8_CHARSET;
@ -50,8 +55,52 @@ public class StringUtil
{
__UTF8_CHARSET=Charset.forName(__UTF8);
__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 = {
'\000','\001','\002','\003','\004','\005','\006','\007',
'\010','\011','\012','\013','\014','\015','\016','\017',
@ -330,7 +379,7 @@ public class StringUtil
/* ------------------------------------------------------------ */
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;
}
/**
* 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.
// ========================================================================
package org.eclipse.jetty.io;
package org.eclipse.jetty.util;
import static org.junit.Assert.assertEquals;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.Test;
/**

View File

@ -149,11 +149,6 @@ public class StringMapTest
assertEquals("abc",entry.getKey());
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);
assertTrue(entry==null);