diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java index f9a048d8471..922388be2a1 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java @@ -20,8 +20,11 @@ package org.eclipse.jetty.http2.parser; import java.nio.ByteBuffer; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.hpack.HpackDecoder; +import org.eclipse.jetty.http2.hpack.HpackException.SessionException; +import org.eclipse.jetty.http2.hpack.HpackException.StreamException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; @@ -72,17 +75,48 @@ public class HeaderBlockParser toDecode = buffer; } - MetaData result = hpackDecoder.decode(toDecode); - - buffer.limit(limit); - - if (blockBuffer != null) + try { - byteBufferPool.release(blockBuffer); - blockBuffer = null; + MetaData metadata = hpackDecoder.decode(toDecode); + + if (metadata instanceof MetaData.Request) + { + // TODO this must be an initial HEADERs frame received by the server OR + // TODO a push promise received by the client. + // TODO this must not be a trailers frame + } + else if (metadata instanceof MetaData.Response) + { + // TODO this must be an initial HEADERs frame received by the client + // TODO this must not be a trailers frame + } + else + { + // TODO this must be a trailers frame + } + + return metadata; } + catch(StreamException ex) + { + // TODO reset the stream + throw new BadMessageException("TODO"); + } + catch(SessionException ex) + { + // TODO reset the session + throw new BadMessageException("TODO"); + } + finally + { + buffer.limit(limit); - return result; + if (blockBuffer != null) + { + byteBufferPool.release(blockBuffer); + blockBuffer = null; + } + } } } } 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 5526eb44772..74b8b87deb9 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 @@ -66,7 +66,7 @@ public class HpackDecoder _localMaxDynamicTableSize=localMaxdynamciTableSize; } - public MetaData decode(ByteBuffer buffer) throws HpackException + public MetaData decode(ByteBuffer buffer) throws HpackException.SessionException, HpackException.StreamException { if (LOG.isDebugEnabled()) LOG.debug(String.format("CtxTbl[%x] decoding %d octets",_context.hashCode(),buffer.remaining())); diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java index 287e02f2e13..78516c73bd2 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java @@ -18,15 +18,22 @@ package org.eclipse.jetty.http2.hpack; -import java.io.IOException; -public abstract class HpackException extends RuntimeException +@SuppressWarnings("serial") +public abstract class HpackException extends Exception { HpackException(String messageFormat, Object... args) { super(String.format(messageFormat, args)); } + /** + * A Stream HPACK exception. + *

Stream exceptions are not fatal to the connection and the + * hpack state is complete and able to continue handling other + * decoding/encoding for the session. + *

+ */ public static class StreamException extends HpackException { StreamException(String messageFormat, Object... args) @@ -35,6 +42,11 @@ public abstract class HpackException extends RuntimeException } } + /** + * A Session HPACK Exception. + *

Session exceptions are fatal for the stream and the HPACK + * state is unable to decode/encode further.

+ */ public static class SessionException extends HpackException { SessionException(String messageFormat, Object... args) diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java index dc65c4fcc9e..3a01e8a593a 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java @@ -228,10 +228,7 @@ public class MetaDataBuilder public MetaData build() throws HpackException.StreamException { if (_streamException!=null) - { - _streamException.addSuppressed(new Throwable()); throw _streamException; - } if (_request && _response) throw new HpackException.StreamException("Request and Response headers"); diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java index dd861890d7e..1e74d100fd7 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java @@ -231,7 +231,7 @@ public class HpackDecoderTest /* 8.1.2.1. Pseudo-Header Fields */ @Test() - public void test8_1_2_1_PsuedoHeaderFields() + public void test8_1_2_1_PsuedoHeaderFields() throws Exception { // 1:Sends a HEADERS frame that contains a unknown pseudo-header field MetaDataBuilder mdb = new MetaDataBuilder(4096);