Merge remote-tracking branch 'origin/jetty-9.3.x' into jetty-9.4.x
This commit is contained in:
commit
3ea2d1cf95
|
@ -116,7 +116,7 @@ public class HpackContext
|
||||||
private static final Trie<StaticEntry> __staticNameMap = new ArrayTernaryTrie<>(true,512);
|
private static final Trie<StaticEntry> __staticNameMap = new ArrayTernaryTrie<>(true,512);
|
||||||
private static final StaticEntry[] __staticTableByHeader = new StaticEntry[HttpHeader.UNKNOWN.ordinal()];
|
private static final StaticEntry[] __staticTableByHeader = new StaticEntry[HttpHeader.UNKNOWN.ordinal()];
|
||||||
private static final StaticEntry[] __staticTable=new StaticEntry[STATIC_TABLE.length];
|
private static final StaticEntry[] __staticTable=new StaticEntry[STATIC_TABLE.length];
|
||||||
private static final int STATIC_SIZE = STATIC_TABLE.length-1;
|
public static final int STATIC_SIZE = STATIC_TABLE.length-1;
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
Set<String> added = new HashSet<>();
|
Set<String> added = new HashSet<>();
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class HpackEncoder
|
||||||
private int _remoteMaxDynamicTableSize;
|
private int _remoteMaxDynamicTableSize;
|
||||||
private int _localMaxDynamicTableSize;
|
private int _localMaxDynamicTableSize;
|
||||||
private int _maxHeaderListSize;
|
private int _maxHeaderListSize;
|
||||||
private int _size;
|
private int _headerListSize;
|
||||||
|
|
||||||
public HpackEncoder()
|
public HpackEncoder()
|
||||||
{
|
{
|
||||||
|
@ -144,7 +144,7 @@ public class HpackEncoder
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug(String.format("CtxTbl[%x] encoding",_context.hashCode()));
|
LOG.debug(String.format("CtxTbl[%x] encoding",_context.hashCode()));
|
||||||
|
|
||||||
_size=0;
|
_headerListSize=0;
|
||||||
int pos = buffer.position();
|
int pos = buffer.position();
|
||||||
|
|
||||||
// Check the dynamic table sizes!
|
// Check the dynamic table sizes!
|
||||||
|
@ -179,9 +179,9 @@ public class HpackEncoder
|
||||||
encode(buffer,field);
|
encode(buffer,field);
|
||||||
|
|
||||||
// Check size
|
// Check size
|
||||||
if (_maxHeaderListSize>0 && _size>_maxHeaderListSize)
|
if (_maxHeaderListSize>0 && _headerListSize>_maxHeaderListSize)
|
||||||
{
|
{
|
||||||
LOG.warn("Header list size too large {} > {} for {}",_size,_maxHeaderListSize);
|
LOG.warn("Header list size too large {} > {} for {}",_headerListSize,_maxHeaderListSize);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("metadata={}",metadata);
|
LOG.debug("metadata={}",metadata);
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ public class HpackEncoder
|
||||||
field = new HttpField(field.getHeader(),field.getName(),"");
|
field = new HttpField(field.getHeader(),field.getName(),"");
|
||||||
|
|
||||||
int field_size = field.getName().length() + field.getValue().length();
|
int field_size = field.getName().length() + field.getValue().length();
|
||||||
_size+=field_size+32;
|
_headerListSize+=field_size+32;
|
||||||
|
|
||||||
final int p=_debug?buffer.position():-1;
|
final int p=_debug?buffer.position():-1;
|
||||||
|
|
||||||
|
@ -307,9 +307,9 @@ public class HpackEncoder
|
||||||
(huffman?"HuffV":"LitV")+
|
(huffman?"HuffV":"LitV")+
|
||||||
(indexed?"Idx":(never_index?"!!Idx":"!Idx"));
|
(indexed?"Idx":(never_index?"!!Idx":"!Idx"));
|
||||||
}
|
}
|
||||||
else if (header==HttpHeader.CONTENT_LENGTH && field.getValue().length()>1)
|
else if (field_size>=_context.getMaxDynamicTableSize() || header==HttpHeader.CONTENT_LENGTH && field.getValue().length()>2)
|
||||||
{
|
{
|
||||||
// Non indexed content length for 2 digits or more
|
// Non indexed if field too large or a content length for 3 digits or more
|
||||||
indexed=false;
|
indexed=false;
|
||||||
encodeName(buffer,(byte)0x00,4,header.asString(),name);
|
encodeName(buffer,(byte)0x00,4,header.asString(),name);
|
||||||
encodeValue(buffer,true,field.getValue());
|
encodeValue(buffer,true,field.getValue());
|
||||||
|
@ -332,7 +332,8 @@ public class HpackEncoder
|
||||||
// If we want the field referenced, then we add it to our
|
// If we want the field referenced, then we add it to our
|
||||||
// table and reference set.
|
// table and reference set.
|
||||||
if (indexed)
|
if (indexed)
|
||||||
_context.add(field);
|
if (_context.add(field)==null)
|
||||||
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_debug)
|
if (_debug)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.eclipse.jetty.http2.hpack;
|
package org.eclipse.jetty.http2.hpack;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -29,6 +30,7 @@ import org.eclipse.jetty.http.HttpFields;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
import org.eclipse.jetty.http.MetaData;
|
import org.eclipse.jetty.http.MetaData;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -185,6 +187,69 @@ public class HpackEncoderTest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldLargerThanTable()
|
||||||
|
{
|
||||||
|
HttpFields fields = new HttpFields();
|
||||||
|
|
||||||
|
HpackEncoder encoder = new HpackEncoder(128);
|
||||||
|
ByteBuffer buffer0 = BufferUtil.allocate(4096);
|
||||||
|
int pos = BufferUtil.flipToFill(buffer0);
|
||||||
|
encoder.encode(buffer0,new MetaData(HttpVersion.HTTP_2,fields));
|
||||||
|
BufferUtil.flipToFlush(buffer0,pos);
|
||||||
|
|
||||||
|
encoder = new HpackEncoder(128);
|
||||||
|
fields.add(new HttpField("user-agent","jetty/test"));
|
||||||
|
ByteBuffer buffer1 = BufferUtil.allocate(4096);
|
||||||
|
pos = BufferUtil.flipToFill(buffer1);
|
||||||
|
encoder.encode(buffer1,new MetaData(HttpVersion.HTTP_2,fields));
|
||||||
|
BufferUtil.flipToFlush(buffer1,pos);
|
||||||
|
|
||||||
|
encoder = new HpackEncoder(128);
|
||||||
|
fields.add(new HttpField(":path",
|
||||||
|
"This is a very large field, whose size is larger than the dynamic table so it should not be indexed as it will not fit in the table ever!"+
|
||||||
|
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX "+
|
||||||
|
"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY "+
|
||||||
|
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ "));
|
||||||
|
ByteBuffer buffer2 = BufferUtil.allocate(4096);
|
||||||
|
pos = BufferUtil.flipToFill(buffer2);
|
||||||
|
encoder.encode(buffer2,new MetaData(HttpVersion.HTTP_2,fields));
|
||||||
|
BufferUtil.flipToFlush(buffer2,pos);
|
||||||
|
|
||||||
|
encoder = new HpackEncoder(128);
|
||||||
|
fields.add(new HttpField("host","somehost"));
|
||||||
|
ByteBuffer buffer = BufferUtil.allocate(4096);
|
||||||
|
pos = BufferUtil.flipToFill(buffer);
|
||||||
|
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields));
|
||||||
|
BufferUtil.flipToFlush(buffer,pos);
|
||||||
|
|
||||||
|
//System.err.println(BufferUtil.toHexString(buffer0));
|
||||||
|
//System.err.println(BufferUtil.toHexString(buffer1));
|
||||||
|
//System.err.println(BufferUtil.toHexString(buffer2));
|
||||||
|
//System.err.println(BufferUtil.toHexString(buffer));
|
||||||
|
|
||||||
|
// something was encoded!
|
||||||
|
assertThat(buffer.remaining(),Matchers.greaterThan(0));
|
||||||
|
|
||||||
|
// check first field is static index name and dynamic index body
|
||||||
|
assertThat((buffer.get(buffer0.remaining())&0xFF)>>6,equalTo(1));
|
||||||
|
|
||||||
|
// check first field is static index name and literal body
|
||||||
|
assertThat((buffer.get(buffer1.remaining())&0xFF)>>4,equalTo(0));
|
||||||
|
|
||||||
|
// check first field is static index name and dynamic index body
|
||||||
|
assertThat((buffer.get(buffer2.remaining())&0xFF)>>6,equalTo(1));
|
||||||
|
|
||||||
|
// Only first and third fields are put in the table
|
||||||
|
HpackContext context = encoder.getHpackContext();
|
||||||
|
assertThat(context.size(),equalTo(2));
|
||||||
|
assertThat(context.get(HpackContext.STATIC_SIZE+1).getHttpField().getName(),equalTo("host"));
|
||||||
|
assertThat(context.get(HpackContext.STATIC_SIZE+2).getHttpField().getName(),equalTo("user-agent"));
|
||||||
|
assertThat(context.getDynamicTableSize(),equalTo(
|
||||||
|
context.get(HpackContext.STATIC_SIZE+1).getSize()+context.get(HpackContext.STATIC_SIZE+2).getSize()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1126,12 +1126,10 @@ public class BufferUtil
|
||||||
buf.append("\\x").append(TypeUtil.toHexString(b));
|
buf.append("\\x").append(TypeUtil.toHexString(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Convert buffer to a Hex Summary String.
|
/** Convert buffer to a Hex Summary String.
|
||||||
* @param buffer the buffer to generate a hex byte summary from
|
* @param buffer the buffer to generate a hex byte summary from
|
||||||
* @return A string showing the escaped content of the buffer around the
|
* @return A string showing a summary of the content in hex
|
||||||
* position and limit (marked with <<< and >>>)
|
|
||||||
*/
|
*/
|
||||||
public static String toHexSummary(ByteBuffer buffer)
|
public static String toHexSummary(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
|
@ -1152,6 +1150,18 @@ public class BufferUtil
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/** Convert buffer to a Hex String.
|
||||||
|
* @param buffer the buffer to generate a hex byte summary from
|
||||||
|
* @return A hex string
|
||||||
|
*/
|
||||||
|
public static String toHexString(ByteBuffer buffer)
|
||||||
|
{
|
||||||
|
if (buffer == null)
|
||||||
|
return "null";
|
||||||
|
return TypeUtil.toHexString(toArray(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private final static int[] decDivisors =
|
private final static int[] decDivisors =
|
||||||
{1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
|
{1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
|
||||||
|
|
Loading…
Reference in New Issue