| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 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.http2.hpack; |
| |
| |
| import static org.hamcrest.Matchers.equalTo; |
| import static org.junit.Assert.assertThat; |
| |
| import java.nio.ByteBuffer; |
| |
| import org.eclipse.jetty.http.HttpField; |
| 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; |
| |
| |
| /* ------------------------------------------------------------ */ |
| /** |
| */ |
| public class HpackEncoderTest |
| { |
| @Test |
| public void testUnknownFieldsContextManagement() |
| { |
| HpackEncoder encoder = new HpackEncoder(38*5); |
| HttpFields fields = new HttpFields(); |
| |
| |
| HttpField[] field = |
| { |
| new HttpField("fo0","b0r"), |
| new HttpField("fo1","b1r"), |
| new HttpField("fo2","b2r"), |
| new HttpField("fo3","b3r"), |
| new HttpField("fo4","b4r"), |
| new HttpField("fo5","b5r"), |
| new HttpField("fo6","b6r"), |
| new HttpField("fo7","b7r"), |
| new HttpField("fo8","b8r"), |
| new HttpField("fo9","b9r"), |
| new HttpField("foA","bAr"), |
| }; |
| |
| // Add 4 entries |
| for (int i=0;i<=3;i++) |
| fields.add(field[i]); |
| |
| // encode them |
| ByteBuffer buffer = BufferUtil.allocate(4096); |
| int pos = BufferUtil.flipToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,pos); |
| |
| // something was encoded! |
| assertThat(buffer.remaining(),Matchers.greaterThan(0)); |
| |
| // All are in the dynamic table |
| Assert.assertEquals(4,encoder.getHpackContext().size()); |
| |
| // encode exact same fields again! |
| BufferUtil.clearToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,0); |
| |
| // All are in the dynamic table |
| Assert.assertEquals(4,encoder.getHpackContext().size()); |
| |
| // Add 4 more fields |
| for (int i=4;i<=7;i++) |
| fields.add(field[i]); |
| |
| // encode |
| BufferUtil.clearToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,0); |
| |
| // something was encoded! |
| assertThat(buffer.remaining(),Matchers.greaterThan(0)); |
| |
| // max dynamic table size reached |
| Assert.assertEquals(5,encoder.getHpackContext().size()); |
| |
| |
| // remove some fields |
| for (int i=0;i<=7;i+=2) |
| fields.remove(field[i].getName()); |
| |
| // encode |
| BufferUtil.clearToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,0); |
| |
| // something was encoded! |
| assertThat(buffer.remaining(),Matchers.greaterThan(0)); |
| |
| // max dynamic table size reached |
| Assert.assertEquals(5,encoder.getHpackContext().size()); |
| |
| |
| // remove another fields |
| fields.remove(field[1].getName()); |
| |
| // encode |
| BufferUtil.clearToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,0); |
| |
| // something was encoded! |
| assertThat(buffer.remaining(),Matchers.greaterThan(0)); |
| |
| // max dynamic table size reached |
| Assert.assertEquals(5,encoder.getHpackContext().size()); |
| |
| |
| // re add the field |
| |
| fields.add(field[1]); |
| |
| // encode |
| BufferUtil.clearToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,0); |
| |
| // something was encoded! |
| assertThat(buffer.remaining(),Matchers.greaterThan(0)); |
| |
| // max dynamic table size reached |
| Assert.assertEquals(5,encoder.getHpackContext().size()); |
| |
| } |
| |
| |
| @Test |
| public void testNeverIndexSetCookie() |
| { |
| HpackEncoder encoder = new HpackEncoder(38*5); |
| ByteBuffer buffer = BufferUtil.allocate(4096); |
| |
| HttpFields fields = new HttpFields(); |
| fields.put("set-cookie","some cookie value"); |
| |
| // encode |
| BufferUtil.clearToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,0); |
| |
| // something was encoded! |
| assertThat(buffer.remaining(),Matchers.greaterThan(0)); |
| |
| // empty dynamic table |
| Assert.assertEquals(0,encoder.getHpackContext().size()); |
| |
| |
| // encode again |
| BufferUtil.clearToFill(buffer); |
| encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2,fields)); |
| BufferUtil.flipToFlush(buffer,0); |
| |
| // something was encoded! |
| assertThat(buffer.remaining(),Matchers.greaterThan(0)); |
| |
| // empty dynamic table |
| Assert.assertEquals(0,encoder.getHpackContext().size()); |
| |
| } |
| |
| |
| @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())); |
| |
| } |
| |
| |
| |
| } |