diff --git a/core/src/main/java/io/undertow/protocols/http2/Http2FrameHeaderParser.java b/core/src/main/java/io/undertow/protocols/http2/Http2FrameHeaderParser.java index 75a34ed977..cd63540920 100644 --- a/core/src/main/java/io/undertow/protocols/http2/Http2FrameHeaderParser.java +++ b/core/src/main/java/io/undertow/protocols/http2/Http2FrameHeaderParser.java @@ -38,6 +38,7 @@ import static io.undertow.protocols.http2.Http2Channel.HEADERS_FLAG_END_HEADERS; import static org.xnio.Bits.allAreClear; import static org.xnio.Bits.allAreSet; +import static org.xnio.Bits.anyAreClear; import static org.xnio.Bits.anyAreSet; /** @@ -233,6 +234,11 @@ int getActualLength() { } else if(type == FRAME_TYPE_HEADERS) { final Http2StreamSourceChannel channel = http2Channel.getIncomingStream(streamId); if(channel != null) { + if(anyAreClear(flags, Http2Channel.HEADERS_FLAG_END_STREAM) && !((Http2HeadersParser) parser).isContentExpected()) { + //this is a protocol error + io.undertow.UndertowLogger.REQUEST_IO_LOGGER.debug("Received HTTP/2 trailers header without end stream set"); + http2Channel.sendGoAway(Http2Channel.ERROR_PROTOCOL_ERROR); + } if (!channel.isHeadersEndStream() && allAreSet(flags, Http2Channel.HEADERS_FLAG_END_HEADERS | Http2Channel.HEADERS_FLAG_END_STREAM)) { http2Channel.removeStreamSource(streamId); } diff --git a/core/src/main/java/io/undertow/protocols/http2/Http2HeaderBlockParser.java b/core/src/main/java/io/undertow/protocols/http2/Http2HeaderBlockParser.java index 0c1b42613e..a812b942e9 100644 --- a/core/src/main/java/io/undertow/protocols/http2/Http2HeaderBlockParser.java +++ b/core/src/main/java/io/undertow/protocols/http2/Http2HeaderBlockParser.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.Set; +import io.undertow.server.protocol.http.HttpContinue; import org.xnio.Bits; import io.undertow.UndertowLogger; @@ -138,6 +139,18 @@ HeaderMap getHeaderMap() { return headerMap; } + boolean isContentExpected() { + if (HttpContinue.requiresContinueResponse(headerMap)) { + return true; + } + String contentLengthString = headerMap.getFirst(Headers.CONTENT_LENGTH); + try { + return contentLengthString != null ? Long.parseLong(contentLengthString) > 0 : false; + } catch (NumberFormatException e) { + return false; + } + } + @Override public void emitHeader(HttpString name, String value, boolean neverIndex) throws HpackException { if(maxHeaderListSize > 0) {