package test.codec.http2.hpack; import com.firefly.codec.http2.hpack.HpackDecoder; import com.firefly.codec.http2.model.*; import com.firefly.utils.lang.TypeUtils; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; import java.nio.ByteBuffer; import java.util.Iterator; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.*; public class HpackDecoderTest { @Test public void testDecodeD_3() { HpackDecoder decoder = new HpackDecoder(4096, 8192); // First request String encoded = "828684410f7777772e6578616d706c652e636f6d"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); MetaData.Request request = (MetaData.Request) decoder.decode(buffer); assertEquals("GET", request.getMethod()); assertEquals(HttpScheme.HTTP.asString(), request.getURI().getScheme()); assertEquals("/", request.getURI().getPath()); assertEquals("www.example.com", request.getURI().getHost()); assertFalse(request.iterator().hasNext()); // Second request encoded = "828684be58086e6f2d6361636865"; buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); request = (MetaData.Request) decoder.decode(buffer); assertEquals("GET", request.getMethod()); assertEquals(HttpScheme.HTTP.asString(), request.getURI().getScheme()); assertEquals("/", request.getURI().getPath()); assertEquals("www.example.com", request.getURI().getHost()); Iterator<HttpField> iterator = request.iterator(); assertTrue(iterator.hasNext()); assertEquals(new HttpField("cache-control", "no-cache"), iterator.next()); assertFalse(iterator.hasNext()); // Third request encoded = "828785bf400a637573746f6d2d6b65790c637573746f6d2d76616c7565"; buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); request = (MetaData.Request) decoder.decode(buffer); assertEquals("GET", request.getMethod()); assertEquals(HttpScheme.HTTPS.asString(), request.getURI().getScheme()); assertEquals("/index.html", request.getURI().getPath()); assertEquals("www.example.com", request.getURI().getHost()); iterator = request.iterator(); assertTrue(iterator.hasNext()); assertEquals(new HttpField("custom-key", "custom-value"), iterator.next()); assertFalse(iterator.hasNext()); } @Test public void testDecodeD_4() { HpackDecoder decoder = new HpackDecoder(4096, 8192); // First request String encoded = "828684418cf1e3c2e5f23a6ba0ab90f4ff"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); MetaData.Request request = (MetaData.Request) decoder.decode(buffer); assertEquals("GET", request.getMethod()); assertEquals(HttpScheme.HTTP.asString(), request.getURI().getScheme()); assertEquals("/", request.getURI().getPath()); assertEquals("www.example.com", request.getURI().getHost()); assertFalse(request.iterator().hasNext()); // Second request encoded = "828684be5886a8eb10649cbf"; buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); request = (MetaData.Request) decoder.decode(buffer); assertEquals("GET", request.getMethod()); assertEquals(HttpScheme.HTTP.asString(), request.getURI().getScheme()); assertEquals("/", request.getURI().getPath()); assertEquals("www.example.com", request.getURI().getHost()); Iterator<HttpField> iterator = request.iterator(); assertTrue(iterator.hasNext()); assertEquals(new HttpField("cache-control", "no-cache"), iterator.next()); assertFalse(iterator.hasNext()); } @Test public void testDecodeWithArrayOffset() { String value = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; HpackDecoder decoder = new HpackDecoder(4096, 8192); String encoded = "8682418cF1E3C2E5F23a6bA0Ab90F4Ff841f0822426173696320515778685a475270626a70766347567549484e6c633246745a513d3d"; byte[] bytes = TypeUtils.fromHexString(encoded); byte[] array = new byte[bytes.length + 1]; System.arraycopy(bytes, 0, array, 1, bytes.length); ByteBuffer buffer = ByteBuffer.wrap(array, 1, bytes.length).slice(); MetaData.Request request = (MetaData.Request) decoder.decode(buffer); assertEquals("GET", request.getMethod()); assertEquals(HttpScheme.HTTP.asString(), request.getURI().getScheme()); assertEquals("/", request.getURI().getPath()); assertEquals("www.example.com", request.getURI().getHost()); assertEquals(1, request.getFields().size()); HttpField field = request.iterator().next(); assertEquals(HttpHeader.AUTHORIZATION, field.getHeader()); assertEquals(value, field.getValue()); } @Test public void testDecodeHuffmanWithArrayOffset() { HpackDecoder decoder = new HpackDecoder(4096, 8192); String encoded = "8286418cf1e3c2e5f23a6ba0ab90f4ff84"; byte[] bytes = TypeUtils.fromHexString(encoded); byte[] array = new byte[bytes.length + 1]; System.arraycopy(bytes, 0, array, 1, bytes.length); ByteBuffer buffer = ByteBuffer.wrap(array, 1, bytes.length).slice(); MetaData.Request request = (MetaData.Request) decoder.decode(buffer); assertEquals("GET", request.getMethod()); assertEquals(HttpScheme.HTTP.asString(), request.getURI().getScheme()); assertEquals("/", request.getURI().getPath()); assertEquals("www.example.com", request.getURI().getHost()); assertFalse(request.iterator().hasNext()); } @Test public void testNghttpx() { // Response encoded by nghttpx String encoded = "886196C361Be940b6a65B6850400B8A00571972e080a62D1Bf5f87497cA589D34d1f9a0f0d0234327690Aa69D29aFcA954D3A5358980Ae112e0f7c880aE152A9A74a6bF3"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); HpackDecoder decoder = new HpackDecoder(4096, 8192); MetaData.Response response = (MetaData.Response) decoder.decode(buffer); assertThat(response.getStatus(), is(200)); assertThat(response.getFields().size(), is(6)); assertTrue(response.getFields().contains(new HttpField(HttpHeader.DATE, "Fri, 15 Jul 2016 02:36:20 GMT"))); assertTrue(response.getFields().contains(new HttpField(HttpHeader.CONTENT_TYPE, "text/html"))); assertTrue(response.getFields().contains(new HttpField(HttpHeader.CONTENT_ENCODING, ""))); assertTrue(response.getFields().contains(new HttpField(HttpHeader.CONTENT_LENGTH, "42"))); assertTrue(response.getFields().contains(new HttpField(HttpHeader.SERVER, "nghttpx nghttp2/1.12.0"))); assertTrue(response.getFields().contains(new HttpField(HttpHeader.VIA, "1.1 nghttpx"))); } @Test public void testTooBigToIndex() { String encoded = "44FfEc02Df3990A190A0D4Ee5b3d2940Ec98Aa4a62D127D29e273a0aA20dEcAa190a503b262d8a2671D4A2672a927aA874988a2471D05510750c951139EdA2452a3a548cAa1aA90bE4B228342864A9E0D450A5474a92992a1aA513395448E3A0Aa17B96cFe3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f14E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F353F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F54f"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); HpackDecoder decoder = new HpackDecoder(128, 8192); try { decoder.decode(buffer); Assert.fail(); } catch (BadMessageException e) { assertThat(e.getCode(), equalTo(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431)); assertThat(e.getReason(), Matchers.startsWith("Indexed field value too large")); } } @Test public void testUnknownIndex() { String encoded = "BE"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtils.fromHexString(encoded)); HpackDecoder decoder = new HpackDecoder(128, 8192); try { decoder.decode(buffer); Assert.fail(); } catch (BadMessageException e) { assertThat(e.getCode(), equalTo(HttpStatus.BAD_REQUEST_400)); assertThat(e.getReason(), Matchers.startsWith("Unknown index")); } } }