From b7454f9cda53faa6d901b33d8c235d2a31a35b13 Mon Sep 17 00:00:00 2001 From: Flavia Rainone Date: Thu, 22 Jun 2023 15:12:38 -0300 Subject: [PATCH] [UNDERTOW-2281] At Http2FrameHeaderParser, throw a protocol error when END_STREAM is absent only when:request does not contain Expect:100-continue header; or response contains a positive content-length indicating the presence of a content. Signed-off-by: Flavia Rainone --- .../protocols/http2/Http2FrameHeaderParser.java | 6 ++++++ .../protocols/http2/Http2HeaderBlockParser.java | 13 +++++++++++++ 2 files changed, 19 insertions(+) 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) {