convert MetaData to HttpField as a list
This commit is contained in:
parent
bbd61f8e19
commit
c319c19125
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
|
||||
|
||||
|
@ -68,14 +70,136 @@ public class HttpField
|
|||
}
|
||||
|
||||
public String[] getValues()
|
||||
{
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
int state = 0;
|
||||
int start=0;
|
||||
int end=0;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (int i=0;i<_value.length();i++)
|
||||
{
|
||||
char c = _value.charAt(i);
|
||||
switch(state)
|
||||
{
|
||||
case 0: // initial white space
|
||||
switch(c)
|
||||
{
|
||||
case '"': // open quote
|
||||
state=2;
|
||||
break;
|
||||
|
||||
case ',': // leading empty field
|
||||
list.add("");
|
||||
break;
|
||||
|
||||
case ' ': // more white space
|
||||
case '\t':
|
||||
break;
|
||||
|
||||
default: // character
|
||||
start=i;
|
||||
end=i;
|
||||
state=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // In token
|
||||
switch(c)
|
||||
{
|
||||
case ',': // next field
|
||||
list.add(_value.substring(start,end+1));
|
||||
state=0;
|
||||
break;
|
||||
|
||||
case ' ': // more white space
|
||||
case '\t':
|
||||
break;
|
||||
|
||||
default:
|
||||
end=i;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // In Quoted
|
||||
switch(c)
|
||||
{
|
||||
case '\\': // next field
|
||||
state=3;
|
||||
break;
|
||||
|
||||
case '"': // end quote
|
||||
list.add(builder.toString());
|
||||
builder.setLength(0);
|
||||
state=4;
|
||||
break;
|
||||
|
||||
default:
|
||||
builder.append(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // In Quoted Quoted
|
||||
builder.append(c);
|
||||
state=2;
|
||||
break;
|
||||
|
||||
case 4: // WS after end quote
|
||||
switch(c)
|
||||
{
|
||||
case ' ': // white space
|
||||
case '\t': // white space
|
||||
break;
|
||||
|
||||
case ',': // white space
|
||||
state=0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("c="+(int)c);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
list.add(_value.substring(start,end+1));
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("state="+state);
|
||||
}
|
||||
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Look for a value in a possible multi valued field
|
||||
* @param value
|
||||
* @return True iff the value is contained in the field value entirely or
|
||||
* as an element of a quoted comma separated list
|
||||
*/
|
||||
public boolean contains(String value)
|
||||
{
|
||||
QuotedStringTokenizer tok = new QuotedStringTokenizer(_value, ",", false, false);
|
||||
tok.setSingle(false);
|
||||
String[] v = new String[tok.countTokens()];
|
||||
int t=0;
|
||||
while(tok.hasMoreTokens())
|
||||
v[t++]=tok.nextToken();
|
||||
return v;
|
||||
if (_value==null)
|
||||
return value==null;
|
||||
|
||||
if (_value.equalsIgnoreCase(value))
|
||||
return true;
|
||||
|
||||
String[] values = getValues();
|
||||
for (String v:values)
|
||||
if (v.equalsIgnoreCase(value))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,13 +24,11 @@ import java.util.Collections;
|
|||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.util.ArrayTernaryTrie;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
|
@ -50,28 +48,34 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* <p>The cookie handling provided by this class is guided by the Servlet specification and RFC6265.
|
||||
*
|
||||
*/
|
||||
public class HttpFields implements Iterable<HttpField>
|
||||
public class HttpFields extends ArrayList<HttpField>
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(HttpFields.class);
|
||||
private final static Pattern __splitter = Pattern.compile("\\s*,\\s*");
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = Log.getLogger(HttpFields.class);
|
||||
public final static String __separators = ", \t";
|
||||
|
||||
private final ArrayList<HttpField> _fields = new ArrayList<>(20);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public HttpFields()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public HttpFields(int capacity)
|
||||
{
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Collection of header names.
|
||||
*/
|
||||
public Collection<String> getFieldNamesCollection()
|
||||
{
|
||||
final Set<String> list = new HashSet<>(_fields.size());
|
||||
for (HttpField f : _fields)
|
||||
final Set<String> list = new HashSet<>(size());
|
||||
for (HttpField f : this)
|
||||
{
|
||||
if (f!=null)
|
||||
list.add(f.getName());
|
||||
|
@ -88,11 +92,6 @@ public class HttpFields implements Iterable<HttpField>
|
|||
return Collections.enumeration(getFieldNamesCollection());
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return _fields.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Field by index.
|
||||
* @return A Field value or null if the Field value has not been set
|
||||
|
@ -100,20 +99,14 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public HttpField getField(int i)
|
||||
{
|
||||
return _fields.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<HttpField> iterator()
|
||||
{
|
||||
return _fields.iterator();
|
||||
return get(i);
|
||||
}
|
||||
|
||||
public HttpField getField(HttpHeader header)
|
||||
{
|
||||
for (int i=0;i<_fields.size();i++)
|
||||
for (int i=0;i<size();i++)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
HttpField f=get(i);
|
||||
if (f.getHeader()==header)
|
||||
return f;
|
||||
}
|
||||
|
@ -122,9 +115,9 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public HttpField getField(String name)
|
||||
{
|
||||
for (int i=0;i<_fields.size();i++)
|
||||
for (int i=0;i<size();i++)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
HttpField f=get(i);
|
||||
if (f.getName().equalsIgnoreCase(name))
|
||||
return f;
|
||||
}
|
||||
|
@ -133,10 +126,10 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public boolean contains(HttpHeader header, String value)
|
||||
{
|
||||
for (int i=0;i<_fields.size();i++)
|
||||
for (int i=0;i<size();i++)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
if (f.getHeader()==header && contains(f,value))
|
||||
HttpField f=get(i);
|
||||
if (f.getHeader()==header && f.contains(value))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -144,39 +137,21 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public boolean contains(String name, String value)
|
||||
{
|
||||
for (int i=0;i<_fields.size();i++)
|
||||
for (int i=0;i<size();i++)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
if (f.getName().equalsIgnoreCase(name) && contains(f,value))
|
||||
HttpField f=get(i);
|
||||
if (f.getName().equalsIgnoreCase(name) && f.contains(value))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean contains(HttpField field,String value)
|
||||
{
|
||||
String v = field.getValue();
|
||||
if (v==null)
|
||||
return false;
|
||||
|
||||
if (value.equalsIgnoreCase(v))
|
||||
return true;
|
||||
|
||||
String[] split = __splitter.split(v);
|
||||
for (int i = 0; split!=null && i < split.length; i++)
|
||||
{
|
||||
if (value.equals(split[i]))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsKey(String name)
|
||||
{
|
||||
for (int i=0;i<_fields.size();i++)
|
||||
for (int i=0;i<size();i++)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
HttpField f=get(i);
|
||||
if (f.getName().equalsIgnoreCase(name))
|
||||
return true;
|
||||
}
|
||||
|
@ -218,7 +193,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
public List<String> getValuesList(String name)
|
||||
{
|
||||
final List<String> list = new ArrayList<>();
|
||||
for (HttpField f : _fields)
|
||||
for (HttpField f : this)
|
||||
if (f.getName().equalsIgnoreCase(name))
|
||||
list.add(f.getValue());
|
||||
return list;
|
||||
|
@ -232,9 +207,9 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public Enumeration<String> getValues(final String name)
|
||||
{
|
||||
for (int i=0;i<_fields.size();i++)
|
||||
for (int i=0;i<size();i++)
|
||||
{
|
||||
final HttpField f = _fields.get(i);
|
||||
final HttpField f = get(i);
|
||||
|
||||
if (f.getName().equalsIgnoreCase(name) && f.getValue()!=null)
|
||||
{
|
||||
|
@ -249,9 +224,9 @@ public class HttpFields implements Iterable<HttpField>
|
|||
{
|
||||
if (field==null)
|
||||
{
|
||||
while (i<_fields.size())
|
||||
while (i<size())
|
||||
{
|
||||
field=_fields.get(i++);
|
||||
field=get(i++);
|
||||
if (field.getName().equalsIgnoreCase(name) && field.getValue()!=null)
|
||||
return true;
|
||||
}
|
||||
|
@ -330,22 +305,22 @@ public class HttpFields implements Iterable<HttpField>
|
|||
public void put(HttpField field)
|
||||
{
|
||||
boolean put=false;
|
||||
for (int i=_fields.size();i-->0;)
|
||||
for (int i=size();i-->0;)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
HttpField f=get(i);
|
||||
if (f.isSameName(field))
|
||||
{
|
||||
if (put)
|
||||
_fields.remove(i);
|
||||
remove(i);
|
||||
else
|
||||
{
|
||||
_fields.set(i,field);
|
||||
set(i,field);
|
||||
put=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!put)
|
||||
_fields.add(field);
|
||||
add(field);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -410,7 +385,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
return;
|
||||
|
||||
HttpField field = new HttpField(name, value);
|
||||
_fields.add(field);
|
||||
add(field);
|
||||
}
|
||||
|
||||
public void add(HttpHeader header, HttpHeaderValue value) throws IllegalArgumentException
|
||||
|
@ -431,7 +406,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
if (value == null) throw new IllegalArgumentException("null value");
|
||||
|
||||
HttpField field = new HttpField(header, value);
|
||||
_fields.add(field);
|
||||
add(field);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,11 +416,11 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public HttpField remove(HttpHeader name)
|
||||
{
|
||||
for (int i=_fields.size();i-->0;)
|
||||
for (int i=size();i-->0;)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
HttpField f=get(i);
|
||||
if (f.getHeader()==name)
|
||||
return _fields.remove(i);
|
||||
return remove(i);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -457,11 +432,11 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public HttpField remove(String name)
|
||||
{
|
||||
for (int i=_fields.size();i-->0;)
|
||||
for (int i=size();i-->0;)
|
||||
{
|
||||
HttpField f=_fields.get(i);
|
||||
HttpField f=get(i);
|
||||
if (f.getName().equalsIgnoreCase(name))
|
||||
return _fields.remove(i);
|
||||
return remove(i);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -570,7 +545,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
try
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
for (HttpField field : _fields)
|
||||
for (HttpField field : this)
|
||||
{
|
||||
if (field != null)
|
||||
{
|
||||
|
@ -591,21 +566,6 @@ public class HttpFields implements Iterable<HttpField>
|
|||
return e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the header.
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
_fields.clear();
|
||||
}
|
||||
|
||||
public void add(HttpField field)
|
||||
{
|
||||
_fields.add(field);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add fields from another HttpFields instance. Single valued fields are replaced, while all
|
||||
|
|
|
@ -436,4 +436,32 @@ public class HttpFieldsTest
|
|||
assertEquals(""+i,i>=4,header.contains(""+i,"def"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValues()
|
||||
{
|
||||
String[] values = new HttpField("name","value").getValues();
|
||||
assertEquals(1,values.length);
|
||||
assertEquals("value",values[0]);
|
||||
|
||||
|
||||
values = new HttpField("name","a,b,c").getValues();
|
||||
assertEquals(3,values.length);
|
||||
assertEquals("a",values[0]);
|
||||
assertEquals("b",values[1]);
|
||||
assertEquals("c",values[2]);
|
||||
|
||||
values = new HttpField("name","a,\"x,y,z\",c").getValues();
|
||||
assertEquals(3,values.length);
|
||||
assertEquals("a",values[0]);
|
||||
assertEquals("x,y,z",values[1]);
|
||||
assertEquals("c",values[2]);
|
||||
|
||||
values = new HttpField("name","a,\"x,\\\"p,q\\\",z\",c").getValues();
|
||||
assertEquals(3,values.length);
|
||||
assertEquals("a",values[0]);
|
||||
assertEquals("x,\"p,q\",z",values[1]);
|
||||
assertEquals("c",values[2]);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,11 @@
|
|||
|
||||
package org.eclipse.jetty.http2.hpack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
|
||||
|
||||
|
@ -35,9 +32,9 @@ import org.eclipse.jetty.http.HttpScheme;
|
|||
*/
|
||||
public class MetaData implements Iterable<HttpField>
|
||||
{
|
||||
private final Iterable<HttpField> _fields;
|
||||
private final HttpFields _fields;
|
||||
|
||||
public MetaData(Iterable<HttpField> fields)
|
||||
public MetaData(HttpFields fields)
|
||||
{
|
||||
_fields=fields;
|
||||
}
|
||||
|
@ -58,14 +55,9 @@ public class MetaData implements Iterable<HttpField>
|
|||
return _fields.iterator();
|
||||
}
|
||||
|
||||
public List<HttpField> getFields()
|
||||
public HttpFields getFields()
|
||||
{
|
||||
if (_fields instanceof List)
|
||||
return (List<HttpField>)_fields;
|
||||
ArrayList<HttpField> list = new ArrayList<>();
|
||||
for (HttpField field:_fields)
|
||||
list.add(field);
|
||||
return list;
|
||||
return _fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -112,7 +104,7 @@ public class MetaData implements Iterable<HttpField>
|
|||
private final int _port;
|
||||
private final String _path;
|
||||
|
||||
public Request(HttpScheme scheme, String method, String authority, String host, int port, String path, Iterable<HttpField> fields)
|
||||
public Request(HttpScheme scheme, String method, String authority, String host, int port, String path, HttpFields fields)
|
||||
{
|
||||
super(fields);
|
||||
_authority=authority;
|
||||
|
@ -200,12 +192,6 @@ public class MetaData implements Iterable<HttpField>
|
|||
_status=status;
|
||||
}
|
||||
|
||||
public Response(int status, Iterable<HttpField> fields)
|
||||
{
|
||||
super(fields);
|
||||
_status=status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequest()
|
||||
{
|
||||
|
|
|
@ -19,12 +19,10 @@
|
|||
|
||||
package org.eclipse.jetty.http2.hpack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.http.HostPortHttpField;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
|
@ -40,7 +38,7 @@ public class MetaDataBuilder
|
|||
private int _port;
|
||||
private String _path;
|
||||
|
||||
List<HttpField> _fields = new ArrayList<>();
|
||||
HttpFields _fields = new HttpFields(10);
|
||||
|
||||
public void emit(HttpField field)
|
||||
{
|
||||
|
@ -104,11 +102,13 @@ public class MetaDataBuilder
|
|||
{
|
||||
try
|
||||
{
|
||||
HttpFields fields = _fields;
|
||||
_fields = new HttpFields(Math.max(10,fields.size()+5));
|
||||
if (_method!=null)
|
||||
return new MetaData.Request(_scheme,_method,_authority,_host,_port,_path,new ArrayList<>(_fields));
|
||||
return new MetaData.Request(_scheme,_method,_authority,_host,_port,_path,fields);
|
||||
if (_status!=0)
|
||||
return new MetaData.Response(_status,new ArrayList<>(_fields));
|
||||
return new MetaData(new ArrayList<>(_fields));
|
||||
return new MetaData.Response(_status,fields);
|
||||
return new MetaData(fields);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -119,7 +119,6 @@ public class MetaDataBuilder
|
|||
_path=null;
|
||||
_host=null;
|
||||
_port=0;
|
||||
_fields.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue