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 848d116f99ec170fb3678d4eb0ee333a85f721a1
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Mar 31 14:03:17 2020 +0100

    Make the HTTP/2 connection ID and stream Id available to applications
---
 java/org/apache/catalina/Globals.java             | 16 ++++++++++
 java/org/apache/catalina/connector/Request.java   | 27 ++++++++++++++++
 java/org/apache/coyote/AbstractProcessor.java     | 39 +++++++++++++++++++++++
 java/org/apache/coyote/ActionCode.java            | 14 +++++++-
 java/org/apache/coyote/http2/StreamProcessor.java | 12 +++++++
 webapps/docs/changelog.xml                        |  5 +++
 webapps/docs/config/http2.xml                     |  9 ++++++
 7 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/Globals.java 
b/java/org/apache/catalina/Globals.java
index 144a028..312d78b 100644
--- a/java/org/apache/catalina/Globals.java
+++ b/java/org/apache/catalina/Globals.java
@@ -51,6 +51,22 @@ public final class Globals {
 
 
     /**
+     * The request attribute used to expose the current connection ID 
associated
+     * with the request, if any. Used with multiplexing protocols such as
+     * HTTTP/2.
+     */
+    public static final String CONNECTION_ID = 
"org.apache.coyote.connectionID";
+
+
+    /**
+     * The request attribute used to expose the current stream ID associated
+     * with the request, if any. Used with multiplexing protocols such as
+     * HTTTP/2.
+     */
+    public static final String STREAM_ID = "org.apache.coyote.streamID";
+
+
+    /**
      * The request attribute that is set to {@code Boolean.TRUE} if some 
request
      * parameters have been ignored during request parameters parsing. It can
      * happen, for example, if there is a limit on the total count of parseable
diff --git a/java/org/apache/catalina/connector/Request.java 
b/java/org/apache/catalina/connector/Request.java
index a38e97a..743be10 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -41,6 +41,7 @@ import java.util.TimeZone;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.naming.NamingException;
 import javax.security.auth.Subject;
@@ -3562,6 +3563,32 @@ public class Request implements 
org.apache.catalina.servlet4preview.http.HttpSer
                         // NO-OP
                     }
                 });
+        specialAttributes.put(Globals.CONNECTION_ID,
+                new SpecialAttributeAdapter() {
+                    @Override
+                    public Object get(Request request, String name) {
+                        AtomicReference<Object> result = new 
AtomicReference<>();
+                        
request.getCoyoteRequest().action(ActionCode.CONNECTION_ID, result);
+                        return result.get();
+                    }
+                    @Override
+                    public void set(Request request, String name, Object 
value) {
+                        // NO-OP
+                    }
+                });
+        specialAttributes.put(Globals.STREAM_ID,
+                new SpecialAttributeAdapter() {
+                    @Override
+                    public Object get(Request request, String name) {
+                        AtomicReference<Object> result = new 
AtomicReference<>();
+                        
request.getCoyoteRequest().action(ActionCode.STREAM_ID, result);
+                        return result.get();
+                    }
+                    @Override
+                    public void set(Request request, String name, Object 
value) {
+                        // NO-OP
+                    }
+                });
 
         for (SimpleDateFormat sdf : formatsTemplate) {
             sdf.setTimeZone(GMT_ZONE);
diff --git a/java/org/apache/coyote/AbstractProcessor.java 
b/java/org/apache/coyote/AbstractProcessor.java
index dd2b807..646578d 100644
--- a/java/org/apache/coyote/AbstractProcessor.java
+++ b/java/org/apache/coyote/AbstractProcessor.java
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
 import java.util.Iterator;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.servlet.RequestDispatcher;
 
@@ -612,6 +613,20 @@ public abstract class AbstractProcessor extends 
AbstractProcessorLight implement
             doPush((Request) param);
             break;
         }
+
+        // Identifiers associated with multiplexing protocols like HTTP/2
+        case CONNECTION_ID: {
+            @SuppressWarnings("unchecked")
+            AtomicReference<Object> result = (AtomicReference<Object>) param;
+            result.set(getConnectionID());
+            break;
+        }
+        case STREAM_ID: {
+            @SuppressWarnings("unchecked")
+            AtomicReference<Object> result = (AtomicReference<Object>) param;
+            result.set(getStreamID());
+            break;
+        }
         }
     }
 
@@ -933,6 +948,30 @@ public abstract class AbstractProcessor extends 
AbstractProcessorLight implement
 
 
     /**
+     * Protocols that support multiplexing (e.g. HTTP/2) should override this
+     * method and return the appropriate ID.
+     *
+     * @return The stream ID associated with this request or {@code null} if a
+     *         multiplexing protocol is not being used
+      */
+    protected Object getConnectionID() {
+        return null;
+    }
+
+
+    /**
+     * Protocols that support multiplexing (e.g. HTTP/2) should override this
+     * method and return the appropriate ID.
+     *
+     * @return The stream ID associated with this request or {@code null} if a
+     *         multiplexing protocol is not being used
+     */
+    protected Object getStreamID() {
+        return null;
+    }
+
+
+    /**
      * Flush any pending writes. Used during non-blocking writes to flush any
      * remaining data from a previous incomplete write.
      *
diff --git a/java/org/apache/coyote/ActionCode.java 
b/java/org/apache/coyote/ActionCode.java
index eb482bb..2795a81 100644
--- a/java/org/apache/coyote/ActionCode.java
+++ b/java/org/apache/coyote/ActionCode.java
@@ -251,5 +251,17 @@ public enum ActionCode {
     /**
      * Push a request on behalf of the client of the current request.
      */
-    PUSH_REQUEST
+    PUSH_REQUEST,
+
+    /**
+     * Obtain the connection identifier for the request. Used with multiplexing
+     * protocols such as HTTP/2.
+     */
+    CONNECTION_ID,
+
+    /**
+     * Obtain the stream identifier for the request. Used with multiplexing
+     * protocols such as HTTP/2.
+     */
+    STREAM_ID
 }
