This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 77ed41ce7491d778c9f3b1ff14722aa3bf2d3d55 Author: Mark Thomas <ma...@apache.org> AuthorDate: Fri Jan 14 19:24:42 2022 +0000 Add support to HTTP/2 test parser for push promise frames. --- test/org/apache/coyote/http2/Http2TestBase.java | 20 +++++++- .../org/apache/coyote/http2/TesterHttp2Parser.java | 55 +++++++++++++++++++++- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/test/org/apache/coyote/http2/Http2TestBase.java b/test/org/apache/coyote/http2/Http2TestBase.java index 4a7be7d..feadb27 100644 --- a/test/org/apache/coyote/http2/Http2TestBase.java +++ b/test/org/apache/coyote/http2/Http2TestBase.java @@ -200,7 +200,7 @@ public abstract class Http2TestBase extends TomcatBaseTest { protected void buildGetRequest(byte[] frameHeader, ByteBuffer headersPayload, byte[] padding, int streamId, String url) { - List<Header> headers = new ArrayList<>(3); + List<Header> headers = new ArrayList<>(4); headers.add(new Header(":method", "GET")); headers.add(new Header(":scheme", "http")); headers.add(new Header(":path", url)); @@ -1002,6 +1002,7 @@ public abstract class Http2TestBase extends TomcatBaseTest { private boolean traceBody = false; private ByteBuffer bodyBuffer = null; private long bytesRead; + private volatile HpackDecoder hpackDecoder = null; public void setTraceBody(boolean traceBody) { this.traceBody = traceBody; @@ -1010,7 +1011,14 @@ public abstract class Http2TestBase extends TomcatBaseTest { @Override public HpackDecoder getHpackDecoder() { - return new HpackDecoder(remoteSettings.getHeaderTableSize()); + if (hpackDecoder == null) { + synchronized (this) { + if (hpackDecoder == null) { + hpackDecoder = new HpackDecoder(remoteSettings.getHeaderTableSize()); + } + } + } + return hpackDecoder; } @@ -1190,6 +1198,14 @@ public abstract class Http2TestBase extends TomcatBaseTest { } + public void pushPromise(int streamId, int pushedStreamId) { + trace.append(streamId); + trace.append("-PushPromise-"); + trace.append(pushedStreamId); + trace.append("\n"); + } + + public void clearTrace() { trace = new StringBuffer(); bytesRead = 0; diff --git a/test/org/apache/coyote/http2/TesterHttp2Parser.java b/test/org/apache/coyote/http2/TesterHttp2Parser.java index 9618d6f..6cc41fd 100644 --- a/test/org/apache/coyote/http2/TesterHttp2Parser.java +++ b/test/org/apache/coyote/http2/TesterHttp2Parser.java @@ -17,18 +17,69 @@ package org.apache.coyote.http2; import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.coyote.http2.Http2TestBase.TestOutput; /** * Expose the parser outside of this package for use in other tests. */ public class TesterHttp2Parser extends Http2Parser { - TesterHttp2Parser(String connectionId, Input input, Output output) { + private final TestOutput output; + + TesterHttp2Parser(String connectionId, Input input, TestOutput output) { super(connectionId, input, output); + this.output = output; } @Override public boolean readFrame(boolean block) throws Http2Exception, IOException { return super.readFrame(block); } -} \ No newline at end of file + + @Override + protected void readPushPromiseFrame(int streamId, int flags, int payloadSize, ByteBuffer buffer) throws Http2Exception, IOException { + + // Parse flags used in this method + boolean hasPadding = Flags.hasPadding(flags); + boolean headersEndStream = Flags.isEndOfStream(flags); + + // Padding size + int paddingSize = 0; + if (hasPadding) { + byte[] bPadSize = new byte[1]; + if (buffer == null) { + input.fill(true, bPadSize); + } else { + buffer.get(bPadSize); + } + paddingSize = ByteUtil.getOneByte(bPadSize, 0); + } + + // Pushed stream ID + byte[] bPushedStreamId = new byte[4]; + if (buffer == null) { + input.fill(true, bPushedStreamId); + } else { + buffer.get(bPushedStreamId); + } + int pushedStreamId = ByteUtil.get31Bits(bPushedStreamId, 0); + + output.pushPromise(streamId, pushedStreamId); + + int headerSize = payloadSize - 4 - paddingSize; + if (hasPadding) { + headerSize--; + } + + HpackDecoder hpackDecoder = output.getHpackDecoder(); + hpackDecoder.setHeaderEmitter(output.headersStart(pushedStreamId, headersEndStream)); + + readHeaderPayload(pushedStreamId, headerSize, buffer); + + if (hasPadding) { + swallowPayload(streamId, FrameType.PUSH_PROMISE.getId(), paddingSize, true, buffer); + } + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org