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 StaticEntry[] __staticTableByHeader = new StaticEntry[HttpHeader.UNKNOWN.ordinal()];
|
||||
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
|
||||
{
|
||||
Set<String> added = new HashSet<>();
|
||||
|
|
|
@ -88,7 +88,7 @@ public class HpackEncoder
|
|||
private int _remoteMaxDynamicTableSize;
|
||||
private int _localMaxDynamicTableSize;
|
||||
private int _maxHeaderListSize;
|
||||
private int _size;
|
||||
private int _headerListSize;
|
||||
|
||||
public HpackEncoder()
|
||||
{
|
||||
|
@ -144,7 +144,7 @@ public class HpackEncoder
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(String.format("CtxTbl[%x] encoding",_context.hashCode()));
|
||||
|
||||
_size=0;
|
||||
_headerListSize=0;
|
||||
int pos = buffer.position();
|
||||
|
||||
// Check the dynamic table sizes!
|
||||
|
@ -179,9 +179,9 @@ public class HpackEncoder
|
|||
encode(buffer,field);
|
||||
|
||||
// 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())
|
||||
LOG.debug("metadata={}",metadata);
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ public class HpackEncoder
|
|||
field = new HttpField(field.getHeader(),field.getName(),"");
|
||||
|
||||
int field_size = field.getName().length() + field.getValue().length();
|
||||
_size+=field_size+32;
|
||||
_headerListSize+=field_size+32;
|
||||
|
||||
final int p=_debug?buffer.position():-1;
|
||||
|
||||
|
@ -307,9 +307,9 @@ public class HpackEncoder
|
|||
(huffman?"HuffV":"LitV")+
|
||||
(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;
|
||||
encodeName(buffer,(byte)0x00,4,header.asString(),name);
|
||||
encodeValue(buffer,true,field.getValue());
|
||||
|
@ -332,7 +332,8 @@ public class HpackEncoder
|
|||
// If we want the field referenced, then we add it to our
|
||||
// table and reference set.
|
||||
if (indexed)
|
||||
_context.add(field);
|
||||
if (_context.add(field)==null)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
if (_debug)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.eclipse.jetty.http2.hpack;
|
||||
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
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.MetaData;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Convert buffer to a Hex Summary String.
|
||||
* @param buffer the buffer to generate a hex byte summary from
|
||||
* @return A string showing the escaped content of the buffer around the
|
||||
* position and limit (marked with <<< and >>>)
|
||||
* @return A string showing a summary of the content in hex
|
||||
*/
|
||||
public static String toHexSummary(ByteBuffer buffer)
|
||||
{
|
||||
|
@ -1152,6 +1150,18 @@ public class BufferUtil
|
|||
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 =
|
||||
{1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
|
||||
|
|
Loading…
Reference in New Issue