This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit dc4bb27f91cfd582696c8f521b0ea4741921eefd
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.
---
 java/org/apache/coyote/http2/Http2Parser.java      |  4 +-
 test/org/apache/coyote/http2/Http2TestBase.java    | 20 +++++++++-
 .../org/apache/coyote/http2/TesterHttp2Parser.java | 46 +++++++++++++++++++++-
 3 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/java/org/apache/coyote/http2/Http2Parser.java 
b/java/org/apache/coyote/http2/Http2Parser.java
index 8fc7385..df173e1 100644
--- a/java/org/apache/coyote/http2/Http2Parser.java
+++ b/java/org/apache/coyote/http2/Http2Parser.java
@@ -36,7 +36,7 @@ class Http2Parser {
             "PRI * 
HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1);
 
     private final String connectionId;
-    private final Input input;
+    protected final Input input;
     private final Output output;
     private final byte[] frameHeaderBuffer = new byte[9];
 
@@ -408,7 +408,7 @@ class Http2Parser {
     }
 
 
-    private void readHeaderPayload(int streamId, int payloadSize)
+    protected void readHeaderPayload(int streamId, int payloadSize)
             throws Http2Exception, IOException {
 
         if (log.isDebugEnabled()) {
diff --git a/test/org/apache/coyote/http2/Http2TestBase.java 
b/test/org/apache/coyote/http2/Http2TestBase.java
index 9b0a43a..e4054c5 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));
@@ -1017,6 +1017,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;
@@ -1025,7 +1026,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;
         }
 
 
@@ -1205,6 +1213,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..2951896 100644
--- a/test/org/apache/coyote/http2/TesterHttp2Parser.java
+++ b/test/org/apache/coyote/http2/TesterHttp2Parser.java
@@ -18,17 +18,59 @@ package org.apache.coyote.http2;
 
 import java.io.IOException;
 
+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) 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];
+            input.fill(true, bPadSize);
+            paddingSize = ByteUtil.getOneByte(bPadSize, 0);
+        }
+
+        // Pushed stream ID
+        byte[] bPushedStreamId = new byte[4];
+        input.fill(true, 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);
+
+        if (hasPadding) {
+            swallowPayload(streamId, FrameType.PUSH_PROMISE.getId(), 
paddingSize, true);
+        }
+    }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to