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

Reply via email to