diff --git a/java/org/apache/coyote/http2/StreamProcessor.java 
b/java/org/apache/coyote/http2/StreamProcessor.java
index f3c380d..be6a353 100644
--- a/java/org/apache/coyote/http2/StreamProcessor.java
+++ b/java/org/apache/coyote/http2/StreamProcessor.java
@@ -300,6 +300,18 @@ class StreamProcessor extends AbstractProcessor {
 
 
     @Override
+    protected Object getConnectionID() {
+        return stream.getConnectionId();
+    }
+
+
+    @Override
+    protected Object getStreamID() {
+        return stream.getIdentifier().toString();
+    }
+
+
+    @Override
     public void recycle() {
         // StreamProcessor instances are not re-used.
         // Clear fields that can be cleared to aid GC and trigger NPEs if this
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 4a05330..164fcad 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -88,6 +88,11 @@
         data on the request line after the URI are treated consistently. Such
         requests will now always be treated as HTTP/1.1. (markt)
       </fix>
+      <add>
+        Expose the HTTP/2 connection ID and stream ID to applications via the
+        request attributes <code>org.apache.coyote.connectionID</code> and
+        <code>org.apache.coyote.streamID</code> respectively. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Jasper">
diff --git a/webapps/docs/config/http2.xml b/webapps/docs/config/http2.xml
index d0055dd..8e72a25 100644
--- a/webapps/docs/config/http2.xml
+++ b/webapps/docs/config/http2.xml
@@ -44,6 +44,15 @@
   the Servlet API is fundamentally blocking, each HTTP/2 stream requires a
   dedicated container thread for the duration of that stream.</p>
 
+  <p>Requests processed using HTTP/2 will have the following additional request
+  attributes available:</p>
+  <ul>
+    <li><code>org.apache.coyote.connectionID</code> will return the HTTP/2
+        connection ID</li>
+    <li><code>org.apache.coyote.streamID</code> will return the HTTP/2 stream
+        ID</li>
+  </ul>
+
 </section>
 
 


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

Reply via email to