From 45ead1bb29394871010bf70977426cf319a529a5 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 15 Jul 2016 13:46:08 +1000 Subject: [PATCH] jetty http2 client parse error #726 --- .../org/eclipse/jetty/http/HttpField.java | 7 +- .../org/eclipse/jetty/http/HttpFields.java | 2 +- .../jetty/http2/hpack/HpackContext.java | 96 +++++++++---------- .../jetty/http2/hpack/HpackDecoder.java | 5 +- .../jetty/http2/hpack/HpackEncoder.java | 3 + .../jetty/http2/hpack/HpackDecoderTest.java | 28 ++++++ .../eclipse/jetty/http2/hpack/HpackTest.java | 8 +- 7 files changed, 92 insertions(+), 57 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java index 584ed74269d..ab9c142dac6 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java @@ -206,6 +206,8 @@ public class HttpField return false; if (_value==null) return false; + if (search.equals(_value)) + return true; search = StringUtil.asciiToLowerCase(search); @@ -410,9 +412,10 @@ public class HttpField @Override public int hashCode() { + int vhc = _value==null?0:_value.hashCode(); if (_header==null) - return _value.hashCode() ^ nameHashCode(); - return _value.hashCode() ^ _header.hashCode(); + return vhc ^ nameHashCode(); + return vhc ^ _header.hashCode(); } @Override diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java index 0951a6de515..283cfc5f45c 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java @@ -161,7 +161,7 @@ public class HttpFields implements Iterable for (int i=_size;i-->0;) { HttpField f=_fields[i]; - if (f.isSameName(field) && f.contains(field.getValue())) + if (f.isSameName(field) && (f.equals(field)||f.contains(field.getValue()))) return true; } return false; diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java index 89fbf00e4ad..2d2b30e2702 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java @@ -47,11 +47,11 @@ import org.eclipse.jetty.util.log.Logger; public class HpackContext { public static final Logger LOG = Log.getLogger(HpackContext.class); - + private static final String EMPTY = ""; public static final String[][] STATIC_TABLE = { {null,null}, - /* 1 */ {":authority",null}, + /* 1 */ {":authority",EMPTY}, /* 2 */ {":method","GET"}, /* 3 */ {":method","POST"}, /* 4 */ {":path","/"}, @@ -65,53 +65,53 @@ public class HpackContext /* 12 */ {":status","400"}, /* 13 */ {":status","404"}, /* 14 */ {":status","500"}, - /* 15 */ {"accept-charset",null}, + /* 15 */ {"accept-charset",EMPTY}, /* 16 */ {"accept-encoding","gzip, deflate"}, - /* 17 */ {"accept-language",null}, - /* 18 */ {"accept-ranges",null}, - /* 19 */ {"accept",null}, - /* 20 */ {"access-control-allow-origin",null}, - /* 21 */ {"age",null}, - /* 22 */ {"allow",null}, - /* 23 */ {"authorization",null}, - /* 24 */ {"cache-control",null}, - /* 25 */ {"content-disposition",null}, - /* 26 */ {"content-encoding",null}, - /* 27 */ {"content-language",null}, - /* 28 */ {"content-length",null}, - /* 29 */ {"content-location",null}, - /* 30 */ {"content-range",null}, - /* 31 */ {"content-type",null}, - /* 32 */ {"cookie",null}, - /* 33 */ {"date",null}, - /* 34 */ {"etag",null}, - /* 35 */ {"expect",null}, - /* 36 */ {"expires",null}, - /* 37 */ {"from",null}, - /* 38 */ {"host",null}, - /* 39 */ {"if-match",null}, - /* 40 */ {"if-modified-since",null}, - /* 41 */ {"if-none-match",null}, - /* 42 */ {"if-range",null}, - /* 43 */ {"if-unmodified-since",null}, - /* 44 */ {"last-modified",null}, - /* 45 */ {"link",null}, - /* 46 */ {"location",null}, - /* 47 */ {"max-forwards",null}, - /* 48 */ {"proxy-authenticate",null}, - /* 49 */ {"proxy-authorization",null}, - /* 50 */ {"range",null}, - /* 51 */ {"referer",null}, - /* 52 */ {"refresh",null}, - /* 53 */ {"retry-after",null}, - /* 54 */ {"server",null}, - /* 55 */ {"set-cookie",null}, - /* 56 */ {"strict-transport-security",null}, - /* 57 */ {"transfer-encoding",null}, - /* 58 */ {"user-agent",null}, - /* 59 */ {"vary",null}, - /* 60 */ {"via",null}, - /* 61 */ {"www-authenticate",null}, + /* 17 */ {"accept-language",EMPTY}, + /* 18 */ {"accept-ranges",EMPTY}, + /* 19 */ {"accept",EMPTY}, + /* 20 */ {"access-control-allow-origin",EMPTY}, + /* 21 */ {"age",EMPTY}, + /* 22 */ {"allow",EMPTY}, + /* 23 */ {"authorization",EMPTY}, + /* 24 */ {"cache-control",EMPTY}, + /* 25 */ {"content-disposition",EMPTY}, + /* 26 */ {"content-encoding",EMPTY}, + /* 27 */ {"content-language",EMPTY}, + /* 28 */ {"content-length",EMPTY}, + /* 29 */ {"content-location",EMPTY}, + /* 30 */ {"content-range",EMPTY}, + /* 31 */ {"content-type",EMPTY}, + /* 32 */ {"cookie",EMPTY}, + /* 33 */ {"date",EMPTY}, + /* 34 */ {"etag",EMPTY}, + /* 35 */ {"expect",EMPTY}, + /* 36 */ {"expires",EMPTY}, + /* 37 */ {"from",EMPTY}, + /* 38 */ {"host",EMPTY}, + /* 39 */ {"if-match",EMPTY}, + /* 40 */ {"if-modified-since",EMPTY}, + /* 41 */ {"if-none-match",EMPTY}, + /* 42 */ {"if-range",EMPTY}, + /* 43 */ {"if-unmodified-since",EMPTY}, + /* 44 */ {"last-modified",EMPTY}, + /* 45 */ {"link",EMPTY}, + /* 46 */ {"location",EMPTY}, + /* 47 */ {"max-forwards",EMPTY}, + /* 48 */ {"proxy-authenticate",EMPTY}, + /* 49 */ {"proxy-authorization",EMPTY}, + /* 50 */ {"range",EMPTY}, + /* 51 */ {"referer",EMPTY}, + /* 52 */ {"refresh",EMPTY}, + /* 53 */ {"retry-after",EMPTY}, + /* 54 */ {"server",EMPTY}, + /* 55 */ {"set-cookie",EMPTY}, + /* 56 */ {"strict-transport-security",EMPTY}, + /* 57 */ {"transfer-encoding",EMPTY}, + /* 58 */ {"user-agent",EMPTY}, + /* 59 */ {"vary",EMPTY}, + /* 60 */ {"via",EMPTY}, + /* 61 */ {"www-authenticate",EMPTY}, }; private static final Map __staticFieldMap = new HashMap<>(); diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java index 38dc8567f1f..c0564daa9ca 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java @@ -78,10 +78,9 @@ public class HpackDecoder while(buffer.hasRemaining()) { - if (LOG.isDebugEnabled()) + if (LOG.isDebugEnabled() && buffer.hasArray()) { - int l=Math.min(buffer.remaining(),16); - // TODO: not guaranteed the buffer has a backing array ! + int l=Math.min(buffer.remaining(),32); LOG.debug("decode {}{}", TypeUtil.toHexString(buffer.array(),buffer.arrayOffset()+buffer.position(),l), l